From 2a66ce0f0b792590115cd5663fed0baa15e7186b Mon Sep 17 00:00:00 2001 From: Ayush Pandey Date: Sat, 1 Aug 2020 23:27:47 -0700 Subject: [PATCH] Dev to master pull request (v 0.9beta) (#158) * Removed Duplicate Reaction Warning These are now used in many Mixtures, so the warning doesn't make sense * global refactor "Michalis" --> "Michaelis" * Minor SBML fixes (#110) * added model Id attribute and compartment name attribute when creating SBML models * An optional `model_id` argument can be passed when creating SBML models. * removing mutable default arguments * change the travis congfig checks with flak8-mutable This is a safeguard which helps to avoid defaults mutable arguments entering the codebase * Adding import guards for bioscrape and libroadrunner (#116) * refactor bioscape and libroadrunner import Bioscrape and Libroadrunners are not hard dependencies, therefore we check put a safeguard around the import statement. Unit tests are included as well to test the expected behaviour. * add another unit test for simulation results * refactor the simulation interface in example notebooks if bioscrape is not found the simulator returns None, all try-except blocks were removed, simulator return value is tested instead. * xml clean up (#113) * delete xml files that were generated by the BioCRNPlyer * add xml files to gitignore xml files are generated by this toolbox, but no need to be stored in the repo * fixup: add end of line to gitignore * removing mutable default arguments * change the travis congfig checks with flak8-mutable This is a safeguard which helps to avoid defaults mutable arguments entering the codebase * Fixed Simulate with Bioscrape Functions & Tests The tests now each have two cases: one without bioscrape and one with bioscrape. * added "is not None" to a bunch of stuff (#118) * try except for pandas, seaborn * added somemore try blocks * missed an if statement * modify plotting text * added "is not None" to a lot of stuff * Fixed Simulate with Bioscrape Functions & Tests The tests now each have two cases: one without bioscrape and one with bioscrape. Co-authored-by: William Poole * Minor Fixes to Pass Tests Old Examples now X.ipynb.old to avoid being tested and maintained. Should be removed permanently in next dev to master merge. Added additional "Results is not None" statements in some examples which were missed before. * bug fix two issues: #115 and #92 (#119) This commit fixes two issues reported on the issues page: * #115 (fixing leak in Repressible and Activatable Promoter classes) Adding leak keyword in activatable and repressible promoters. Until now, the "leak" keyword did nothing in these promoters. It now toggles the leak reaction. This required changing the NegativeHillTranscription and PositiveHillTranscription Mechanisms to also use a leak keyword. * #92 (fixing filter_dict issues in GlobalMechanisms). A new keyword has been added to global mechanisms: recursive_species_filtering = True/False. This allows for filter_dict keywords to be searched recursively through the species inside ComplexSpecies or not. A new recursive method, get_species, was added to ComplexSpecies in order to do this. This functionality is tested in a new test file: test_global_mechanism.py. This functionality has also been documented in example notebook number 6. Co-authored-by: William Poole * changing pytest config (#121) * change pytest config adding verbose test output (vv), colors (color=yes) and adding some ignores for warnings (filterwarnings) * fixup: adding a new line at the EOF * add new parameter classes (#124) * New Parameter Classes Parameters are now stored in a ParameterDatabase populated by ParameterEntries. These new objects have required changes to how Mixtures and Components find, store, and load parameters (and initial conditions). * ParameterKeys are namedtuples ParameterKeys in ParameterDatabase are namedtuples. * Associated Tests for Parameter objects have been made and tests for Mixtures and Components have been updated. * For now, Parameters are returned as numbers (instead of ParameterEntries) - this will need to be undone when new parameter classes are added with new reaction classes. * add checks to string parsing in Parameter Parameter object accepts parameters values from strings * Changes to make ExpressionMixtures work The issue is that ExpressionMixtures were replacing Species. In retrospect, this is not the rigth way for them to work. Now they can use Mechanisms normally by just setting all transcripts in DNA assembly to be None (if Protein is not None). The mechanisms now switch between Expression and Transcription in this case. * Combinatorial Testing and Fixes Added tests to tests combinations of Components and Mixtures. * Added .replace_species unit tests To get coverage in chemical_reaction_network.py back to where it was previously, I added unit tests for ChemicalReactionNetwork, Species, ComplexSpecies OrderedComplexSpecies and Reaction .replace_species(old_s, new_s) function. This is no longer used in the code, but could be useful I imagine. Co-authored-by: William Poole Co-authored-by: zoltuz * new object based Propensities (#103) * add object-oriented Propensity types This introduces a new class structure that replaces the string based propensity type with a class-based system. * replace the string based propensity checks It leverages on the object-oriented Propensity type when a new reactions is created * create new object-based propensities * Refactored chemical reaction network: It is now in 3 files: species, reaction, propensities, and chemical_reaction_network * Annotations & SBML writing work with tests * add check and unit tests for WeightedSpecies and add float to int conversion in WeightedSpecies * add compatibility handling for Reaction: with this commit there's a new interface for Reaction. To keep the backward compatibility the old interface is suppored to some extent (massaction kinetic is supported with Deprecation warnings, other kinetics throw a NotImplementedError) * add propensity unittest for non-massaction types * refactor create_rate_law * propagating for_bioscrape keyword for annotation export * example how to setup Propensity through the old_interface * Create test_sbml.py * force numerical values for parameters in MultiOccupancyTxTl_Demo and Cooperativity parameter via Component.get_parameter(... return_numerical = True/False) keyword. * remove tests for reversible SBML reactions * change simulate_with_bioscrape_via_sbml call to get a correct return value * changed CRN.add_species and add_reactions * changed printouts in example notebooks to be more/less verbose in different cases. * Added details on viewing parameter keys to the parameter notebook. Co-authored-by: William Poole * Ordered polymer species (#126) * try except for pandas, seaborn * OrderedPolymer, OrderedMonomer, OrderedPolymerSpecies class: OrderedMonomers are copied when inserted into an OrderedPolymer * minor fixes to chemical complex * attributes, name and material types as properties: name and material_types are now a properties for Species and all Subclasses. * parent, direction, and position are now properties: created setters etc. Also OrderedPolymerSpecies.circular is now used as an attribute as well. * Complex() function makes OrderedComplexSpecies as well as ComplexSpecies and replaced ComplexSpecies with Complex throughout the code. Also added a warning if ComplexSpecies or OrderedComplexSpecies is made not from Complex. * added tests for polymer and complex * no attrib inheritance for ComplexSpecies, circular. * Changed the order of species file * More combinatoric tests *ComplexSpecies names now but the 2x (for duplicate species) at the end. This is an SBML compatability issue. Co-authored-by: William Poole * fixed a typo - very surprised this wasn't caught via testing. * added create_modifier for SpeciesModifier reference in SBML * refactored annotations for bioscrape into kwargs * moved or_bioscrape to kwargs everywhere and added species modifier refernece to SBML * fixed typos in crn for comments * no modifiers needed for massaction propensity reactions * param keyword needed only for massaction while creating annotations * changed propensity bioscrape_name to name attribute. modifiers working. * added SBML validation code to SBML testing in BioCRNpyler test suite. need debugging... * moved test_validate to sbmlutil.py * minor bug fix * fixed import statements in test_sbml.py * renamed test_validate_sbml to validate_sbml, to prevent travis from revognizing that as a fixture for test function * all sbml models validated/validation testing works. annotations not working * refactor sbml modifier to avoid searching for nonexistent species * bugfix key error in annotation_dict * fixed stochastic massaction propensity to not have S-0 term * fixed typo bug in stochastic massaction * finally fixed the bug with propensity writing and annotation in SBML * refactored test_sbml to separate out bioscrape testing. Added General propensity testing to SBML. * fixed general propensity typo * general propensities working but sbml models are invalid because parameters for general propensity models are not added to SBML * add a general propensity class GeneralPropesity accpets a propensity formula in str and also requires the list of species and parameters that are part if the propensity formula. * clean up to make it pep8 compatible * bugfix for propensity annotation writing * minor comment add * added sbml validation to other parts of automated testing * fixed comments from PR review by zoltuz * bioscrape annotations, simulations all working. * added new SBML basics testing to test libsbml functions and other sbmlutil functions * refactor and bugfix SBML writing (#131) * Minor SBML writing bug fix (#109) * Added model Id attribute and compartment name attribute when creating SBML models. * An optional argument can be passed when creating SBML models : `model_id` to give an ID to your SBML model. The SBML writing test was fixed accordingly. * added create_modifier for SpeciesModifier reference in SBML * refactored annotations for_bioscrape into kwargs and added species modifier reference to SBML * no modifiers needed for massaction propensity reactions * changed propensity bioscrape_name to name attribute. modifiers working. * added SBML validation code to SBML testing in BioCRNpyler test suite * moved test_validate to validate_sbml * all sbml models validated/validation testing works. * refactor sbml modifier to avoid searching for nonexistent species * fixed stochastic massaction propensity to not have S-0 term * fixed typo bug in stochastic massaction * finally fixed the bug with propensity writing and annotation in SBML (#135 ) * refactored test_sbml to separate out bioscrape testing. Added General propensity testing to SBML. * add a general propensity class: GeneralPropesity accepts a propensity formula in a string and also requires the list of species and parameters that are part of the propensity formula. (#132 ) * added sbml validation to other parts of automated testing * added new SBML basics testing to test libsbml functions and other sbmlutil functions Co-authored-by: zoltuz * Mechanisms and Components interface better with Mixtures (#134) * Mechanisms and Components interface better with Mixtures Many changes regarding how Mechanisms and Components interface with Mixtures: * Component.mechanisms is now a property with a setter. Component.add_mechanism(s) are the best functions to add new mechanisms to Components. Mechanisms are copied when added to a Component. * Mixture.mechanisms is now a property with a setter. Mixture.add_mechanism(s) are the best functions to add new mechanisms to Mixtures. Mechanisms are copied when added to a Mixture. *Mixture and Component mechanism dictionaries are no longer design to be accessed directly. Instead use Component.get_mechanism(mechanism_type). This allows for the removal of "default_mechanisms", versus "custom_mechanisms" versus "mechanisms" in both Component and Mixture. Now each only has Mechanisms. First, the component mechanisms are searched, then the mixture mechanisms are searched. * Mixture.components is now a property with a setter. Mixture.add_component(s) are the best functions for adding Components to a Mixture. Components are copied when added to a Mixture. Mixture.get_component will return a Component from inside the mixture using a couple of keywords. * These new functions make subclassing mixtures and components easier. Now, in the construct of each, call super.__init__(...) then just add any mechanisms or components you want using add_mechanisms(...) or add_components(...), respectively. The example notebooks have been changed to reflect this. * A number of bug were also fixed - including a bug in parameter defaulting! * Fixed many errors in notebooks and added tests * Fixed error in Global Mech ipynb * Added tests for DNAassembly and GlobalMechanisms Additionally propogated some of the changes into DNAassembly - importantly when overwriting Mechanisms, DNAassembly never overwrites the mechanisms of its promoter and rbs, these must be accessed individually. * Fixed typo in Component.load_parameters & CRN.simulate_with_bioscrape_via_sbml * fixed bug in global mechanism Co-authored-by: William Poole * added contributing.md and updated version information * add full compatibility with the old Reaction class interface (#141) Reaction now workings with Propensity types, but for compatibility reasons the old (string based) is supported for now. * add sphinx docs files * modify setup.py for PyPi installation * update the README.md (#143) * update the README.md * update the README.md fixing typos * update the README.md fixing typos * updated link for documentation on readthe docs (#145) * add all argument to setup.py for optional dependencies. move plotting imports to plotting.py and remove from __init__ * try except blocks for all plotting libraries * move matplotlib inline to try except in ipynbs * add versioning information to README * add new DNA construction (#102) This commit adds a separate path to set up DNA assemblies where, for example, multiple binding sites are present on the DNA or other complicated biocircuits operations is needed (i.e. integrase in the future). This path is recommended when biocircuit is already built in the lab and a companion in silico model is needed. For exploratory biocircuits, DNAassembly class is still recommended. * DNAComplexSpecies * DNA binding site and dna_to_bind * OrderedPolymer new way to do DNA_construct * rerunning update_species happens in dna_construct * Added tests for DNA assembly and GlobalMechanisms Additionally propagated some of the changes into DNAassembly - importantly when overwriting Mechanisms, DNAassembly never overwrites the mechanisms of its promoter and rbs, these must be accessed individually. Co-authored-by: William Poole * merge from Dr3y/master (#153) * change the import order and remove import Co-authored-by: dr3y Co-authored-by: William Poole * Factor out Matplotlib, fixed tests requiring specific species (#149) * bugfix changes, remove matplotlib Co-authored-by: William Poole Co-authored-by: Zoltan Tuza * Bug Fixes & Global Mechanism Improvements (#144) * Modified CRN compilation Mixture.update_species & Mixture.update_reactions is removed. CRN.add_species and CRN.add_reactions is used instead to add species and reactions to the CRN, with the CRN doing the logic. Some tests have been changed accordingly. Additionally, new checking fro component.get_initial_condition to make sure component.mixture is defined. * Species.pretty_print now shows initial condition. * RNA_degredation_mm is now a global mechanism Note: this means mechanisms like Multi-tl work better because rna can be degraded, even when it is bound to ribosomes. DNA assemblies no longer look for RNA degredation. Also some changes to parameter naming in multi_tx and multi_tl to make things simpler * Fixed error with found/search keys and printing ParameterDatabase * recursive call in CRN.get_all_species_containing(species) & bugs in multi_tx multi_tl works for embedded ComplexSpecies now. index error in multi_tx and multi_tl causing bugs now fixed * Created a Deg-tagged protein mechanism * global mechanism name change * Fixed a bug in RNAase Degredation global mechanism Co-authored-by: William Poole Co-authored-by: Zoltan Tuza * add docstrings and some PEP8 formatting (#152) it also bugfix some typos and the length setter in component.py * factor out numpy dependency (#147) * factor out numpy dependencies * factor out numpy dependencies * refactor Jupyter notebooks all plotting related packages are now tested with try-except blocks * fixing import error * bugfix in DNA construct Example notebook * Support old dnaplotlib (#157) Co-authored-by: William Poole Co-authored-by: Zoltan Tuza * optimize package imports (#154) * remov old code in chemical_reaction_network.py. fix sbml_warnings keyword in simulate function Co-authored-by: William Poole Co-authored-by: Eldad Afik Co-authored-by: Zoltan Tuza Co-authored-by: dr3y Co-authored-by: William Poole --- .gitignore | 4 + .travis.yml | 7 + CRN.xml | 80 - Makefile | 20 + README.md | 76 +- Tests/test_DNAconstruct.py | 208 +++ Tests/test_chemicalReactionNetwork.py | 136 +- Tests/test_combinatorial_promoter.py | 107 +- Tests/test_complex.py | 23 + Tests/test_complex_species.py | 57 +- Tests/test_component.py | 150 +- Tests/test_dna_assembly.py | 134 ++ Tests/test_global_mechanism.py | 108 ++ Tests/test_initial_condition.py | 11 + Tests/test_mixture.py | 174 +- ...mixtures_and_components_combinatorially.py | 184 ++ Tests/test_parameter.py | 300 +++- Tests/test_polymer.py | 163 ++ Tests/test_propensities.py | 176 ++ Tests/test_reaction.py | 199 ++- Tests/test_sbml.py | 298 ++++ Tests/test_simulation_packages_import.py | 73 + Tests/test_species.py | 83 +- biocrnpyler/__init__.py | 53 +- biocrnpyler/chemical_reaction_network.py | 1231 ++----------- biocrnpyler/component.py | 384 ++-- biocrnpyler/components_basic.py | 277 +-- biocrnpyler/components_dcas9.py | 56 - biocrnpyler/crnlab.py | 15 +- biocrnpyler/dna_assembly.py | 300 ++-- biocrnpyler/dna_assembly_rbs.py | 44 - biocrnpyler/dna_construct.py | 781 +++++++++ biocrnpyler/dna_part.py | 129 ++ biocrnpyler/dna_part_cds.py | 28 + biocrnpyler/dna_part_misc.py | 78 + ...embly_promoter.py => dna_part_promoter.py} | 310 ++-- biocrnpyler/dna_part_rbs.py | 78 + biocrnpyler/dna_part_terminator.py | 15 + biocrnpyler/global_mechanism.py | 351 ++-- biocrnpyler/mechanism.py | 66 +- biocrnpyler/mechanisms_binding.py | 174 +- biocrnpyler/mechanisms_enzyme.py | 171 +- biocrnpyler/mechanisms_txtl.py | 699 ++++---- biocrnpyler/mixture.py | 635 ++++--- biocrnpyler/mixtures_cell.py | 202 ++- biocrnpyler/mixtures_extract.py | 156 +- biocrnpyler/parameter.py | 597 +++++-- biocrnpyler/pathutil.py | 6 +- biocrnpyler/plotting.py | 283 ++- biocrnpyler/polymer.py | 214 +++ biocrnpyler/propensities.py | 576 ++++++ biocrnpyler/reaction.py | 265 +++ biocrnpyler/sbmlutil.py | 433 ++--- biocrnpyler/species.py | 834 +++++++++ biocrnpyler/utils.py | 41 + conf.py | 62 + docs/CONTRIBUTING.md | 39 + docs/conf.py | 10 +- examples/1. Building CRNs Directly.ipynb | 189 +- ...s with Enzymes Catalysis and Binding.ipynb | 291 ++-- ...sion, transcription, and translation.ipynb | 677 ++++++-- ...lation, and Gene Regulatory Networks.ipynb | 829 +++++---- examples/5. Parameters.ipynb | 583 ++++++- examples/6. Global Mechanisms.ipynb | 429 +++-- examples/7. Network Plotting Examples.ipynb | 568 +----- examples/8. Developer Overview.ipynb | 139 +- examples/DNA_construct Examples.ipynb | 783 +++++++++ ...ples.ipynb => Advanced Examples.ipynb.old} | 208 +-- ...de.ipynb => Beginner User Guide.ipynb.old} | 0 examples/Old Examples and Tests/CRN.xml | 80 - examples/Old Examples and Tests/GFP.xml | 1547 ----------------- ... => Non-Massaction Propensities.ipynb.old} | 0 .../Testing Propensities.py | 40 +- .../Old Examples and Tests/bioscrape_test.xml | 249 --- examples/Old Examples and Tests/geneexpr.xml | 248 --- ...for_crn_and_component_and_write_to_sbml.py | 9 +- .../Old Examples and Tests/temp_sbml_file.xml | 65 - .../CombinatorialPromoter Details.ipynb | 337 ++-- .../MultiOccupancyTxTl_Demo.ipynb | 732 +++----- .../default_parameters.txt | 15 +- examples/build_crns_directly.xml | 70 - examples/default_parameters.txt | 12 +- examples/temp_sbml_file.xml | 70 - index.rst | 20 + make.bat | 35 + pytest.ini | 2 +- setup.py | 38 +- temp_sbml_file.xml | 65 - 88 files changed, 12576 insertions(+), 8118 deletions(-) delete mode 100644 CRN.xml create mode 100644 Makefile create mode 100644 Tests/test_DNAconstruct.py create mode 100644 Tests/test_complex.py create mode 100644 Tests/test_dna_assembly.py create mode 100644 Tests/test_global_mechanism.py create mode 100644 Tests/test_initial_condition.py create mode 100644 Tests/test_mixtures_and_components_combinatorially.py create mode 100644 Tests/test_polymer.py create mode 100644 Tests/test_propensities.py create mode 100644 Tests/test_sbml.py create mode 100644 Tests/test_simulation_packages_import.py delete mode 100644 biocrnpyler/components_dcas9.py delete mode 100644 biocrnpyler/dna_assembly_rbs.py create mode 100644 biocrnpyler/dna_construct.py create mode 100644 biocrnpyler/dna_part.py create mode 100644 biocrnpyler/dna_part_cds.py create mode 100644 biocrnpyler/dna_part_misc.py rename biocrnpyler/{dna_assembly_promoter.py => dna_part_promoter.py} (54%) create mode 100644 biocrnpyler/dna_part_rbs.py create mode 100644 biocrnpyler/dna_part_terminator.py create mode 100644 biocrnpyler/polymer.py create mode 100644 biocrnpyler/propensities.py create mode 100644 biocrnpyler/reaction.py create mode 100644 biocrnpyler/species.py create mode 100644 biocrnpyler/utils.py create mode 100644 conf.py create mode 100644 docs/CONTRIBUTING.md create mode 100644 examples/DNA_construct Examples.ipynb rename examples/Old Examples and Tests/{Advanced Examples.ipynb => Advanced Examples.ipynb.old} (96%) rename examples/Old Examples and Tests/{Beginner User Guide.ipynb => Beginner User Guide.ipynb.old} (100%) delete mode 100644 examples/Old Examples and Tests/CRN.xml delete mode 100644 examples/Old Examples and Tests/GFP.xml rename examples/Old Examples and Tests/{Non-Massaction Propensities.ipynb => Non-Massaction Propensities.ipynb.old} (100%) delete mode 100644 examples/Old Examples and Tests/bioscrape_test.xml delete mode 100644 examples/Old Examples and Tests/geneexpr.xml delete mode 100644 examples/Old Examples and Tests/temp_sbml_file.xml delete mode 100644 examples/build_crns_directly.xml delete mode 100644 examples/temp_sbml_file.xml create mode 100644 index.rst create mode 100644 make.bat delete mode 100644 temp_sbml_file.xml diff --git a/.gitignore b/.gitignore index 6c80405e..7732cc83 100644 --- a/.gitignore +++ b/.gitignore @@ -70,3 +70,7 @@ docs/_build/ # Ignore all local history of files **/.history .vscode/settings.json + +### BioCRNPlyer +# Ignore xml files generated by this toolbox +*.xml diff --git a/.travis.yml b/.travis.yml index db76956f..8bb221be 100644 --- a/.travis.yml +++ b/.travis.yml @@ -13,10 +13,17 @@ install: - pip install pytest-runner - pip install pytest-cov - pip install nbval + - pip install flake8-mutable + - pip install flake8 # command to run tests +# 1, pytest +# 2, flake8 checks for default mutable argument script: - "python setup.py test" + - flake8 --select M biocrnpyler + - if [[ `flake8 --select M biocrnpyler` ]]; then >&2 echo "default mutable argument detected"; exit 1 ; fi + # Push the results back to codecov after_success: diff --git a/CRN.xml b/CRN.xml deleted file mode 100644 index fb4cf464..00000000 --- a/CRN.xml +++ /dev/null @@ -1,80 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - type=proportionalhillnegative k=1.0 K=10.0 n=2 s1=protein_A d=dna_G - - - - - - - - - - - - - - - k - dna_G - - - - - - protein_A - n - - K - - - - - - - - - - - - - type=massaction k=0.1 - - - - - - - - - k - protein_X - - - - - - - - - - diff --git a/Makefile b/Makefile new file mode 100644 index 00000000..d4bb2cbb --- /dev/null +++ b/Makefile @@ -0,0 +1,20 @@ +# Minimal makefile for Sphinx documentation +# + +# You can set these variables from the command line, and also +# from the environment for the first two. +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = _build + +# Put it first so that "make" without argument is like "make help". +help: + @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) + +.PHONY: help Makefile + +# Catch-all target: route all unknown targets to Sphinx using the new +# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) diff --git a/README.md b/README.md index 7fca870c..99555cdc 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,79 @@ # BioCRNPyler -- Biomolecular Chemical Reaction Network Compiler -## Python toolbox to create CRN models in SBML for biomolecular mechanisms +## Python toolbox to create CRN models in SBML for biomolecular mechanisms [![Build Status](https://travis-ci.com/BuildACell/BioCRNPyler.svg?branch=master)](https://travis-ci.com/BuildACell/BioCRNPyler) [![codecov](https://codecov.io/gh/BuildACell/BioCRNPyler/branch/master/graph/badge.svg)](https://codecov.io/gh/BuildACell/BioCRNPyler) +[![PyPI version](https://badge.fury.io/py/biocrnpyler.svg)](https://badge.fury.io/py/biocrnpyler) + + +BioCRNPyler is a Python package for the creation, manipulation, +and study of the structure, dynamics, and functions +of complex networks. + +- **Website:** https://github.com/BuildACell/BioCRNPyler +- **Mailing list:** TBA +- **Source:** https://github.com/BuildACell/BioCRNPyler +- **Bug reports:** https://github.com/BuildACell/BioCRNPyler/issues +- **Documentation** [biocrnpyler.readthedocs.io](https://readthedocs.org/projects/biocrnpyler/) + +# Simple example + +Building a simple reaction network + +```python +from biocrnpyler import * +# let's build the following CRN +# A -->[k1] 2B +# B -->[k2] B+D +# Species +A = Species("A") +B = Species("B") +C = Species("C") +D = Species("D") + +#Reaction Rates +k1 = 3. +k2 = 1.4 + +#Reaciton Objects +R1 = Reaction.from_massaction([A], [B, B], k_forward = k1) +R2 = Reaction.from_massaction([B], [C, D], k_forward = k2) + +#Make a CRN +CRN = ChemicalReactionNetwork(species = [A, B, C, D], reactions = [R1, R2]) +print(CRN) +``` +More advanced examples can be found in the [example](https://github.com/BuildACell/BioCRNPyler/tree/master/examples) folder, +here's the first file in the Tutorial series: [Building CRNs](https://github.com/BuildACell/BioCRNPyler/blob/master/examples/1.%20Building%20CRNs%20Directly.ipynb) + +# Installation + + +Install the latest version of BioCRNPyler:: + + $ pip install biocrnpyler + +Install with all optional dependencies:: + + $ pip install biocrnpyler[all] + +Further details about the installation process can be found in the [BioCRNPyler wiki](https://github.com/BuildACell/BioCRNPyler/wiki#installation). +# Bugs +Please report any bugs that you find [here](https://github.com/BuildACell/BioCRNPyler/issues). +Or, even better, fork the repository on [GitHub](https://github.com/BuildACell/BioCRNPyler), +and create a pull request (PR). We welcome all changes, big or small, and we +will help you make the PR if you are new to `git` (just ask on the issue and/or +see `docs/CONTRIBUTING.md`). + +# Versions + +BioCRNpyler versions: + +* 1.0.0 (latest stable release): To install run `pip install biocrnpyler` +* 0.2.1 (alpha release): To install run `pip install biocrnpyler==0.2.1` + +# License +Released under the BSD 3-Clause License (see `LICENSE`) + +Copyright (c) 2020, Build-A-Cell. All rights reserved. + diff --git a/Tests/test_DNAconstruct.py b/Tests/test_DNAconstruct.py new file mode 100644 index 00000000..1ff510db --- /dev/null +++ b/Tests/test_DNAconstruct.py @@ -0,0 +1,208 @@ + +# Copyright (c) 2020, Build-A-Cell. All rights reserved. +# See LICENSE file in the project root directory for details. + +from unittest import TestCase +from biocrnpyler import * +import copy + +from biocrnpyler import Transcription_MM, Translation_MM, Degredation_mRNA_MM + +class TestDNAConstruct(TestCase): + def test_initialization(self): + myprom = Promoter("prom") + myrbs = RBS("rbs") + mycds = CDS("mycds","GFP") + myt = Terminator("t1") + myz = AttachmentSite("attB","attB",direction="forward",color="blue",color2="skyblue",sequence="agcgcga") + self.assertTrue("attB" in str(myz)) + + myconst = DNA_construct([myprom,\ + myrbs,\ + [mycds,"forward"],\ + [myt,"forward"]]) + + bspec = Species("prom_rbs_mycds_t1",material_type="dna") + #base species naming + self.assertEqual(myconst.base_species,bspec) + #Components are contained + self.assertTrue(myprom in myconst) + self.assertTrue(myrbs in myconst) + self.assertTrue(mycds in myconst) + self.assertTrue(myt in myconst) + self.assertTrue("prom" in myconst) + + spec = myconst.get_species() + p = copy.deepcopy(spec[0]) + p.remove() + u = copy.deepcopy(spec[1]) + u.remove() + c = copy.deepcopy(spec[2]) + c.remove() + t = copy.deepcopy(spec[3]) + t.remove() + self.assertTrue(p == Species(myprom.name,material_type="dna")) + self.assertTrue(u == Species(myrbs.name,material_type="dna")) + self.assertTrue(c == Species(mycds.name,material_type="dna")) + self.assertTrue(t == Species(myt.name,material_type="dna")) + for a in spec: + self.assertTrue(a.direction=="forward") + myconst2 = DNA_construct([[myt,"reverse"],\ + [mycds,"reverse"],\ + [myrbs,"reverse"],\ + [myprom,"reverse"]],circular=True) + self.assertTrue(myconst2.parts_list[0].direction=="reverse") + self.assertTrue(myconst2.parts_list[1].direction=="reverse") + self.assertTrue(myconst2.parts_list[2].direction=="reverse") + self.assertTrue(myconst2.parts_list[3].direction=="reverse") + myconst3 = copy.deepcopy(myconst) + myconst3.circular = True + myconst3.reverse() + self.assertTrue(myconst3==myconst2) + + #testing automatic name creation where we insert _r for reverse and _o for circular + self.assertTrue("_r_" in myconst2.name) + self.assertTrue("_o" in myconst2.name) + + #testing get_part + self.assertTrue(myconst.get_part(part=CDS("mycds","GFP")) == myconst[2]) + self.assertTrue(myconst.get_part(part_type=CDS) == myconst[2]) + self.assertTrue(myconst.get_part(name="mycds") == myconst[2]) + self.assertTrue(myconst.get_part(index=2) == myconst[2]) + + myt2 = Terminator("myt2") + myconst.insert(4,myt2.set_dir("forward")) + with self.assertWarnsRegex(Warning, 'multiple matching components'): + x = myconst.get_part(part_type=Terminator) + self.assertTrue(len(x)==2) + + def test_changes(self): + myprom = Promoter("prom") + myrbs = RBS("rbs") + mycds = CDS("mycds","GFP") + myt = Terminator("t1") + myt2 = Terminator("t2") + myconst = DNA_construct([myprom,\ + myrbs,\ + [mycds,"forward"],\ + [myt,"forward"]]) + self.assertTrue(myprom.name in myconst.name) + self.assertTrue(myrbs.name in myconst.name) + self.assertTrue(mycds.name in myconst.name) + self.assertTrue(myt.name in myconst.name) + #above, making sure that everything initialized right + myconst[3] = myt2 + #if you replace a part, the name should be different + self.assertTrue(myt2.name in myconst.name) + myconst.reverse() + #if you reverse, the name should change + self.assertTrue("_r" in myconst.name) + self.assertTrue(myconst[-1].name == myprom.name) + myconst = DNA_construct([myprom,\ + myrbs,\ + [mycds,"forward"],\ + [myt,"forward"]]) + myconst.insert(4,myt2) + self.assertTrue(myt2.name in myconst.name) + def test_txtl(self): + myprom = Promoter("prom") + myrbs = RBS("rbs") + myrbs2 = RBS("rbs2") + mycds = CDS("mycds","GFP") + mycds2 = CDS("mycds2","RFP") + myt = Terminator("t1") + + + mycdsNOSTOP = CDS("mycds3","CFP",no_stop_codons=["forward"]) + + myconst = DNA_construct([[myrbs,"forward"],\ + [myrbs,"forward"],\ + [mycdsNOSTOP, "forward"],\ + [mycds,"forward"],\ + [myt,"forward"], \ + [myprom,"forward"],\ + [myrbs2,"forward"],\ + [mycds2,"forward"]],circular=True) + rnas,proteins = myconst.explore_txtl() + + #circular construct properly makes RNA + self.assertTrue(myconst[5] in rnas) + + myTranscript = rnas[myconst[5]] + myRBS = myTranscript[0] + myRBSnotl = myTranscript[2] + myRBS2 = myTranscript[3] + myCDS = myTranscript[1] + myCDS2 = myTranscript[4] + myCDS3 = myTranscript[5] + #transcript is made + self.assertTrue(myTranscript in proteins) + #two RBSes found in the transcript + self.assertTrue(myRBS in proteins[myTranscript]) + self.assertTrue(myRBSnotl in proteins[myTranscript]) + self.assertTrue(myRBS2 in proteins[myTranscript]) + #proper protein is made by the right RBS + self.assertTrue(myCDS in proteins[myTranscript][myRBS]) + self.assertTrue(myCDS2 in proteins[myTranscript][myRBS2]) + self.assertTrue(myCDS3 in proteins[myTranscript][myRBS2]) + self.assertTrue(proteins[myTranscript][myRBSnotl]==[]) + #CDSes have the right name + self.assertTrue(proteins[myTranscript][myRBS][0].name==mycds2.name) + self.assertTrue(proteins[myTranscript][myRBS2][1].name==mycds.name) + + + def test_dna_construct_species(self): + myprom = Promoter("prom") + myrbs = RBS("rbs") + myrbs2 = RBS("rbs2") + mycds = CDS("mycds","GFP") + mycds2 = CDS("mycds2","RFP") + myt = Terminator("t1") + myt2 = Terminator("t2") + myconst = DNA_construct([[myrbs,"forward"],\ + [mycds,"forward"],\ + [myt,"forward"], \ + [myprom,"forward"],\ + [myrbs2,"forward"],\ + [mycds2,"forward"]], \ + circular=True) + parameters={"cooperativity":2,"kb":100, "ku":10, "ktx":.05, "ktl":.2, "kdeg":2,"kint":.05} + myMixture = TxTlExtract(name = "txtl", parameters = parameters, \ + components = [myconst]) + myCRN = myMixture.compile_crn() + myspec = myCRN.species + myrxn = myCRN.reactions + #TODO check if these species and reactions are correct + #generating the right number of species and reactions + self.assertTrue(len(myspec)>3) + self.assertTrue(len(myrxn)>3) + numspec = len(myspec) + numrxn = len(myrxn) + #one promoter makes one rna + self.assertTrue(sum([spec.material_type=="rna" for spec in myspec])==1) + + newplist = list(myconst.parts_list[:3])+[[myprom,"reverse"]]+list(myconst.parts_list[3:]) + myconst2 = DNA_construct(newplist,circular=True) + myMixture2 = TxTlExtract(name = "txtl", parameters = parameters, \ + components = [myconst2]) + myCRN2 = myMixture2.compile_crn() + #we add a promoter and more reactions and species are made + self.assertTrue(len(myCRN2.species)>numspec) + self.assertTrue(len(myCRN2.reactions)>numrxn) + #now there are two promoters + self.assertTrue(sum([spec.material_type=="rna" for spec in myCRN2.species])==2) + + #make sure we saved the predicted values + mc2_from_mix = myMixture2.get_component(name=myconst2.name) + self.assertTrue(mc2_from_mix.predicted_rnas is not None) + self.assertTrue(mc2_from_mix.predicted_proteins is not None) + mc2_from_mix[4]=myt2.set_dir("forward") + #now, when we change the cosntruct, the previous values are not valid any more + self.assertTrue(mc2_from_mix.predicted_rnas is None) + self.assertTrue(mc2_from_mix.predicted_proteins is None) + + + + + + diff --git a/Tests/test_chemicalReactionNetwork.py b/Tests/test_chemicalReactionNetwork.py index 6098310e..a92615d4 100644 --- a/Tests/test_chemicalReactionNetwork.py +++ b/Tests/test_chemicalReactionNetwork.py @@ -4,8 +4,10 @@ from unittest import TestCase from unittest.mock import mock_open, patch -from biocrnpyler import ChemicalReactionNetwork, Species, Reaction +from biocrnpyler import ChemicalReactionNetwork, Species, Reaction, Complex +from biocrnpyler import ProportionalHillPositive, ParameterEntry, ParameterKey import libsbml +import warnings class TestChemicalReactionNetwork(TestCase): @@ -17,16 +19,19 @@ def setUp(self) -> None: self.s3 = Species(name='test_species3') self.s4 = Species(name='test_species4') + self.s_old = Species("s_old") + self.s_new = Species("s_new") + self.species_list = [self.s1, self.s2] # creating a valid reaction two species - self.rx1 = Reaction(inputs=[self.s1], outputs=[self.s2], k=0.1) + self.rx1 = Reaction.from_massaction(inputs=[self.s1], outputs=[self.s2], k_forward=0.1) self.rxn_list = [self.rx1] self.crn = ChemicalReactionNetwork(species=self.species_list, reactions=self.rxn_list) def test_check_crn_validity(self): - checked_species, checked_reactions = ChemicalReactionNetwork.check_crn_validity(reactions=self.rxn_list, + checked_reactions, checked_species = ChemicalReactionNetwork.check_crn_validity(reactions=self.rxn_list, species=self.species_list) # test that the returned species list is the same as the species list supplied self.assertEqual(self.species_list, checked_species) @@ -39,34 +44,46 @@ def test_check_crn_validity(self): # test whether a non-species object is detected and Value error has been raised # A non-species object was used as a species: [test_species1, test_species2, None]!"' # A non-species object was used as a species: [test_species1, test_species2, None]!" - with self.assertRaisesRegexp(ValueError, "A non-species object was used as a species!"): + with self.assertRaisesRegex(ValueError, "A non-species object was used as a species!"): ChemicalReactionNetwork.check_crn_validity(reactions=self.rxn_list, species=species_list_with_none) rxn_list_with_none = self.rxn_list.copy() # injecting a None to the reaction list rxn_list_with_none.append(None) # test whether a non-reaction object is detected and Value Error has been raised - with self.assertRaisesRegexp(ValueError, 'A non-reaction object was used as a reaction!'): + with self.assertRaisesRegex(ValueError, 'A non-reaction object was used as a reaction!'): ChemicalReactionNetwork.check_crn_validity(reactions=rxn_list_with_none, species=self.species_list) - rxn2 = Reaction(inputs=[self.s1], outputs=[self.s3], k=0.1) + rxn2 = Reaction.from_massaction(inputs=[self.s1], outputs=[self.s3], k_forward=0.1) # test warning raised if a species (in the reaction outputs) is detected which is not part of the species list - with self.assertWarnsRegex(Warning, f'contains a species {self.s3.name} which is not in the CRN'): - ChemicalReactionNetwork.check_crn_validity(reactions=[rxn2], species=self.species_list, warnings=True) + with self.assertWarnsRegex(Warning, f'are not part of any reactions in the CRN'): + ChemicalReactionNetwork.check_crn_validity(reactions=[rxn2], species=self.species_list, show_warnings=True) - rxn3 = Reaction(inputs=[self.s4], outputs=[self.s2], k=0.1) + rxn3 = Reaction.from_massaction(inputs=[self.s4], outputs=[self.s2], k_forward=0.1) # test warning raised if a species (in the reaction inputs) is detected which is not part of the species list - with self.assertWarnsRegex(Warning, f'contains a species {self.s4.name} which is not in the CRN'): - ChemicalReactionNetwork.check_crn_validity(reactions=[rxn3], species=self.species_list, warnings=True) + with self.assertWarnsRegex(Warning, f'are not part of any reactions in the CRN'): + ChemicalReactionNetwork.check_crn_validity(reactions=[rxn3], species=self.species_list, show_warnings=True) + + # test warning if reaction has unlisted species + rxn4 = Reaction.from_massaction(inputs=[self.s4, self.s3], outputs=[self.s2], k_forward=0.1) + with self.assertWarnsRegex(Warning, f'are not listed in the Species list, but part of the reactions'): + ChemicalReactionNetwork.check_crn_validity(reactions=[rxn4], species=[self.s4, self.s2], show_warnings=True) - # test duplicate reactions + # test duplicate reactions are both added rxn_list = [self.rx1, self.rx1] + + CRN = ChemicalReactionNetwork(species = [self.s1, self.s2], reactions = rxn_list) + self.assertTrue(CRN.reactions.count(self.rx1) == 2) + with self.assertWarnsRegex(Warning, 'may be duplicated in CRN definitions'): - ChemicalReactionNetwork.check_crn_validity(reactions=rxn_list, species=self.species_list, warnings=True) + ChemicalReactionNetwork.check_crn_validity(reactions=rxn_list, species=self.species_list, show_warnings=True) - def test_species_index(self): - # TODO add test if we actually use this function - pass + # test warning suppression + with warnings.catch_warnings(record=True) as w: + # Cause all warnings to always be triggered. + ChemicalReactionNetwork.check_crn_validity(reactions=rxn_list, species=self.species_list, show_warnings=False) + + assert not w def test_initial_condition_vector(self): @@ -85,7 +102,7 @@ def test_initial_condition_vector(self): def test_get_all_species_containing(self): # test that the species arument must be Species object - with self.assertRaisesRegexp(ValueError, 'species argument must be an instance of Species!'): + with self.assertRaisesRegex(ValueError, 'species argument must be an instance of Species!'): self.crn.get_all_species_containing(species=self.species_list) # s3 is not part of the CRN @@ -101,36 +118,73 @@ def test_get_all_species_containing(self): rtn_species_list = self.crn.get_all_species_containing(species=self.s1, return_as_strings=True) self.assertEqual(rtn_species_list, [repr(self.s1)]) - def test_generate_sbml_model(self): - - # generate an sbml model - document, model = self.crn.generate_sbml_model() - # all species from the CRN are accounted for - self.assertEqual(len(model.getListOfSpecies()), len(self.crn.species)) - # all reactions from the CRN are accounted for - self.assertEqual(len(model.getListOfReactions()), len(self.crn.reactions)) - - # test a reversible reaction - rx1 = Reaction(inputs=[self.s1], outputs=[self.s2], k=0.1, k_rev=0.1) - rxn_list = [rx1] - crn = ChemicalReactionNetwork(species=self.species_list, reactions=rxn_list) - - # generate an sbml model - document, model = crn.generate_sbml_model() - # all species from the CRN are accounted for - self.assertEqual(len(model.getListOfSpecies()), len(crn.species)) - # all reactions from the CRN are accounted for - # the sbml represents a reverisble reaction with to separate reactions - self.assertEqual(len(model.getListOfReactions()), 2*len(crn.reactions)) + def test_replace_species_in_Species(self): + + #Test replace species in a Species + self.assertTrue(self.s1.replace_species(self.s2, self.s_new) == self.s1) + self.assertTrue(self.s_old.replace_species(self.s_old, self.s_new) == self.s_new) + + def test_replace_Species_in_ComplexSpecies(self): + c1 = Complex([self.s1, self.s_old]) + c2 = Complex([self.s1, c1]) + self.assertTrue(c1.replace_species(self.s2, self.s_new) == c1) + self.assertTrue(c1.replace_species(self.s_old, self.s_new) == Complex([self.s1, self.s_new])) + self.assertTrue(c2 == Complex([self.s1, c1])) + self.assertTrue(c2.replace_species(self.s_new, self.s_old) == Complex([self.s1, Complex([self.s1, self.s_old])])) + + def test_replace_Species_in_OrderedComplexSpecies(self): + oc1 = Complex([self.s1, self.s_old], ordered = True) + self.assertTrue(oc1.replace_species(self.s_old, self.s_new) == Complex([self.s1, self.s_new], ordered = True)) + + def test_replace_species_in_Reaction(self): + c1 = Complex([self.s1, self.s_old]) + c2 = Complex([self.s1, self.s_new]) + r1 = Reaction.from_massaction([self.s1, self.s_old], [c1], k_forward=1) + self.assertTrue(r1.replace_species(self.s_old, self.s_new) == Reaction.from_massaction([self.s1, self.s_new], [c2], k_forward=1)) + + def test_replace_species_with_a_non_massaction_reaction(self): + c1 = Complex([self.s1, self.s_old]) + + prop_hill_old = ProportionalHillPositive(k=1., s1=self.s1, K=10, d=self.s_old, n=2) + r1 = Reaction([self.s1, self.s_old], [c1], propensity_type=prop_hill_old) + prop_hill_new = ProportionalHillPositive(k=1., s1=self.s1, K=10, d=self.s_new, n=2) + r1_new = Reaction([self.s1, self.s_new], [c1.replace_species(self.s_old, self.s_new)], propensity_type=prop_hill_new) + self.assertTrue(r1.replace_species(self.s_old, self.s_new) == r1_new) + + def test_replace_in_a_chemical_reaction_network(self): + c1 = Complex([self.s1, self.s_old]) + c2 = Complex([self.s1, c1]) + species = [self.s1, self.s_old, c1, c2] + r1 = Reaction.from_massaction([self.s1, self.s_old], [c1], k_forward=1) + crn = ChemicalReactionNetwork(species = species, reactions = [r1]) + new_crn = crn.replace_species(self.s_old, self.s_new) + + self.assertTrue(self.s1 in new_crn.species) + self.assertFalse(self.s_old in new_crn.species) + + self.assertTrue(self.s_new in new_crn.species) + self.assertFalse(c1 in new_crn.species) + self.assertFalse(c2 in new_crn.species) + c1_new = Complex([self.s1, self.s_new]) + c2_new = Complex([self.s1, c1_new]) + self.assertTrue(c1_new in new_crn.species) + self.assertTrue(c2_new in new_crn.species) + r1_new = Reaction.from_massaction([self.s1, self.s_new], [c1_new], k_forward=1) + self.assertFalse(r1 in new_crn.reactions) + self.assertTrue(r1_new in new_crn.reactions) def test_write_sbml_file(self): + s1, s2 = Species("S1"), Species("S2") + rx1 = Reaction.from_massaction(inputs=[s1], outputs=[s2], k_forward=0.1) + crn = ChemicalReactionNetwork(species = [s1, s2], reactions = [rx1]) - document, _ = self.crn.generate_sbml_model(model_id = 'test_model') + model_id = 'test_model' + document, _ = crn.generate_sbml_model(model_id=model_id) sbml_string = libsbml.writeSBMLToString(document) file_name = 'test_sbml.xml' with patch("builtins.open", new=mock_open()) as _file: - self.crn.write_sbml_file(file_name, model_id = 'test_model') + crn.write_sbml_file(file_name, model_id=model_id) _file.assert_called_once_with(file_name, 'w') - _file().write.assert_called_once_with(sbml_string) + _file().write.assert_called_once_with(sbml_string) \ No newline at end of file diff --git a/Tests/test_combinatorial_promoter.py b/Tests/test_combinatorial_promoter.py index ee6faf8f..b9fe2224 100644 --- a/Tests/test_combinatorial_promoter.py +++ b/Tests/test_combinatorial_promoter.py @@ -32,95 +32,110 @@ def test_initialization(self): self.assertTrue(newprom4.regulators == [Species("treg1",material_type="protein"), Species("treg2",material_type="rna")]) #make sure the default mechanism is the correct one - self.assertTrue(isinstance(newprom4.default_mechanisms["binding"],Combinatorial_Cooperative_Binding)) + self.assertTrue(isinstance(newprom4.mechanisms["binding"],Combinatorial_Cooperative_Binding)) def test_update_species(self): from biocrnpyler import CombinatorialPromoter, Protein, Species, Combinatorial_Cooperative_Binding, \ - DNAassembly,Transcription_MM, Translation_MM, Multimer, ComplexSpecies + DNAassembly,Transcription_MM, Translation_MM, Multimer, Complex #make a complicated promoter newprom = CombinatorialPromoter("testprom",["treg1",Species("treg2",material_type="rna")],\ tx_capable_list = [["treg1","treg2"]],cooperativity={"testprom_treg2":1},leak=True) + sp_rnap = Species("RNAP",material_type="protein") + ribosome = Species("Ribo", material_type = "protein") + newdna = DNAassembly("testDNA",promoter=newprom) - newdna.update_mechanisms(mechanisms={"transcription":Transcription_MM(), "translation":Translation_MM()}) + newdna.add_mechanisms({"transcription":Transcription_MM(rnap = sp_rnap), "translation":Translation_MM(ribosome = ribosome)}) newdna.update_parameters(parameters={"cooperativity":2,"kb":100, "ku":10, "ktx":.05, "ktl":.2, "kdeg":2}) - newprom_spec = newprom.update_species() + + #Promoters are copied when added to DNAassemblies + newprom_copy = newdna.promoter + newprom_spec = newprom_copy.update_species() sp_treg1 = Species("treg1",material_type="protein") sp_treg2 = Species("treg2",material_type="rna") #mu_treg2 = Multimer(sp_treg2,2) sp_dna = Species("testDNA",material_type="dna") - sp_rnap = Species("RNAP",material_type="protein") + sp_rna = Species("testDNA",material_type="rna") - cp_dna_rnap = ComplexSpecies([sp_dna,sp_rnap]) - cp_dna_treg1 = ComplexSpecies([sp_dna,sp_treg1,sp_treg1]) - cp_dna_treg2 = ComplexSpecies([sp_dna,sp_treg2]) - cp_dna_treg1_rnap = ComplexSpecies([cp_dna_treg1,sp_rnap]) - cp_dna_treg2_rnap = ComplexSpecies([cp_dna_treg2,sp_rnap]) - cp_dna_treg1_treg2 = ComplexSpecies([sp_dna,sp_treg1,sp_treg1,sp_treg2]) - cp_dna_treg1_treg2_rnap = ComplexSpecies([cp_dna_treg1_treg2,sp_rnap]) + cp_dna_rnap = Complex([sp_dna,sp_rnap]) + cp_dna_treg1 = Complex([sp_dna,sp_treg1,sp_treg1]) + cp_dna_treg2 = Complex([sp_dna,sp_treg2]) + cp_dna_treg1_rnap = Complex([cp_dna_treg1,sp_rnap]) + cp_dna_treg2_rnap = Complex([cp_dna_treg2,sp_rnap]) + cp_dna_treg1_treg2 = Complex([sp_dna,sp_treg1,sp_treg1,sp_treg2]) + cp_dna_treg1_treg2_rnap = Complex([cp_dna_treg1_treg2,sp_rnap]) knownspecies = [sp_dna,sp_rnap,sp_rna,cp_dna_rnap,cp_dna_treg1,\ cp_dna_treg2,cp_dna_treg1_treg2,cp_dna_treg1_rnap, \ - cp_dna_treg2_rnap,cp_dna_treg1_treg2_rnap] + cp_dna_treg2_rnap,cp_dna_treg1_treg2_rnap,sp_treg1,sp_treg2] #these are the species that should come out test_set = set([str(a) for a in newprom_spec]) + mistake_found = False - #we should have the correct length of species - self.assertTrue(len(test_set)==len(knownspecies)) + error_txt = "" for known_spec in knownspecies: #go through and check each species if it's in the set generated by the promoter if(str(known_spec) not in test_set): - print("couldn't find "+str(known_spec)) + error_txt += "\ncouldn't find "+str(known_spec) mistake_found = True - break + + if mistake_found: + raise ValueError(f"Mistake found in Species output:{error_txt}. Returned Species: {test_set}.") + #we should have the correct length of species + self.assertTrue(len(test_set)==len(knownspecies)) self.assertTrue(not mistake_found) - def test_update_reactions(self): """this function tests the CombinatorialPromoter for the ability to make reactions with the proper inputs and outputs.""" from biocrnpyler import CombinatorialPromoter, Protein, Species, Combinatorial_Cooperative_Binding, \ - DNAassembly,Transcription_MM, Translation_MM, ComplexSpecies, Multimer + DNAassembly,Transcription_MM, Translation_MM, Complex, Multimer, ParameterKey #make a relatively simple combinatorial promoter - newprom = CombinatorialPromoter("testprom",["treg1","treg2"],tx_capable_list=[["treg2","treg1"]], leak = True) + parameters={"cooperativity":2,"kb":100, "ku":10, "ktx":.05, + ParameterKey(mechanism = None, part_id = "testprom_leak", name = "ktx"):.01, + ParameterKey(mechanism = None, part_id = "testprom_leak", name = "ku"):50, + ParameterKey(mechanism = None, part_id = "testprom_treg1_treg2_RNAP", name = "ku"):5} + + newprom = CombinatorialPromoter("testprom",["treg1","treg2"],tx_capable_list=[["treg2","treg1"]], leak = True, parameters = parameters) #you have to put it into an assembly newdna = DNAassembly("testDNA",promoter=newprom) #adding mechanisms because there is no mixture. I believe this is what the mixture does - newdna.update_mechanisms(mechanisms={"transcription":Transcription_MM(), "translation":Translation_MM()}) - newdna.update_parameters(parameters={"cooperativity":2,"kb":100, "ku":10, "ktx":.05, ("testprom_leak","ktx"):.01,\ - ("testprom_leak","ku"):50,("testprom_treg1_treg2_RNAP","ku"):5}) + sp_rnap = Species("RNAP",material_type="protein") + ribosome = Species("Ribo", material_type = "protein") + + newdna.add_mechanisms({"transcription":Transcription_MM(rnap = sp_rnap), "translation":Translation_MM(ribosome = ribosome)}) #you have to do update_species first - newprom_spec = newprom.update_species() + newprom_copy = newdna.promoter #Promoters are copied when added to DNAassemblies + newprom_spec = newprom_copy.update_species() #now the test... does it produce the right reactions?? - newprom_rxns = newprom.update_reactions() + newprom_rxns = newprom_copy.update_reactions() #here i am generating the species manually sp_dna = Species("testDNA",material_type="dna") sp_rna = Species("testDNA",material_type="rna") sp_treg1 = Species("treg1",material_type="protein") sp_treg2 = Species("treg2",material_type="protein") - sp_rnap = Species("RNAP",material_type="protein") #now the complexes - sp_dna_treg1 = ComplexSpecies([sp_dna,sp_treg1,sp_treg1]) - sp_dna_treg2 = ComplexSpecies([sp_dna,sp_treg2,sp_treg2]) - sp_dna_treg1_treg2 = ComplexSpecies([sp_dna,sp_treg2,sp_treg2,sp_treg1,sp_treg1]) - sp_dna_rnap = ComplexSpecies([sp_dna,sp_rnap]) - sp_dna_treg1_rnap = ComplexSpecies([sp_dna_treg1,sp_rnap]) - sp_dna_treg2_rnap = ComplexSpecies([sp_dna_treg2,sp_rnap]) - sp_dna_treg1_treg2_rnap = ComplexSpecies([sp_dna_treg1_treg2,sp_rnap]) + sp_dna_treg1 = Complex([sp_dna,sp_treg1,sp_treg1]) + sp_dna_treg2 = Complex([sp_dna,sp_treg2,sp_treg2]) + sp_dna_treg1_treg2 = Complex([sp_dna,sp_treg2,sp_treg2,sp_treg1,sp_treg1]) + sp_dna_rnap = Complex([sp_dna,sp_rnap]) + sp_dna_treg1_rnap = Complex([sp_dna_treg1,sp_rnap]) + sp_dna_treg2_rnap = Complex([sp_dna_treg2,sp_rnap]) + sp_dna_treg1_treg2_rnap = Complex([sp_dna_treg1_treg2,sp_rnap]) #print('\n\n'.join([str(a) for a in newprom_rxns])) #now, we generate the reaction input outputs manually r0 = [set([sp_rnap,sp_dna]),set([sp_dna_rnap]),100,50] #RNAP binding to DNA - r1 = [set([sp_dna_rnap]),set([sp_dna,sp_rna,sp_rnap]),.01,0] #leaky transcription + r1 = [set([sp_dna_rnap]),set([sp_dna,sp_rna,sp_rnap]),.01,None] #leaky transcription r2 = [set([sp_dna,sp_treg1]),set([sp_dna_treg1]),100,10] #treg1 binding r3 = [set([sp_dna_treg1,sp_rnap]),set([sp_dna_treg1_rnap]),100,50] #rnap binding to treg1 bound dna - r4 = [set([sp_dna_treg1_rnap]),set([sp_dna_treg1,sp_rnap,sp_rna]),.01,0] #leaky tx from single regulator - r5 = [set([sp_dna_treg2_rnap]),set([sp_dna_treg2,sp_rnap,sp_rna]),.01,0] #leaky tx from single regulator - r6 = [set([sp_dna_treg1_treg2_rnap]),set([sp_dna_treg1_treg2,sp_rnap,sp_rna]),.05,0] #ktx for regular tx + r4 = [set([sp_dna_treg1_rnap]),set([sp_dna_treg1,sp_rnap,sp_rna]),.01,None] #leaky tx from single regulator + r5 = [set([sp_dna_treg2_rnap]),set([sp_dna_treg2,sp_rnap,sp_rna]),.01,None] #leaky tx from single regulator + r6 = [set([sp_dna_treg1_treg2_rnap]),set([sp_dna_treg1_treg2,sp_rnap,sp_rna]),.05,None] #ktx for regular tx r7 = [set([sp_dna_treg2,sp_rnap]),set([sp_dna_treg2_rnap]),100,50] #rnap binding to treg2 bound dna r8 = [set([sp_dna,sp_treg2]),set([sp_dna_treg2]),100,10] #treg2 binding r9 = [set([sp_dna_treg1,sp_treg2]),set([sp_dna_treg1_treg2]),100,10] #treg2 binding to dna that already has treg1 @@ -129,27 +144,25 @@ def test_update_reactions(self): truthlist = [r0,r1,r2,r3,r4,r5,r6,r7,r8,r9,r10,r11] #print('\n\n'.join([str(a) for a in newprom_rxns])) for rxn in newprom_rxns: - in_outs = [set(rxn.inputs),set(rxn.outputs)] + in_outs = [set([i.species for i in rxn.inputs]), set([o.species for o in rxn.outputs])] correctPick = False for rset in truthlist: #go through all the reactions and make sure that #they have the correct inputs, outputs, and constants. if(rset[0]==in_outs[0] and rset[1] == in_outs[1]): - self.assertTrue(rxn.k==rset[2]) - self.assertTrue(rxn.k_r==rset[3]) + self.assertTrue(rxn.propensity_type.k_forward == rset[2]) + self.assertTrue(rxn.propensity_type.k_reverse == rset[3]) correctPick = True break self.assertTrue(correctPick) #12 reactions must be generated self.assertTrue(len(newprom_rxns)==len(truthlist)) - #TODO: tests below this are questionable #then we should also test what happens if you say that nothing can transcribe: - newprom2 = CombinatorialPromoter("testprom",["treg1"])#,tx_capable_list = []) + newprom2 = CombinatorialPromoter("testprom",["treg1"], parameters = parameters,tx_capable_list = [],leak=False,\ + mechanisms={"transcription":Transcription_MM(rnap = sp_rnap), "translation":Translation_MM(ribosome = ribosome)}) newdna2 = DNAassembly("testDNA",promoter=newprom2) #adding mechanisms because there is no mixture. I believe this is what the mixture does - newdna2.update_mechanisms(mechanisms={"transcription":Transcription_MM(), "translation":Translation_MM()}) - newdna2.update_parameters(parameters={"cooperativity":2,"kb":100, "ku":10, "ktx":.05}) - with self.assertWarns(UserWarning): - #TODO fix this with a warning detection system that actually checks for the proper warning - newprom_rxns = newprom2.update_reactions() + sp_rnap = Species("RNAP",material_type="protein") + ribosome = Species("Ribo", material_type = "protein") + self.assertWarnsRegex(UserWarning, 'nothing can transcribe',newdna2.update_reactions) diff --git a/Tests/test_complex.py b/Tests/test_complex.py new file mode 100644 index 00000000..d7fea037 --- /dev/null +++ b/Tests/test_complex.py @@ -0,0 +1,23 @@ +# Copyright (c) 2019, Build-A-Cell. All rights reserved. +# See LICENSE file in the project root directory for details. + +from unittest import TestCase +from biocrnpyler import OrderedPolymer, OrderedMonomer, OrderedPolymerSpecies, Species, ComplexSpecies, Complex, OrderedComplexSpecies + +class TestComplex(TestCase): + def test_complex(self): + a = Species('A') + b = Species('B') + c = Complex([a,b]) + d = OrderedPolymerSpecies([a,b,a]) + #normal complex that makes complex species + self.assertEqual(set(c.species),set([a,b])) + self.assertTrue(type(c)==ComplexSpecies) + #Polymer Complex + testpoly = Complex([d[1],a]).parent + truth = OrderedPolymerSpecies([a,Complex([b,a]),a]) + self.assertEqual(testpoly,truth) + #Ordered Complex + truth = OrderedComplexSpecies([a,Complex([b,a]),a]) + testcomplx = Complex([a,Complex([b,a]),a],ordered=True) + self.assertEqual(truth,testcomplx) \ No newline at end of file diff --git a/Tests/test_complex_species.py b/Tests/test_complex_species.py index 196796c4..ae9ad3cc 100644 --- a/Tests/test_complex_species.py +++ b/Tests/test_complex_species.py @@ -19,49 +19,52 @@ def test_species_initialization(self): s2 = Species(name='s2', material_type="m2") # Check invalidity of ComplexSpecies with fewer than 2 component - with self.assertRaisesRegexp(ValueError,'chemical_reaction_network.complex requires ' + with self.assertRaisesRegex(ValueError,'chemical_reaction_network.complex requires ' '2 or more species in its constructor'): - ComplexSpecies([s1]) + ComplexSpecies([s1], called_from_complex = True) # Check invalidity of OrderedComplexSpecies with fewer than 2 component - with self.assertRaisesRegexp(ValueError, 'chemical_reaction_network.complex requires 2 ' + with self.assertRaisesRegex(ValueError, 'chemical_reaction_network.complex requires 2 ' 'or more species in its constructor.'): - OrderedComplexSpecies([s1]) + OrderedComplexSpecies([s1], called_from_complex = True) # Check invalidity of multimers with fewer than 2 component - with self.assertRaisesRegexp(ValueError, 'chemical_reaction_network.complex requires 2 ' + with self.assertRaisesRegex(ValueError, 'chemical_reaction_network.complex requires 2 ' 'or more species in its constructor'): - Multimer(s1, 1) + Multimer(s1, 1, called_from_complex = True) # Check the naming conventions - oc1 = OrderedComplexSpecies([s2, s1]) - c1 = ComplexSpecies([s2, s1]) - m1 = Multimer(s1, 2) - c3 = ComplexSpecies([s1, s1]) + oc1 = OrderedComplexSpecies([s2, s1], called_from_complex = True) + c1 = ComplexSpecies([s2, s1], called_from_complex = True) + m1 = Multimer(s1, 2, called_from_complex = True) + c3 = ComplexSpecies([s1, s1], called_from_complex = True) - # Check validity of ComplexSpecies, Multimers and OrderedComplexSpecies with strings instead of species - self.assertEqual(OrderedComplexSpecies([s2, "s1"]), oc1) - self.assertEqual(ComplexSpecies([s2, "s1"]), c1) - self.assertEqual(Multimer("s1", 2), m1) + # Check invalidity of ComplexSpecies, Multimers and OrderedComplexSpecies with strings instead of species + with self.assertRaisesRegex(TypeError, 'recieved a non-species as a member of the list species'): + self.assertEqual(OrderedComplexSpecies([s2, "s1"]), oc1) + self.assertEqual(ComplexSpecies([s2, "s1"]), c1) + self.assertEqual(Multimer("s1", 2), m1) + # ComplexSpecies should sort the species added alphabetically by representation - self.assertEqual(repr(c1), "complex_"+repr(s2)+"_"+repr(s1)) + #an extra underscore is added at the end of the representation to deal with embedded complexes. + self.assertEqual(repr(c1), "complex_"+repr(s2)+"_"+repr(s1)+"_") # OrderedComplexSpecies do not sort their internal species - self.assertEqual(repr(oc1), "ordered_complex_"+repr(s2)+"_"+repr(s1)) + self.assertEqual(repr(oc1), "ordered_complex_"+repr(s2)+"_"+repr(s1)+"_") # Multimers are just complexes with multiplicity - self.assertEqual(repr(m1), "complex_2x_"+repr(s1)) + self.assertEqual(repr(m1), "complex_"+repr(s1)+"_2x_") self.assertEqual(repr(c3), repr(m1)) # Nested list creation of ComplexSpecies - c1 = ComplexSpecies([s1, [s2, s1]]) - c2 = ComplexSpecies([s1, s2, s1]) + c1 = ComplexSpecies([s1, [s2, s1]], called_from_complex = True) + c2 = ComplexSpecies([s1, s2, s1], called_from_complex = True) self.assertEqual(c1, c2) - c1 = OrderedComplexSpecies([s1, [s2, s1]]) - c2 = OrderedComplexSpecies([s1, s2, s1]) - c3 = OrderedComplexSpecies([s1, [s1, s2]]) + c1 = OrderedComplexSpecies([s1, [s2, s1]], called_from_complex = True) + c2 = OrderedComplexSpecies([s1, s2, s1], called_from_complex = True) + c3 = OrderedComplexSpecies([s1, [s1, s2]], called_from_complex = True) self.assertEqual(c1, c2) self.assertFalse(c1==c3) @@ -70,11 +73,13 @@ def test_species_equality(self): s1 = Species(name='s1', material_type="m1") s2 = Species(name='s2', material_type="m2") - c1 = ComplexSpecies([s1, s2]) - c2 = ComplexSpecies([s2, s1]) + c1 = ComplexSpecies([s1, s2], called_from_complex = True) + c2 = ComplexSpecies([s2, s1], called_from_complex = True) # Check equality of differently ordered complexes self.assertEqual(c1, c2) - oc1 = OrderedComplexSpecies([s2, s1]) - oc2 = OrderedComplexSpecies([s1, s2]) + oc1 = OrderedComplexSpecies([s2, s1], called_from_complex = True) + oc2 = OrderedComplexSpecies([s1, s2], called_from_complex = True) self.assertFalse(oc1 == oc2) + #check of __contains__ + self.assertTrue(s1 in c1) diff --git a/Tests/test_component.py b/Tests/test_component.py index 436eaf1f..27e3bc4a 100644 --- a/Tests/test_component.py +++ b/Tests/test_component.py @@ -3,8 +3,8 @@ # See LICENSE file in the project root directory for details. from unittest import TestCase -from biocrnpyler import Component, DNA -from biocrnpyler import Transcription_MM, Translation_MM, Degredation_mRNA_MM +from biocrnpyler import Component, DNA, ParameterDatabase, Mixture, Mechanism +from biocrnpyler import SimpleTranscription, SimpleTranslation class TestComponent(TestCase): @@ -14,7 +14,7 @@ def setUp(self) -> None: self.comp_name = 'test_component' self.default_concentration = 0 self.component = Component(name=self.comp_name, mechanisms={}, parameters={}, parameter_file=None, - mixture=None, attributes=[], initial_conc=self.default_concentration, parameter_warnings=True) + mixture=None, attributes=[], initial_conc=self.default_concentration) def test_initial_concentration(self): @@ -26,7 +26,7 @@ def test_initial_concentration(self): self.assertEqual(self.component.initial_concentration, new_value) not_valid_value = -1 - with self.assertRaisesRegexp(ValueError, f'Initial concentration must be non-negative, this was given: {not_valid_value}'): + with self.assertRaisesRegex(ValueError, f'Initial concentration must be non-negative, this was given: {not_valid_value}'): self.component.initial_concentration = not_valid_value def test_get_species(self): @@ -38,7 +38,7 @@ def test_set_attributes(self): attr_list = ['attr1', 'attr2'] - with self.assertRaisesRegexp(Warning,f'Component {self.component.name} has no internal species and therefore no attributes'): + with self.assertRaisesRegex(Warning,f'Component {self.component.name} has no internal species and therefore no attributes'): self.component.set_attributes(attr_list) # DNA is inherited from component and has valid internal species @@ -53,90 +53,92 @@ def test_update_parameters(self): parameters = {"kb": kb, "ku": ku, "ktx": ktx, "ktl": ktl, "kdeg": kdeg} # test that the custom parameters dictionary is empty - self.assertTrue(isinstance(self.component.custom_parameters, dict) - and len(self.component.custom_parameters) == 0) + self.assertTrue(isinstance(self.component.parameter_database, ParameterDatabase) + and len(self.component.parameter_database.parameters) == 0) - one_param = {"kb": kb} - self.component.custom_parameters = one_param + - self.component.update_parameters(mixture_parameters={}, parameters=parameters, overwrite_custom_parameters=False) - # test that the new parameter is the only parameter custom parameter in the component - self.assertTrue(len(self.component.custom_parameters) == len(one_param)) + self.component.update_parameters(parameters=parameters) - self.component.update_parameters(mixture_parameters={}, parameters=parameters) - self.assertEqual(self.component.custom_parameters, one_param) + # test that the component has all the parameters + self.assertTrue(len(self.component.parameter_database.parameters) == len(parameters)) - self.component.update_parameters(mixture_parameters=parameters, parameters={}) - # test that the parameter dictionary is still the same as before - self.assertEqual(self.component.parameters, parameters) + # test overwriting parameters + new_val = 111 + one_param = {"kb": new_val} + self.component.update_parameters(parameters=one_param, overwrite_parameters = True) + self.assertEqual(self.component.parameter_database[(None, None, "kb")].value, new_val) + # test that the parameter dictionary is still the same length as before + self.assertTrue(len(self.component.parameter_database.parameters) == len(parameters)) def test_update_mechanisms(self): - tx = Transcription_MM() - tl = Translation_MM() - deg = Degredation_mRNA_MM() + tx = SimpleTranscription() + tl = SimpleTranslation() test_mech = {tx.mechanism_type: tx, tl.mechanism_type: tl} - default_test_mech = {deg.mechanism_type: deg} - # test that component has no mechanism self.assertTrue(isinstance(self.component.mechanisms, dict) and len(self.component.mechanisms) == 0) - self.component.update_mechanisms(mixture_mechanisms=test_mech) - # test that the test_mech is registered as the only mechanism - self.assertEqual(self.component.mechanisms, test_mech) - self.component.default_mechanisms = default_test_mech - self.component.update_mechanisms(mixture_mechanisms=test_mech) - test_mech.update(default_test_mech) - self.assertEqual(self.component.mechanisms, test_mech) + #test mechanism setter + self.component.mechanisms = test_mech + self.assertEqual(self.component.mechanisms.keys(), test_mech.keys()) - # testing that the custom mechanism gets updated - self.assertTrue(isinstance(self.component.custom_mechanisms, dict) and len(self.component.custom_mechanisms) == 0) - self.component.update_mechanisms(mechanisms=test_mech) - self.assertEqual(self.component.custom_mechanisms, test_mech) + #test mechanisms are copied + self.assertEqual(type(self.component.mechanisms[tx.mechanism_type]), type(test_mech[tx.mechanism_type])) + self.assertFalse(self.component.mechanisms[tx.mechanism_type] == test_mech[tx.mechanism_type]) - # testing that custom mechanism is protected by the overwrite_custom_mechanisms=False flag - self.component.update_mechanisms(mechanisms=default_test_mech, overwrite_custom_mechanisms=False) - self.assertEqual(self.component.custom_mechanisms, test_mech) + #remove all mechanisms + self.component.mechanisms = {} + self.assertEqual(self.component.mechanisms, {}) - # multiple mechanisms can be supplied with a list - test_mech_list = list(test_mech.values()) - self.component.update_mechanisms(mechanisms=test_mech_list) - self.assertEqual(self.component.custom_mechanisms, test_mech) + #test add_mechanism + self.component.add_mechanism(tx, tx.mechanism_type) + self.component.add_mechanism(tl) + self.assertEqual(self.component.mechanisms.keys(), test_mech.keys()) - # testing an invalid mechanism format - with self.assertRaisesRegexp(ValueError, 'Mechanisms must be passed as a list of instantiated objects or a ' - 'dictionary {mechanism_type:mechanism instance}'): - self.component.update_mechanisms(mechanisms=(tx, tl)) + #test add_mechanisms with list + self.component.mechanisms = {} + test_mech_list = list(test_mech.values()) + self.component.add_mechanisms(test_mech_list) + self.assertEqual(self.component.mechanisms.keys(), test_mech.keys()) def test_get_parameter(self): # testing an invalid parameter - with self.assertRaisesRegexp(ValueError, 'No parameters can be found that match the'): + with self.assertRaisesRegex(ValueError, 'No parameters can be found that match the'): self.component.get_parameter(param_name='kb') # Create Param Dict - kb, ku, ktx, ktl, kdeg, cooperativity = 100, 10, 3, 2, 1, 1 + kb, ku, ktx, ktl, kdeg, cooperativity = 100, 10, 3, 2, 1, 4 p_id = 'p10' - parameters = {"kb": kb, "ku": ku, "ktx": ktx, "ktl": ktl, "kdeg": kdeg, "cooperativity": cooperativity, - # default params - ("transcription", "ktx"): ktx, - ("transcription", p_id, 'ku'): ku - } - - one_param = {"kb": kb} - self.component.update_parameters(mixture_parameters={}, parameters=one_param) - # testing that one_param was registered - self.assertEqual(self.component.get_parameter(param_name="kb"), one_param["kb"]) + parameters = {"kb": kb, "kdeg":kdeg, + ("transcription", None, "ktx"): ktx, + ("transcription", p_id, 'ku'): ku, + (None, p_id, "ktl"): ktl } # update the component parameters self.component.update_parameters(parameters=parameters) + + tx = SimpleTranscription() # testing the different parameter definitions - tx = Transcription_MM() - self.assertEqual(self.component.get_parameter(mechanism=tx, param_name='ktx'), ktx) + self.assertEqual(self.component.get_parameter(param_name='kb').value, kb) + self.assertEqual(self.component.get_parameter(mechanism=tx, param_name='ktx').value, ktx) + self.assertEqual(self.component.get_parameter(part_id=p_id, param_name='ktl').value, ktl) + self.assertEqual(self.component.get_parameter(mechanism=tx, part_id=p_id, param_name='ku').value, ku) - self.assertEqual(self.component.get_parameter(mechanism=tx, part_id=p_id, param_name='ku'), ku) + # testing parameter with return_numerical = True + self.assertEqual(self.component.get_parameter(param_name='kb', return_numerical = True), kb) + + one_param = {"kb": kb} + self.component.update_parameters(parameters=one_param) + # testing that one_param was registered + self.assertEqual(self.component.get_parameter(param_name="kb").value, one_param["kb"]) + + #testing a parameter which can't be found + with self.assertRaisesRegex(ValueError, "No parameters can be found"): + self.component.get_parameter("not a parameter") def test_update_species(self): # warning if update_species on a component object @@ -147,3 +149,33 @@ def test_update_reactions(self): # warning if update_reaction on a component object with self.assertWarnsRegex(Warning, f'Unsubclassed update_reactions called for {self.component}'): self.component.update_reactions() + + def test_get_mechanism(self): + M1_comp = Mechanism(name = "m1_comp", mechanism_type = "shared") + M1_mix = Mechanism(name = "m1_mix", mechanism_type = "shared") + M2_comp = Mechanism(name = "m2_comp", mechanism_type = "comp") + M2_mix = Mechanism(name = "m2_mix", mechanism_type = "mixture") + + #Create a Mixture and Component with the above mechanisms + C = Component(name = "comp", mechanisms = [M1_comp, M2_comp]) + M = Mixture(mechanisms = [M1_mix, M2_mix], components = [C]) + + #Get the copy of C in M + C_copy = M.get_component(component = C) + + self.assertTrue(C_copy.get_mechanism("shared").name == "m1_comp") + self.assertTrue(M.get_mechanism("shared").name == "m1_mix") + self.assertTrue(C_copy.get_mechanism("comp").name == "m2_comp") + self.assertTrue(C_copy.get_mechanism("mixture").name == "m2_mix") + + #Make sure the Mixture get_mechanism works as well, just in case. + self.assertTrue(M.get_mechanism("comp") is None) + + #test get Mechanism with no_key_error = False (Default) + with self.assertRaisesRegex(KeyError, "Unable to find mechanism of type"): + C_copy.get_mechanism("DNE") + + #test get_mechanism with no_key_error = True + self.assertTrue(C_copy.get_mechanism("DNE", optional_mechanism = True) is None) + + diff --git a/Tests/test_dna_assembly.py b/Tests/test_dna_assembly.py new file mode 100644 index 00000000..bd3b5547 --- /dev/null +++ b/Tests/test_dna_assembly.py @@ -0,0 +1,134 @@ +import pytest +from biocrnpyler import DNAassembly, Promoter, RBS, Mechanism, Species + + +def test_instantiation(): + #Instantiate from strings + ass = DNAassembly(name = "ass", rbs = "rbs", promoter = "prom") + assert type(ass.promoter) is Promoter and ass.promoter.name == "prom" + assert type(ass.rbs) is RBS and ass.rbs.name == "rbs" + assert type(ass.transcript) is Species and ass.transcript.name == ass.name + assert type(ass.protein) is Species and ass.protein.name == ass.name + assert type(ass.dna) is Species and ass.dna.name == ass.name + + #Instantiate with rbs = None + ass = DNAassembly(name = "ass", rbs = None, promoter = "prom") + assert ass.rbs is None + + #Instantiate with prom = None + ass = DNAassembly(name = "ass", rbs = "rbs", promoter = None) + assert ass.promoter is None + assert type(ass.rbs) is RBS and ass.rbs.name == "rbs" + assert type(ass.protein) is Species and ass.protein.name == ass.name + + #instantiate with transcript = Species + T = Species("T") + ass = DNAassembly(name = "ass", rbs = "rbs", promoter = "prom", transcript = T) + assert ass.transcript == T + + #instantiate with dna = Species + D = Species("D") + ass = DNAassembly(name = "ass", rbs = "rbs", promoter = "prom", dna = D) + assert ass.dna == D + + #instantiate with protein = Species + P = Species("P") + ass = DNAassembly(name = "ass", rbs = "rbs", promoter = "prom", protein = P) + assert ass.protein == P + + +def test_update_promoter(): + T = Species("T") + D = Species("D") + P = Species("P") + prom = Promoter("prom") + mech = Mechanism(name = "mech", mechanism_type = "assembly") + + ass = DNAassembly("ass", rbs = None, promoter = None, transcript = T, dna = D, protein = P, mechanisms = [mech]) + ass.update_promoter(prom) + + #test copying + assert ass.promoter != prom + assert type(ass.promoter) == type(prom) + assert ass.promoter.name == prom.name + + #test resetting transcript + assert ass.promoter.transcript == T + + #test mechanism inheritance + assert mech.mechanism_type in ass.promoter.mechanisms + +def test_update_rbs(): + T = Species("T") + D = Species("D") + P = Species("P") + rbs = RBS("rbs") + mech = Mechanism(name = "mech", mechanism_type = "assembly") + + ass = DNAassembly("ass", rbs = None, promoter = None, transcript = T, dna = D, protein = P, mechanisms = [mech]) + ass.update_rbs(rbs) + + #test copying + assert ass.rbs != rbs + assert type(ass.rbs) == type(rbs) + assert ass.rbs.name == rbs.name + + #test resetting transcript + assert ass.rbs.protein == P + + #test mechanism inheritance + assert mech.mechanism_type in ass.rbs.mechanisms + +def test_update_transcript(): + T = Species("T") + ass = DNAassembly(name = "ass", rbs = "rbs", promoter = "prom") + ass.update_transcript(T) + assert ass.transcript == T + assert ass.promoter.transcript == T + assert ass.rbs.transcript == T + +def test_update_dna(): + D = Species("D") + ass = DNAassembly(name = "ass", rbs = "rbs", promoter = "prom") + ass.update_dna(D) + assert ass.dna == D + +def test_update_protein(): + P = Species("P") + + ass = DNAassembly(name = "ass", rbs = "rbs", promoter = "prom") + ass.update_protein(P) + assert ass.protein == P + assert ass.promoter.protein == P + assert ass.rbs.protein == P + +def test_add_mechanism(): + mech = Mechanism(name = "mech", mechanism_type = "assembly") + ass = DNAassembly(name = "ass", rbs = "rbs", promoter = "prom") + ass.add_mechanism(mech) + #Mechanism should be added to promoter and rbs + assert mech.mechanism_type in ass.mechanisms + assert mech.mechanism_type in ass.promoter.mechanisms + assert mech.mechanism_type in ass.rbs.mechanisms + + #Mechaisms which are already in the Promoter or RBS should NOT be overwritten + mech_rbs = Mechanism(name = "rbs", mechanism_type = "mech") + mech_promoter = Mechanism(name = "promoter", mechanism_type = "mech") + mech_assembly = Mechanism(name = "assembly", mechanism_type = "mech") + + #Create promoter and assembly with their own mechanisms + prom = Promoter("prom", mechanisms = [mech_promoter]) + assert mech_promoter.mechanism_type in prom.mechanisms + rbs = RBS("rbs", mechanisms = [mech_rbs]) + assert mech_rbs.mechanism_type in rbs.mechanisms + ass = DNAassembly(name = "ass", rbs = rbs, promoter = prom) + assert ass.rbs.mechanisms["mech"].name == mech_rbs.name + assert ass.promoter.mechanisms["mech"].name == mech_promoter.name + + #Overwrite the assembly mechanism + #this should not propogate down to rbs or promoter! + ass.add_mechanism(mech_assembly) + assert mech_assembly.mechanism_type in ass.mechanisms + assert ass.rbs.mechanisms["mech"].name == mech_rbs.name + assert ass.promoter.mechanisms["mech"].name == mech_promoter.name + diff --git a/Tests/test_global_mechanism.py b/Tests/test_global_mechanism.py new file mode 100644 index 00000000..be071aae --- /dev/null +++ b/Tests/test_global_mechanism.py @@ -0,0 +1,108 @@ + +# Copyright (c) 2020, Build-A-Cell. All rights reserved. +# See LICENSE file in the project root directory for details. + +from unittest import TestCase +from biocrnpyler import GlobalMechanism,Species, Complex + +class TestGlobalMechanism(TestCase): + + def setUp(self) -> None: + self.mech_name = 'test_mechanism' + self.mechanism = GlobalMechanism(name=self.mech_name, mechanism_type='dummy') + + def test_update_species(self): + s = Species("s") + params = {} + # GlobalMechanism returns empty list of species by default + self.assertTrue(len(self.mechanism.update_species(s, params)) == 0) + + def test_update_reactions(self): + s = Species("s") + params = {} + # GlobalMechanism returns empty list of reactions by default + self.assertTrue(len(self.mechanism.update_reactions(s, params)) == 0) + + def test_default_filtering(self): + #No filter dictionary used in these tests + s1 = Species("s1", material_type = "m1", attributes = ["a1"]) + s2 = Species("s2", material_type = "m2", attributes = ["a2"]) + c1 = Complex([s1, s2], name = "c1") + c2 = Complex([c1, s2], name = "c2") + + #Always ON for all species + mech_default_on = GlobalMechanism(name = self.mech_name, mechanism_type = "dummy", default_on = True) + self.assertTrue(False not in [mech_default_on.apply_filter(s) for s in [s1, s2, c1, c2]]) + + #Always OFF for all species + mech_default_off = GlobalMechanism(name = self.mech_name, mechanism_type = "dummy", default_on = False) + self.assertTrue(True not in [mech_default_off.apply_filter(s) for s in [s1, s2, c1, c2]]) + + + def test_filter_dictionary(self): + #Test default filters via name, attributes, and materials with recursive_species_filtering = False + + s1 = Species("s1", material_type = "m1", attributes = ["a1"]) + s2 = Species("s2", material_type = "m2", attributes = ["a2"]) + c1 = Complex([s1, s2], name = "c1") + c2 = Complex([c1, s2], name = "c2") + + + fd = {"s1":False} #Filter based on name + mech_default_on_fds1 = GlobalMechanism(name = self.mech_name, mechanism_type = "dummy", + default_on = True, filter_dict = fd, recursive_species_filtering = False) + self.assertFalse(mech_default_on_fds1.apply_filter(s1)) + self.assertTrue(mech_default_on_fds1.apply_filter(s2)) + self.assertTrue(mech_default_on_fds1.apply_filter(c1)) + self.assertTrue(mech_default_on_fds1.apply_filter(c2)) + + fd = {"m1":False} #Filter based on material + mech_default_on_fds1 = GlobalMechanism(name = self.mech_name, mechanism_type = "dummy", + default_on = True, filter_dict = fd, recursive_species_filtering = False) + self.assertFalse(mech_default_on_fds1.apply_filter(s1)) + self.assertTrue(mech_default_on_fds1.apply_filter(s2)) + self.assertTrue(mech_default_on_fds1.apply_filter(c1)) + self.assertTrue(mech_default_on_fds1.apply_filter(c2)) + + fd = {"a1":False} #Filter based on attribute + mech_default_on_fds1 = GlobalMechanism(name = self.mech_name, mechanism_type = "dummy", + default_on = True, filter_dict = fd, recursive_species_filtering = False) + self.assertFalse(mech_default_on_fds1.apply_filter(s1)) + self.assertTrue(mech_default_on_fds1.apply_filter(s2)) + self.assertTrue(mech_default_on_fds1.apply_filter(c1)) #attributes are NOT inherited through ComplexSpecies + self.assertTrue(mech_default_on_fds1.apply_filter(c2)) + + + def test_recursive_filtering(self): + #Test default off via name, attributes, and materials with recursive_species_filtering = True + + s1 = Species("s1", material_type = "m1", attributes = ["a1"]) + s2 = Species("s2", material_type = "m2", attributes = ["a2"]) + c1 = Complex([s1, s2], name = "c1") + c2 = Complex([c1, s2], name = "c2") + + fd = {"s1":True} #Filter based on name + mech_default_on_fds1 = GlobalMechanism(name = self.mech_name, mechanism_type = "dummy", + default_on = False, filter_dict = fd, recursive_species_filtering = True) + self.assertTrue(mech_default_on_fds1.apply_filter(s1)) + self.assertFalse(mech_default_on_fds1.apply_filter(s2)) + self.assertTrue(mech_default_on_fds1.apply_filter(c1)) + self.assertTrue(mech_default_on_fds1.apply_filter(c2)) + + fd = {"m1":True} #Filter based on material + mech_default_on_fds1 = GlobalMechanism(name = self.mech_name, mechanism_type = "dummy", + default_on = False, filter_dict = fd, recursive_species_filtering = True) + self.assertTrue(mech_default_on_fds1.apply_filter(s1)) + self.assertFalse(mech_default_on_fds1.apply_filter(s2)) + self.assertTrue(mech_default_on_fds1.apply_filter(c1)) + self.assertTrue(mech_default_on_fds1.apply_filter(c2)) + + fd = {"a1":True} #Filter based on attribute + mech_default_on_fds1 = GlobalMechanism(name = self.mech_name, mechanism_type = "dummy", + default_on = False, filter_dict = fd, recursive_species_filtering = True) + self.assertTrue(mech_default_on_fds1.apply_filter(s1)) + self.assertFalse(mech_default_on_fds1.apply_filter(s2)) + self.assertTrue(mech_default_on_fds1.apply_filter(c1)) #attributes are not inherited through ComplexSpecies, but contained inside + self.assertTrue(mech_default_on_fds1.apply_filter(c2)) + + diff --git a/Tests/test_initial_condition.py b/Tests/test_initial_condition.py new file mode 100644 index 00000000..d8b78159 --- /dev/null +++ b/Tests/test_initial_condition.py @@ -0,0 +1,11 @@ +# Copyright (c) 2019, Build-A-Cell. All rights reserved. +# See LICENSE file in the project root directory for details. + +from unittest import TestCase +from biocrnpyler import Species, Mixture, Component, ParameterDatabase + + +class TestSpecies(TestCase): + #TODO - wait for revamp of Species because that will likely change this + pass + diff --git a/Tests/test_mixture.py b/Tests/test_mixture.py index 99905758..947a83e2 100644 --- a/Tests/test_mixture.py +++ b/Tests/test_mixture.py @@ -2,7 +2,7 @@ # See LICENSE file in the project root directory for details. from unittest import TestCase -from biocrnpyler import Mixture, Species, Component, DNA, Reaction, ChemicalReactionNetwork +from biocrnpyler import Mixture, Species, DNA, Reaction, ChemicalReactionNetwork, Component, SimpleTranscription, SimpleTranslation, GlobalMechanism class TestMixture(TestCase): @@ -16,7 +16,7 @@ def test_add_species(self): self.assertEqual([species], mixture.added_species) # adding invalid species - with self.assertRaisesRegexp(AssertionError,'only Species type is accepted!'): + with self.assertRaisesRegex(AssertionError,'only Species type is accepted!'): mixture.add_species(['ok', 'ok']) def test_add_components(self): @@ -25,28 +25,137 @@ def test_add_components(self): # test that new mixture has no components self.assertTrue(len(mixture.components) == 0) component = Component('test_comp') - mixture.add_components(component) + mixture.add_component(component) + + # test that the new components was added to the mixture + self.assertTrue(mixture.get_component(component = component) is not None) + #test that it was added by copying + self.assertTrue(component not in mixture._components) + #test that the same component cannot be added again + with self.assertRaisesRegex(ValueError,f'{component} of the same type and name already in Mixture!'): + mixture.add_component(component) + + + #use the constructor the other way + mixture = Mixture(components = [component]) # test that the new components was added to the mixture - self.assertTrue(component in mixture.components) + self.assertTrue(mixture.get_component(component = component) is not None) + #test that it was added by copying + self.assertTrue(component not in mixture._components) + species = Species('test_species') # species are invalid components - with self.assertRaisesRegexp(AssertionError,f'the object: {species} passed into mixture as component must be of the class Component'): + with self.assertRaisesRegex(ValueError,f'add_components expected a list of Components.'): mixture.add_components(species) - def test_update_species(self): + def test_get_component(self): + c1 = Component('c1') + c2 = Component('c2') + c3 = DNA('c1') + c4 = DNA("c2") + mixture = Mixture() + mixture.add_components([c1, c2, c3]) + + #Test with name + #nothing named c3 is in the mixture + self.assertTrue(mixture.get_component(name = "c3") is None) + #two things named c2 are in the mixture + self.assertTrue(type(mixture.get_component(name = "c1")) is list) + #one thing named c1 is in the mixture + self.assertTrue(type(mixture.get_component(name = "c2")) is Component) + + #test with component + self.assertTrue(type(mixture.get_component(component = c1)) is Component) + self.assertTrue(type(mixture.get_component(component = c2)) is Component) + self.assertTrue(type(mixture.get_component(component = c3)) is DNA) + self.assertTrue(mixture.get_component(component = c4) is None) + + #Test with index + self.assertTrue(type(mixture.get_component(index = 1)) is Component) + self.assertTrue(type(mixture.get_component(index = 2)) is DNA) + with self.assertRaisesRegex(IndexError,""): + mixture.get_component(index = 3) + + with self.assertRaisesRegex(ValueError,""): + mixture.get_component(index = 3, component = c1) + + with self.assertRaisesRegex(ValueError,""): + mixture.get_component(component = "c1") + + with self.assertRaisesRegex(ValueError,""): + mixture.get_component(name = c1) + + with self.assertRaisesRegex(ValueError,""): + mixture.get_component(index = c1) + + + def test_add_mechanisms(self): + + mixture = Mixture() + + tx = SimpleTranscription() + tl = SimpleTranslation() + + test_mech = {tx.mechanism_type: tx, tl.mechanism_type: tl} + + # test that mixture has no mechanism + self.assertTrue(isinstance(mixture.mechanisms, dict) and len(mixture.mechanisms) == 0) + + #test mechanism setter + mixture.mechanisms = test_mech + self.assertEqual(mixture.mechanisms.keys(), test_mech.keys()) + + #test mechanisms are copied + self.assertEqual(type(mixture.mechanisms[tx.mechanism_type]), type(test_mech[tx.mechanism_type])) + self.assertFalse(mixture.mechanisms[tx.mechanism_type] == test_mech[tx.mechanism_type]) + + #remove all mechanisms + mixture.mechanisms = {} + self.assertEqual(mixture.mechanisms, {}) + + #test add_mechanism + mixture.add_mechanism(tx, tx.mechanism_type) + mixture.add_mechanism(tl) + self.assertEqual(mixture.mechanisms.keys(), test_mech.keys()) + + #test add_mechanisms with list + mixture.mechanisms = {} + test_mech_list = list(test_mech.values()) + mixture.add_mechanisms(test_mech_list) + self.assertEqual(mixture.mechanisms.keys(), test_mech.keys()) + + def test_add_global_mechanism(self): + mixture = Mixture() + GM = GlobalMechanism(name = "gm", mechanism_type = "global") + + mixture.add_global_mechanism(GM) + #Global Mechanisms should be copied! + self.assertTrue(mixture.global_mechanisms["global"] != GM) + self.assertTrue(mixture.global_mechanisms["global"].name == GM.name) + + #test setter to clear + mixture.global_mechanisms = {} + self.assertTrue("global" not in mixture.global_mechanisms) + #test add via add_mechanisms with different key + mixture.add_mechanisms({"key2":GM}) + self.assertTrue("global" not in mixture.global_mechanisms) + self.assertTrue("key2" in mixture.global_mechanisms) + + def test_add_species_to_crn(self): species = Species(name='H2O') mixture = Mixture(species=[species]) + mixture.add_species_to_crn(species, None) - self.assertTrue(species in mixture.update_species()) + self.assertTrue(species in mixture.crn.species) dna = DNA(name='test_DNA') mixture.add_components(dna) - crn_list = mixture.update_species() + mixture.add_species_to_crn(dna.update_species(), dna) for s_dna in dna.update_species(): - self.assertTrue(s_dna in crn_list) + self.assertTrue(s_dna in mixture.crn.species) # Currently, there is no global mechanism that creates new species @@ -56,16 +165,18 @@ def test_update_species(self): # mixture = Mixture(global_mechanisms=global_mechanisms) # mixture.update_species() + """ + update mechanisms has been removed - keeping here just in case it comes back def test_update_reactions(self): mixture = Mixture() - with self.assertRaisesRegexp(AttributeError, 'Mixture.crn_species not defined.'): + with self.assertRaisesRegex(AttributeError, 'Mixture.crn_species not defined.'): mixture.update_reactions() component = Component(name='test_component') # creating a mock update function to decouple the update process from the rest of the code def mock_update_reactions(): - rxn = Reaction(inputs=[], outputs=[], k=0.1) + rxn = Reaction.from_massaction(inputs=[], outputs=[], k_forward=0.1) return [rxn] component.update_reactions = mock_update_reactions @@ -74,7 +185,7 @@ def mock_update_reactions(): mixture.update_species() crn_rxn = mixture.update_reactions() crn_rxn_mock = mock_update_reactions() - self.assertEqual(crn_rxn, crn_rxn_mock) + self.assertEqual(crn_rxn, crn_rxn_mock)""" # TODO add test for reactions added by global mechanisms @@ -84,20 +195,47 @@ def test_compile_crn(self): species_list = [a, b] + rxn = Reaction.from_massaction(inputs=[a], outputs=[b], k_forward=0.1) + + CRN = ChemicalReactionNetwork(species_list, [rxn]) + + # create a component + component = Component("comp") + # creating a mock update function to decouple the update process from the rest of the code def mock_update_reactions(): - rxn = Reaction(inputs=[a], outputs=[b], k=0.1) + rxn = Reaction.from_massaction(inputs=[a], outputs=[b], k_forward=0.1) return [rxn] - rxn = Reaction(inputs=[a], outputs=[b], k=0.1) + def mock_update_species(): + return [a, b] - CRN = ChemicalReactionNetwork(species_list, [rxn]) + component.update_species = mock_update_species + component.update_reactions = mock_update_reactions - mixture = Mixture(species=species_list) - mixture.update_reactions = mock_update_reactions + mixture = Mixture(components=[component]) crn_from_mixture = mixture.compile_crn() # test that the mixture has the same species as the manually build CRN object - self.assertEqual(CRN.species, crn_from_mixture.species) + self.assertEqual(set(CRN.species), set(crn_from_mixture.species)) # test that the mixture has the same reactions as the manually build CRN object self.assertEqual(CRN.reactions, crn_from_mixture.reactions) + + + def test_compoents_in_multiple_mixtures(self): + C = Component("comp") + M1 = Mixture(components = [C]) + + #M1 should have a copy of C, not C itself + self.assertTrue(type(M1.get_component(component = C)) == Component) + self.assertTrue(C not in M1._components) + + #C.mixture should not be set, only it's copy + self.assertTrue(C.mixture is None) + self.assertTrue(M1.get_component(component = C).mixture is M1) + + #Add C to another Mixture + M2 = Mixture(components = [C]) + self.assertTrue(type(M2.get_component(component = C)) == Component) + self.assertTrue(M2.get_component(component = C).mixture is M2) + self.assertTrue(M1.get_component(component = C) != M2.get_component(component = C)) diff --git a/Tests/test_mixtures_and_components_combinatorially.py b/Tests/test_mixtures_and_components_combinatorially.py new file mode 100644 index 00000000..c6dcfbf7 --- /dev/null +++ b/Tests/test_mixtures_and_components_combinatorially.py @@ -0,0 +1,184 @@ +from unittest import TestCase +from biocrnpyler import * +import sys + + +class CombinatorialComponentMixtureTest(TestCase): + + def setUp(self) -> None: + #Stores a tuple Class, argument keywords dictionary + #which will be instantiated in each test case below + self.component_classes = [ + (DNA, {"name":"dna"}), + (RNA, {"name":"rna"}), + (Protein, {"name":"protein"}), + (ChemicalComplex, {"species":[Species("S1"), Species("S2")]}), + (Enzyme, {"enzyme":Species("E"), "substrate":Species("S"), "product":Species("P")}), + (MultiEnzyme, {"enzyme":Species("E1"), "substrates":[Species("S1"), Species("S2")], "products":[Species("P1"), Species("P2")]}), + (DNAassembly, {'name':"dna_assembly_v1", "promoter":"P", "rbs":"R", "transcript":"T", "protein":"X"}), + (DNAassembly, {'name':"dna_assembly_v2", "promoter":"P", "rbs":"R", "transcript":None, "protein":None}), + (DNAassembly, {'name':"dna_assembly_v3", "promoter":"P", "rbs":None}), + (DNAassembly, {'name':"dna_assembly_v4", "promoter":None, "rbs":None}), + (DNAassembly, {'name':"dna_assembly_v5", "promoter":"P", "rbs":"rbs", "transcript":None, "protein":"X"}), + (DNAassembly, {'name':"dna_assembly_v6", "promoter":"P", "rbs":"rbs", "transcript":"T", "protein":None}) + ] + + #Each of these promoters will be passed into + self.promoter_classes = [ + (Promoter, {"name":"promoter"}), + (ActivatablePromoter, {"name":"activatable_promoter", "activator":Species("A")}), + (RepressiblePromoter, {"name":"repressible_promoter", "repressor":Species("R")}), + (RegulatedPromoter, {"name":"regulated_promoter", "regulators":[Species("R1"), Species("R2")]}), + (CombinatorialPromoter, {"name":"combinatorial_promoter", "regulators":[Species("R1"), Species("R2")]}) + ] + + self.rbs_classes = [ + (RBS, {"name":"rbs"}) + ] + + self.mixture_classes = [ + (ExpressionExtract, {"name":"expression_extract"}), + (SimpleTxTlExtract, {"name":"simple_tx_tl_extract"}), + (TxTlExtract, {"name":"tx_tl_extract"}), + (ExpressionDilutionMixture, {"name":"expression_dilution_mixture"}), + (SimpleTxTlDilutionMixture, {'name':"simple_tx_tl_dilution_mixture"}), + (TxTlDilutionMixture, {"name":"tx_tl_dilution_mixture"}) + ] + + #Use default parameters + self.parameters = {"kb":1.0, "ku":1.0, "ktx":1.0, "ktl":1.0, "kdeg":1.0, "kdil":1.0, "kexpress":1.0,"kcat":1.0, "K":10, + "cooperativity":2, "n":2, "k":1.0, "max_occ":10, "kleak":.01, "k1":1.0, "kbr":1.0, "k2":1.0, "kur":.1, "k_iso":.2, "ktx_solo":1.0, "k_iso_r":10, "ktl_solo":1.0} + + self.transcription_mechs = [ + (SimpleTranscription, {}), + (Transcription_MM, {"rnap":Species("RNAP")}), + (multi_tx, {"pol":Species("RNAP")}), + ] + + self.translation_mechs = [ + (SimpleTranslation, {}), + (Translation_MM, {"ribosome":Species("Ribosome")}), + (multi_tl, {"ribosome":Species("Ribosome")}), + ] + + #Instantiate every Component + def test_component_instantiation(self): + try: + for (comp, args) in self.component_classes: + C = comp(**args) + except Exception as e: + error_txt = f"Instantiating Component {comp} with args {args}. \n Unexpected Error: {str(e)}." + raise Exception(error_txt) + + #Instantiate every promoter + def test_promoter_instantiation(self): + try: + for (prom, args) in self.promoter_classes: + P = prom(**args) + except Exception as e: + error_txt = f"Instantiating Promoter {prom} with args {args}. \n Unexpected Error: {str(e)}." + raise Exception(error_txt) + + #Instantiate every RBS + def test_rbs_instantiation(self): + try: + for (rbs, args) in self.rbs_classes: + R = rbs(**args) + except Exception as e: + error_txt = f"Instantiating RBS {rbs} with args {args}. \n Unexpected Error: {str(e)}." + raise Exception(error_txt) + + #Instantiate every Mixture + def test_mixture_instantiation(self): + try: + for (mixture, args) in self.mixture_classes: + M = mixture(**args) + except Exception as e: + error_txt = f"Instantiating Mixture {mixture} with args {args}. \n Unexpected Error: {str(e)}." + raise Exception(error_txt) + + def test_mechanism_instantiation(self): + try: + for (mech, args) in self.transcription_mechs: + M = mech(**args) + for (mech, args) in self.translation_mechs: + M = mech(**args) + except Exception as e: + error_txt = f"Instatiating Mechanism {mech}. \n Unexpected Error: {str(e)}." + raise Exception(error_txt) + + #Instantiate Each Component in each Mixture + def test_components_in_mixtures(self): + + try: + for (comp, args) in self.component_classes: + C = comp(**args) + for (mixture, args) in self.mixture_classes: + args["parameters"] = dict(self.parameters) + M = mixture(**args, components = [C]) + + if M.get_component(component = C) is None: + raise AttributeError(f"{C} not found in M.components={M.components}") + + CRN = M.compile_crn() + document, _ = CRN.generate_sbml_model() + assert validate_sbml(document) == 0 + + except Exception as e: + error_txt = f"Instantiating Component {comp} in Mixture {mixture} with args {args}. \n Unexpected Error: {str(e)}." + raise Exception(error_txt) + + #Instantiate Each set of Promoter-RBS in a DNAassembly in each Mixture + def test_dna_assemblies_in_mixtures(self): + try: + for (prom, args) in self.promoter_classes: + P = prom(**args) + for (rbs, args) in self.rbs_classes: + R = rbs(**args) + for (mixture, args) in self.mixture_classes: + A = DNAassembly("assembly", promoter = P, rbs = R) + args["parameters"] = dict(self.parameters) + + #test adding the component in the construtor + M = mixture(**args, components = [A]) + if M.get_component(component = A) is None: + raise AttributeError(f"{A} not found in M.components={M.components}") + CRN = M.compile_crn() + document, _ = CRN.generate_sbml_model() + assert validate_sbml(document) == 0 + + #Test adding the component after the constructor + M2 = mixture(**args) + M2.add_component(A) + if M2.get_component(component = A) is None: + raise AttributeError(f"{A} not found in M.components={M2.components}") + + CRN2 = M2.compile_crn() + document, _ = CRN2.generate_sbml_model() + assert validate_sbml(document) == 0 + + except Exception as e: + error_txt = f"Instantiating Promoter {prom} & RBS {rbs} in a DNAassembly in Mixture {mixture} with args {args}. \n Unexpected Error: {str(e)}." + raise Exception(error_txt) + + def test_dna_assemblies_with_combinations_of_mechanisms(self): + try: + for (prom, args) in self.promoter_classes: + P = prom(**args) + for (rbs, args) in self.rbs_classes: + R = rbs(**args) + for (mech_tx, args_tx) in self.transcription_mechs: + for (mech_tl, args_tl) in self.translation_mechs: + Mtx = mech_tx(**args_tx) + Mtl = mech_tl(**args_tl) + mechs = {Mtx.mechanism_type:Mtx, Mtl.mechanism_type:Mtl, "binding": One_Step_Cooperative_Binding()} + A = DNAassembly("assembly", promoter = P, rbs = R) + M = Mixture(mechanisms = mechs, components = [A], parameters = self.parameters) + + CRN = M.compile_crn() + document, _ = CRN.generate_sbml_model() + assert validate_sbml(document) == 0 + except Exception as e: + error_txt = f"Instantiating Promoter {prom} & RBS {rbs} in a DNAassembly in Mixure with mech_tx = {mech_tx} and mech_tl = {mech_tl}. \n Unexpected Error: {str(e)}." + raise Exception(error_txt) + diff --git a/Tests/test_parameter.py b/Tests/test_parameter.py index 431a074a..c10c6c22 100644 --- a/Tests/test_parameter.py +++ b/Tests/test_parameter.py @@ -3,44 +3,87 @@ from unittest import TestCase from unittest.mock import patch, mock_open -from biocrnpyler import Parameter +from biocrnpyler import Parameter, ParameterEntry, ModelParameter, ParameterDatabase, ParameterKey, Mechanism import sys from warnings import warn class TestParameter(TestCase): - def test_parameter_initialization(self): - # test unknown parameter type - with self.assertRaisesRegexp(ValueError,"can't parse value of parameter"): - Parameter(name='test_param', param_type='Nothing', value=0) - # test invalid parameter type - with self.assertRaisesRegexp(ValueError,'parameter_type must be a string'): - Parameter(name='test_param', param_type=[], value=0) + def test_parameter(self): + # test parameter name + with self.assertRaisesRegex(ValueError, f"parameter_name must be a string"): + Parameter(parameter_name=None, parameter_value=1.0) + # test parameter value + with self.assertRaisesRegex(ValueError, f"parameter_value must be a float or int"): + Parameter(parameter_name="None", parameter_value=None) - def test__get_field_names(self): + # test invalid value string + with self.assertRaisesRegex(ValueError, f"No valid parameter value! Accepted format"): + Parameter(parameter_name="None", parameter_value='2ba') + + # test string parameter values + self.assertTrue(Parameter(parameter_name="None", parameter_value="1.0").value == 1.0) + + self.assertTrue(Parameter(parameter_name="None", parameter_value="1/2").value == 0.5) + + self.assertTrue(Parameter(parameter_name="None", parameter_value="1e2").value == 100) + + # testing invalid parameter name + with self.assertRaisesRegex(ValueError, f"parameter_name should be at least one character and cannot start with a number!"): + Parameter(parameter_name="2", parameter_value=2) + + def test_parameter_entry(self): + #Valid ParameterEntry Construction + ParameterEntry(parameter_name="None", parameter_value=1.0, parameter_key = {"part_id":"id"}, parameter_info = {"comment":"comment"}) + + #Invalid keys + param_keys = Parameter(parameter_name="None", parameter_value=1.0) + with self.assertRaisesRegex(ValueError, "parameter_key must be"): + ParameterEntry(parameter_name="None", parameter_value=1.0, parameter_key = param_keys) + + #Invalid info + param_info = "blah blah" + with self.assertRaisesRegex(ValueError, f"parameter_info must be None or a dictionary"): + ParameterEntry(parameter_name="None", parameter_value=1.0, parameter_info = param_info) + + def test_model_parameter(self): + #valid ModelParameter Construction + ModelParameter(parameter_name="None", parameter_value=1.0, search_key = ("that", "this", "k"), found_key = ("this", None, "k")) + + #Invalid keys + k = Parameter(parameter_name="None", parameter_value="1.0") + with self.assertRaisesRegex(ValueError,"parameter_key must be None"): + ModelParameter(parameter_name="None", parameter_value=1.0, search_key = k, found_key = ("this", None, "k")) + + with self.assertRaisesRegex(ValueError,"parameter_key must be None"): + ModelParameter(parameter_name="None", parameter_value=1.0, search_key = ("that", "this", "k"), found_key = k) + + + def test_get_field_names(self): + PD = ParameterDatabase test_accepted_field_names = {'mechanism': ['mechanism', 'mechanism_id']} valid_field_names = ['part_id'] # test None as field_names - with self.assertRaisesRegexp(ValueError, 'field_names must be a list of strings'): - Parameter._get_field_names(field_names=None, accepted_field_names=test_accepted_field_names) + with self.assertRaisesRegex(ValueError, 'field_names must be a list of strings'): + PD._get_field_names(field_names=None, accepted_field_names=test_accepted_field_names) # test invalid field_names type - with self.assertRaisesRegexp(ValueError, 'field_names must be a list of strings'): - Parameter._get_field_names(field_names={}, accepted_field_names=test_accepted_field_names) + with self.assertRaisesRegex(ValueError, 'field_names must be a list of strings'): + PD._get_field_names(field_names={}, accepted_field_names=test_accepted_field_names) # test empty field_names list - with self.assertRaisesRegexp(ValueError,'field_names cannot be empty list!'): - Parameter._get_field_names(field_names=[], accepted_field_names=test_accepted_field_names) + with self.assertRaisesRegex(ValueError,'field_names cannot be empty list!'): + PD._get_field_names(field_names=[], accepted_field_names=test_accepted_field_names) # test None as accepted_field_names - with self.assertRaisesRegexp(ValueError, 'accepted_field_names must be a dictionary'): - Parameter._get_field_names(field_names=valid_field_names, accepted_field_names=None) + with self.assertRaisesRegex(ValueError, 'accepted_field_names must be a dictionary'): + PD._get_field_names(field_names=valid_field_names, accepted_field_names=None) # test invalid accepted_field_names type - with self.assertRaisesRegexp(ValueError, 'accepted_field_names must be a dictionary'): - Parameter._get_field_names(field_names=valid_field_names, accepted_field_names=[]) + with self.assertRaisesRegex(ValueError, 'accepted_field_names must be a dictionary'): + PD._get_field_names(field_names=valid_field_names, accepted_field_names=[]) # test empty field_names list - with self.assertRaisesRegexp(ValueError, 'accepted_field_names cannot be empty dictionary'): - Parameter._get_field_names(field_names=valid_field_names, accepted_field_names={}) + with self.assertRaisesRegex(ValueError, 'accepted_field_names cannot be empty dictionary'): + PD._get_field_names(field_names=valid_field_names, accepted_field_names={}) accepted_field_names = {'mechanism': ['mechanism', 'mechanism_id'], 'param_name': ["parameter_name", "parameter", "param", "param_name"], @@ -48,48 +91,221 @@ def test__get_field_names(self): 'param_val': ["val", "value", "param_val", "parameter_value"] } - ret_dict = Parameter._get_field_names(field_names=[''], accepted_field_names=accepted_field_names) + ret_dict = PD._get_field_names(field_names=[''], accepted_field_names=accepted_field_names) self.assertEqual(accepted_field_names.keys(), ret_dict.keys()) with self.assertWarns(Warning): - Parameter._get_field_names(valid_field_names, accepted_field_names) + PD._get_field_names(valid_field_names, accepted_field_names) accepted_field_names = {'dummy': ['dumb', 'dumber'], } with self.assertWarns(Warning): - Parameter._get_field_names(valid_field_names, accepted_field_names) + PD._get_field_names(valid_field_names, accepted_field_names) - def test_load_parameter_file(self): + def test_load_parameters_from_file(self): - with self.assertRaises(AssertionError): - Parameter.load_parameter_file(filename=None) + # Bad parameter file keyword + with self.assertRaisesRegex(ValueError, f"parameter_file must be a string representing a file name and path."): + ParameterDatabase(parameter_file={}) # TODO track down why this test fails in python 3.6! if sys.version_info[1] >= 7: - # do NOT reformat this string below + # !!! DO NOT reformat this string below !!!! example_csv = """mechanism_id part_id param_name param_val comments\ntranscription_mm ptet_tetR kb 10. extra columns are okay!\ntranscription_mm ptet_tetR ku .1 These are the parameters for transcription""" + # !!! DO NOT reformat this string above !!!! with patch('builtins.open', mock_open(read_data=example_csv), create=True): - rtn_dict = Parameter.load_parameter_file(filename='test_file') + PD = ParameterDatabase(parameter_file='test_file.tsv') + + + right_dict = { + ('transcription_mm', 'ptet_tetR', 'kb'): 10.0, + ('transcription_mm', 'ptet_tetR', 'ku'): 0.1 + } + returned_dict = {(k.mechanism, k.part_id, k.name):PD.parameters[k].value for k in PD.parameters} + #raise ValueError(str(returned_dict)) + self.assertEqual(right_dict, returned_dict) + else: + warn('version below 3.6 was detected! This test was skipped') - right_dict = {('transcription_mm', 'ptet_tetR', 'kb'): 10.0, ('transcription_mm', 'ptet_tetR', 'ku'): 0.1} + # TODO track down why this test fails in python 3.6! + if sys.version_info[1] >= 7: + example_csv = """mechanism_id""" + + with patch('builtins.open', mock_open(read_data=example_csv), create=True): + with self.assertWarnsRegex(Warning, f"No param_name column was found, could not load parameter!"): + ParameterDatabase(parameter_file='test_file.tsv') - self.assertEqual(rtn_dict, right_dict) else: warn('version below 3.6 was detected! This test was skipped') - def test_create_parameter_dictionary(self): - # test that no parameter dictionary or parameter files are given empty parameter dict is returned - empty_dict = {} - parameters = Parameter.create_parameter_dictionary(parameters=None, parameter_file=None) - self.assertEqual(parameters, empty_dict) + def test_load_parameters_from_dictionary(self): + + # bad parameter_dictionary keyword + with self.assertRaisesRegex(ValueError, f"parameter_dictionary must be None or a dictionary!"): + PD = ParameterDatabase(parameter_dictionary='test_file') + + # proper parameter dictionary + parameter_dict = { + (None, None, "k"):1, + ("M", "pid", "k"):2.0, + (None, "pid", "k"):3.3, + ("M", None, "k"): 4, + } + PD = ParameterDatabase(parameter_dictionary=parameter_dict) + return_dict = {(k.mechanism, k.part_id, k.name):PD.parameters[k].value for k in PD.parameters} + self.assertEqual(return_dict, parameter_dict) + + #improper parameter dictionary + k = ("M", "k") + parameter_dict = {k:2.0} + with self.assertRaisesRegex(ValueError, f"parameter_key must be"): + PD = ParameterDatabase(parameter_dictionary = parameter_dict) + + #duplicate parameter dictionary + key = (None, None, "k") + parameter_dict = {"k":1, (None, None, "k"):1} + with self.assertRaisesRegex(ValueError, f"Duplicate parameter detected"): + PD = ParameterDatabase(parameter_dictionary = parameter_dict) + + def test_iterator(self): + parameter_dict = { + "k":1, + ("M", "pid", "k"):2.0, + (None, "pid", "k"):3.3, + ("M", None, "k"): 4, + } + + PD = ParameterDatabase(parameter_dictionary = parameter_dict) + + #All things in iterator are entries + count = 0 + for entry in PD: + count += 1 + self.assertTrue(isinstance(entry, ParameterEntry)) + + #The correct number of entries + self.assertEqual(count, len(parameter_dict)) + + def test_len(self): + parameter_dict = { + "k":1, + ("M", "pid", "k"):2.0, + (None, "pid", "k"):3.3, + ("M", None, "k"): 4, + } + + PD = ParameterDatabase(parameter_dictionary = parameter_dict) + self.assertTrue(len(PD) == len(parameter_dict)) + + def test_contains(self): + parameter_dict = { + "k":1, + ("M", "pid", "k"):2.0, + (None, "pid", "k"):3.3, + ("M", None, "k"): 4, + } + + PD = ParameterDatabase(parameter_dictionary = parameter_dict) + + self.assertTrue("k" in PD) + self.assertTrue(("M", "pid", "k") in PD) + self.assertTrue(PD["k"] in PD) + self.assertFalse("ktx" in PD) + self.assertFalse(("M", "k") in PD) + + def test_indexing(self): + parameter_dict = { + "k":1, + ("M", "pid", "k"):2.0, + (None, "pid", "k"):3.3, + ("M", None, "k"): 4, + } + + PD = ParameterDatabase(parameter_dictionary = parameter_dict) + + #Test correct accessing + self.assertTrue(PD["k"].value == 1) + self.assertTrue(PD[("M", "pid", "k")].value == 2.0) + self.assertTrue(PD[(None, "pid", "k")].value == 3.3) + self.assertTrue(PD[("M", None, "k")].value == 4) + + #test incorrect accessing + with self.assertRaisesRegex(ValueError, f"parameter_key must be"): + PD[("M", "k")] + + #test accessing something not in the PD + with self.assertRaisesRegex(KeyError, f"ParameterKey"): + PD["kb"] + + #test inserting values + PD["kb"] = 100 + self.assertTrue(PD["kb"].value == 100) + PD[(None, None, "ku")] = 200 + self.assertTrue(PD["ku"].value == 200) + PD[("M", "pid", "ktx")] = 300 + self.assertTrue(PD[("M", "pid", "ktx")].value == 300) + + #Test inserting ParameterEntry + PE = ParameterEntry("test", 1.0) + PD["test"] = PE + self.assertTrue(PE in PD) + + #Test Correct Overwriting + PE = ParameterEntry("test", 2.0) + PD["test"] = PE + self.assertTrue(PD["test"].value == PE.value) + + #Test incorrect Overwriting + PE = ParameterEntry("t", 1.0) + with self.assertRaisesRegex(ValueError, f"Parameter Key does not match"): + PD["test"] = PE + + + #Invalid parameter key + with self.assertRaisesRegex(ValueError, f"parameter_key must be"): + PD[("M", "k")] = 10 + + #Test overwriting + PD["k"] = .1 + self.assertTrue(PD["k"].value == .1) + PD[("M", "pid", "ktx")] = .333 + self.assertTrue(PD[("M", "pid", "ktx")].value == .333) + + def test_find_parameter(self): + + """Test the parameter defaulting heirarchy + Parameter defaulting heirarchy: + (mechanism_name, part_id, param_name) --> param_val. If that particular parameter key cannot be found, + the software will default to the following keys: + (mechanism_type, part_id, param_name) >> (part_id, param_name) >> + (mechanism_name, param_name) >> (mechanism_type, param_name) >> + (param_name) and give a warning. """ + + parameter_dict = { + (None, None, "k"):1.0, + ("M", None, "k"): 2.1, + ("m", None, "k"): 2.2, + (None, "pid", "k"):3, + ("M", "pid", "k"):4.1, + ("m", "pid", "k"):4.2, + } + + M1 = Mechanism(name = "m", mechanism_type = "M") + M2 = Mechanism(name = "m2", mechanism_type = "M") + M3 = Mechanism(name = "m3", mechanism_type = "M2") + + PD = ParameterDatabase(parameter_dictionary = parameter_dict) + + self.assertEqual(PD.find_parameter(mechanism = M3, part_id="id", param_name = "k").value, 1.0) + self.assertEqual(PD.find_parameter(mechanism = M2, part_id="id", param_name = "k").value, 2.1) + self.assertEqual(PD.find_parameter(mechanism = M1, part_id="id", param_name = "k").value, 2.2) + self.assertEqual(PD.find_parameter(mechanism = M3, part_id="pid", param_name = "k").value, 3.0) + self.assertEqual(PD.find_parameter(mechanism = M2, part_id="pid", param_name = "k").value, 4.1) + self.assertEqual(PD.find_parameter(mechanism = M1, part_id="pid", param_name = "k").value, 4.2) + + - # test that no parameter file is given then the supplied parameter dictionary is returned - param_dict = {'kb': 10.0} - parameters = Parameter.create_parameter_dictionary(parameters=param_dict, parameter_file=None) - self.assertEqual(parameters, param_dict) - with self.assertRaises(FileNotFoundError): - Parameter.create_parameter_dictionary(parameters={}, parameter_file='dummy_file') diff --git a/Tests/test_polymer.py b/Tests/test_polymer.py new file mode 100644 index 00000000..612be137 --- /dev/null +++ b/Tests/test_polymer.py @@ -0,0 +1,163 @@ +# Copyright (c) 2019, Build-A-Cell. All rights reserved. +# See LICENSE file in the project root directory for details. + +from unittest import TestCase +from biocrnpyler import OrderedPolymer, OrderedMonomer, OrderedPolymerSpecies, Species + +class TestOrderedMonomer(TestCase): + + def test_ordered_monomer_initialization(self): + + #Correct instantiation + x = OrderedMonomer() + x = OrderedMonomer(direction="forward") + self.assertEqual(x.direction,"forward") + self.assertEqual(x.position,None) + self.assertEqual(x.parent,None) + self.assertEqual(OrderedMonomer(direction="reverse"),x.set_dir("reverse")) + + #Position with no parent + with self.assertRaisesRegex(ValueError, f"OrderedMonomer"): + m = OrderedMonomer(position = 1) + + #Bad parent + with self.assertRaisesRegex(ValueError, f"parent must be an OrderedPolymer"): + m = OrderedMonomer(parent = 1) + + p = OrderedPolymer(parts = []) + #Parent with no position + with self.assertRaisesRegex(ValueError, f"OrderedMonomer"): + m = OrderedMonomer(parent = p) + + #Correct instantiation with parent and position + m = OrderedMonomer(parent = p, position = 0) + + def test_properties(self): + x = OrderedMonomer() + + #Test None initialization of properties + self.assertTrue(x.parent is None) + self.assertTrue(x.direction is None) + self.assertTrue(x.position is None) + + p = OrderedPolymer(parts = []) + x = OrderedMonomer(parent = p, position = 0, direction = "r") + self.assertTrue(x.parent == p) + self.assertTrue(x.position == 0) + self.assertTrue(x.direction == "r") + + +class TestOrderedPolymer(TestCase): + + def test_ordered_polymer_intialization(self): + + x = OrderedMonomer(direction="forward") + y = OrderedPolymer([x,[OrderedMonomer(),"reverse"],OrderedMonomer()]) + + self.assertFalse(y[0]==x)#Parts should be copied, not inserted! + + #Test faithful copying of a part + self.assertEqual(y[0].direction, x.direction) + self.assertEqual(y[0].parent, y) + self.assertEqual(y[0].position, 0) + + self.assertEqual(y[1].position,1) + self.assertEqual(y[1].direction,"reverse") + self.assertEqual(y[1].parent,y) + self.assertEqual(y[2].position,2) + self.assertEqual(y[2].direction,None) + self.assertEqual(y[2].parent,y) + + def test_ordered_polymer_manipulations(self): + z = OrderedMonomer(direction="forward") + x = OrderedMonomer(direction="reverse") + y = OrderedPolymer([x,[OrderedMonomer(),"reverse"],OrderedMonomer()]) + #replace + y.replace(1,z) + truthvalue = OrderedPolymer([OrderedMonomer(direction="reverse"),OrderedMonomer(direction="forward"),OrderedMonomer(direction=None)]) + self.assertEqual(y,truthvalue) + #insert + y = OrderedPolymer([x,OrderedMonomer()]) + ins = OrderedMonomer(direction="forward") + y.insert(1,ins) + self.assertEqual(y,truthvalue) + #append + y = OrderedPolymer([x,OrderedMonomer(direction="forward")]) + y.append(OrderedMonomer()) + self.assertEqual(y,truthvalue) + #reverse + y = OrderedPolymer([OrderedMonomer(),OrderedMonomer(direction="reverse"),\ + OrderedMonomer(direction="forward")]) + y.reverse() + self.assertEqual(y,truthvalue) + #delpart + y = OrderedPolymer([OrderedMonomer(direction="reverse"),\ + OrderedMonomer(direction="forward"),\ + OrderedMonomer(direction="reverse"),\ + OrderedMonomer()]) + z = y[2] + self.assertEqual(z.parent,y) + y.delpart(2) + self.assertEqual(z.parent,None) + self.assertEqual(y,truthvalue) +class TestOrderedPolymerSpecies(TestCase): + def test_ordered_polymer_species_initialization(self): + a = Species("A") + x = OrderedPolymerSpecies([Species("A"),[Species("B"),"forward"],\ + Species("C").set_dir("reverse")],attributes=["ooga"]) + #repr + revtest = OrderedPolymerSpecies([Species("A",direction="forward"),Species("A")]) + r1 = str(revtest) + revtest.reverse() + r2 = str(revtest) + self.assertEqual(type(r1),str) + self.assertNotEqual(r1,r2) + #pretty_print + self.assertEqual(type(x.pretty_print()),str) + #make sure we're copying + self.assertEqual(a.parent,None) + #make sure we're setting the properties of the components + self.assertEqual(x[0].parent,x) + self.assertEqual(x[1].parent,x) + self.assertEqual(x[2].parent,x) + self.assertEqual(x[1].direction,"forward") + self.assertEqual(x[2].direction,"reverse") + + self.assertEqual(x[0].position,0) + self.assertEqual(x[1].position,1) + self.assertEqual(x[2].position,2) + + #circularity + x.circular = True + self.assertEqual(x.circular, True) + self.assertIn("circular",x.attributes) + x.circular = False + self.assertEqual(x.circular, False) + self.assertNotIn("circular",x.attributes) + + def test_ordered_polymer_species_manipulations(self): + a = Species("A") + b = Species("B").set_dir("forward") + c = Species("C").set_dir("reverse") + truth = OrderedPolymerSpecies([Species("A"),[Species("B"),"forward"],\ + Species("C").set_dir("reverse")],attributes=["ooga"]) + reversd = OrderedPolymerSpecies([Species("C").set_dir("forward"),[Species("B"),"reverse"],\ + Species("A")],attributes=["ooga"]) + unreplaced = OrderedPolymerSpecies([Species("z"),[Species("B"),"forward"],\ + Species("C").set_dir("reverse")],attributes=["ooga"]) + uninserted = OrderedPolymerSpecies([Species("A"),\ + Species("C").set_dir("reverse")],attributes=["ooga"]) + unappended = OrderedPolymerSpecies([Species("A"),[Species("B"),"forward"],\ + ],attributes=["ooga"]) + #replace + unreplaced.replace(0,a) + self.assertEqual(unreplaced,truth) + #insert + uninserted.insert(1,b) + self.assertEqual(uninserted,truth) + #append + unappended.append(c) + self.assertEqual(unappended,truth) + #reverse + reversd.reverse() + self.assertEqual(reversd,truth) \ No newline at end of file diff --git a/Tests/test_propensities.py b/Tests/test_propensities.py new file mode 100644 index 00000000..c46f539c --- /dev/null +++ b/Tests/test_propensities.py @@ -0,0 +1,176 @@ +# Copyright (c) 2020, Build-A-Cell. All rights reserved. +# See LICENSE file in the project root directory for details. + +from biocrnpyler import MassAction, ProportionalHillNegative, ProportionalHillPositive, HillPositive, HillNegative +from biocrnpyler import GeneralPropensity +from biocrnpyler import ParameterEntry +from biocrnpyler import Species +import pytest +from biocrnpyler import sbmlutil + + +def test_massaction_forward_rate(): + + with pytest.raises(ValueError, match=r"Propensity parameters must be Parameters or floats with positive values.*"): + MassAction(k_forward=0) + + with pytest.raises(ValueError, match=r"Propensity parameters must be Parameters or floats with positive values.*"): + MassAction(k_forward=-1) + + +def test_massaction_reserve_rate(): + with pytest.raises(TypeError, match=r"missing 1 required positional argument: 'k_forward'"): + MassAction(k_reverse=0.1) + + with pytest.raises(ValueError, match=r"Propensity parameters must be Parameters or floats with positive values.*"): + MassAction(k_forward=1, k_reverse=0) + + with pytest.raises(ValueError, match=r"Propensity parameters must be Parameters or floats with positive values.*"): + MassAction(k_forward=1, k_reverse=-1) + + +def test_massaction_is_reverable(): + mak = MassAction(k_forward=1, k_reverse=0.1) + assert mak.is_reversible + + +def test_massaction_from_parameters(): + mak = MassAction(k_forward=ParameterEntry("k", .1)) + assert mak.k_forward == .1 + + mak = MassAction(k_forward=ParameterEntry("k", .1), k_reverse=ParameterEntry("k", .01)) + assert mak.k_reverse == .01 + + +def test_hill_negative_init(): + s1 = Species('s1') + hillneg = HillNegative(k=1, s1=s1, K=5, n=2) + assert s1 == hillneg.s1 + + assert hillneg.is_reversible is False + + with pytest.raises(TypeError, match='Propensity expected a Species'): + HillNegative(k=1, s1='s1', K=5, n=2) + + with pytest.raises(TypeError): + d = Species('d') + HillNegative(k=1, s1=s1, K=5, n=2, d=d) + + +def test_hill_negative_rate_formula(): + in_s1 = Species('s1') + in_k = 1 + in_K = 5 + in_n = 2 + philpos = HillNegative(k=in_k, s1=in_s1, K=in_K, n=in_n) + + assert philpos._get_rate_formula(philpos.propensity_dict) == f"{in_k}/({in_s1}^{in_n}+{in_K})" + + +def test_hill_positive_init(): + s1 = Species('s1') + philpos = HillPositive(k=1, s1=s1, K=5, n=2) + assert s1 == philpos.s1 + + assert philpos.is_reversible is False + + with pytest.raises(TypeError, match='Propensity expected a Species'): + HillPositive(k=1, s1='s1', K=5, n=2) + + with pytest.raises(TypeError): + d = Species('d') + HillPositive(k=1, s1=s1, K=5, n=2, d=d) + + +def test_hill_positive_rate_formula(): + in_s1 = Species('s1') + in_k = 1 + in_K = 5 + in_n = 2 + philpos = HillPositive(k=in_k, s1=in_s1, K=in_K, n=in_n) + + assert philpos._get_rate_formula(philpos.propensity_dict) == f"{in_k}*{in_s1}^{in_n}/({in_s1}^{in_n}+{in_K})" + + +def test_proportional_hill_positive_init(): + d = Species('d') + s1 = Species('s1') + philpos = ProportionalHillPositive(k=1, s1=s1, K=5, n=2, d=d) + assert d == philpos.d + assert s1 == philpos.s1 + + assert philpos.is_reversible is False + + with pytest.raises(TypeError, match='Propensity expected a Species'): + ProportionalHillPositive(k=1, s1=s1, K=5, n=2, d='') + + with pytest.raises(TypeError, match='Propensity expected a Species'): + ProportionalHillPositive(k=1, s1='s1', K=5, n=2, d=d) + + +def test_proportional_hill_positive_rate_formula(): + in_d = Species('d') + in_s1 = Species('s1') + in_k = 1 + in_K = 5 + in_n = 2 + philpos = ProportionalHillPositive(k=in_k, s1=in_s1, K=in_K, n=in_n, d=in_d) + + assert philpos._get_rate_formula(philpos.propensity_dict) == f"{in_k}*{in_d}*{in_s1}^{in_n}/({in_s1}^{in_n}+{in_K})" + + +def test_proportional_hill_negative_init(): + d = Species('d') + s1 = Species('s1') + philneg = ProportionalHillNegative(k=1, s1=s1, K=5, n=2, d=d) + assert d == philneg.d + assert s1 == philneg.s1 + + assert philneg.is_reversible is False + + with pytest.raises(TypeError, match='Propensity expected a Species'): + ProportionalHillNegative(k=1, s1=s1, K=5, n=2, d='') + + with pytest.raises(TypeError, match='Propensity expected a Species'): + ProportionalHillNegative(k=1, s1='s1', K=5, n=2, d=d) + + +def test_proportional_hill_negative_rate_formula(): + in_d = Species('d') + in_s1 = Species('s1') + in_k = 1 + in_K = 5 + in_n = 2 + philneg = ProportionalHillNegative(k=in_k, s1=in_s1, K=in_K, n=in_n, d=in_d) + + assert philneg._get_rate_formula(philneg.propensity_dict) == f"{in_k}*{in_d}/({in_s1}^{in_n}+{in_K})" + + +def test_general_propensity(): + S1, S2, S3 = Species("S1"), Species("S2"), Species("S3") + # create some parameters + k1 = ParameterEntry("k1", 1.11) + k2 = ParameterEntry("k2", 2.22) + + gn1 = GeneralPropensity('k1*2 - k2/S1^2', propensity_species=[S1], propensity_parameters=[k1, k2]) + assert str(S1) in gn1.propensity_dict['species'] + assert k1.parameter_name in gn1.propensity_dict['parameters'] + assert k2.parameter_name in gn1.propensity_dict['parameters'] + + gn2 = GeneralPropensity('S1^2 + S2^2 + S3^2', propensity_species=[S1, S2, S3], propensity_parameters=[]) + assert str(S1) in gn1.propensity_dict['species'] + assert k1.parameter_name not in gn2.propensity_dict['parameters'] + + with pytest.raises(TypeError, match='propensity_species must be a list of Species!'): + GeneralPropensity('S1^2 + S2^2 + S3^2', propensity_species=[k1], propensity_parameters=[]) + + with pytest.raises(TypeError, match='propensity_parameter must be a list of ParameterEntry!'): + GeneralPropensity('S1^2 + S2^2 + S3^2', propensity_species=[], propensity_parameters=[S2]) + + test_formula = 'S3^2' + with pytest.raises(ValueError, match=f'must be part of the formula'): + GeneralPropensity(test_formula, propensity_species=[S1], propensity_parameters=[]) + + test_formula = 'k2*S3^2' + with pytest.raises(ValueError, match=f'must be part of the formula'): + GeneralPropensity(test_formula, propensity_species=[S3], propensity_parameters=[k1]) diff --git a/Tests/test_reaction.py b/Tests/test_reaction.py index f5033d63..8dd8b420 100644 --- a/Tests/test_reaction.py +++ b/Tests/test_reaction.py @@ -3,116 +3,125 @@ # See LICENSE file in the project root directory for details. from unittest import TestCase -from biocrnpyler import Reaction, Species +from biocrnpyler import Reaction, Species, MassAction, WeightedSpecies +import pytest class TestReaction(TestCase): def test_reaction_initialization(self): # warns if both input and output species are empty + mak = MassAction(k_forward=0.1) with self.assertWarns(Warning): - Reaction(inputs=[], outputs=[], k=0.1, propensity_type="massaction", propensity_params=None) + Reaction(inputs=[], outputs=[], propensity_type=mak) - # non-massaction propensities require propensity_params dict + # test for invalid propensity type with self.assertRaises(ValueError): - Reaction(inputs=[], outputs=[], k=0.1, propensity_type="not_massaction") - - # non-massaction propensities cannot be reversible - with self.assertRaises(ValueError): - Reaction(inputs=[], outputs=[], k=0.1, propensity_type="not_massaction", propensity_params={}, k_rev=1) - - # test under specified propensity parameters - propensity_types = ["hillpositive", "hillnegative", "proportionalhillpositive", "proportionalhillnegative"] - for propensity_type in propensity_types: - with self.assertRaises(ValueError): - Reaction(inputs=[], outputs=[], k=0.1, propensity_type=propensity_type, propensity_params={'s1': 0}) - - # test when rate is missing from the propensity parameter dictionary for a general propensity - with self.assertRaises(ValueError): - Reaction(inputs=[], outputs=[], k=0.1, propensity_type='general', propensity_params={}) - - # test unknown propensity type - with self.assertRaises(ValueError): - Reaction(inputs=[], outputs=[], k=0.1, propensity_type="dummy", propensity_params={}) + Reaction(inputs=[], outputs=[], propensity_type=Species) # input must be a valid species object - with self.assertRaises(ValueError): - Reaction(inputs=['a'], outputs=[], k=0.1) + with self.assertRaises(TypeError): + Reaction(inputs=['a'], outputs=[], propensity_type=mak) # output must be a valid species object - with self.assertRaises(ValueError): - Reaction(inputs=[], outputs=['b'], k=0.1) - - # reaction rate coefficient must be larger than zero - with self.assertRaises(ValueError): - Reaction(inputs=[], outputs=[], k=0) - # reaction rate coefficient must be larger than zero - with self.assertRaises(ValueError): - Reaction(inputs=[], outputs=[], k=-1) + with self.assertRaises(TypeError): + Reaction(inputs=[], outputs=['b'], propensity_type=mak) - rxn = Reaction(inputs=[], outputs=[], k=0.1, k_rev=1) + rxn = Reaction.from_massaction(inputs=[], outputs=[], k_forward=0.1, k_reverse=1) # test whether the reaction is registered as reversible - self.assertTrue(rxn.reversible) + self.assertTrue(rxn.is_reversible) # test whether the reaction is registered as massaction - self.assertTrue(rxn.propensity_type == 'massaction') - - # test overspecified mass action - sp1 = Species(name='test_species_a') - sp2 = Species(name='test_species_b') - with self.assertWarns(Warning): - Reaction(inputs=[sp1], outputs=[sp2], propensity_type="massaction", propensity_params={}, k=0.1) + self.assertTrue(isinstance(rxn.propensity_type, MassAction)) - # test whether the number of input and output coefficients match - with self.assertRaises(ValueError): - Reaction(inputs=[], outputs=[], k=0.1, input_coefs=[1,2]) - - # test whether the number of input and output coefficients match - with self.assertRaises(ValueError): - Reaction(inputs=[], outputs=[], k=0.1, output_coefs=[1, 2]) - - # test for the equality operator - rxn1 = Reaction(inputs = [sp1, sp2], outputs = [sp2, sp2], k = 1) - rxn2 = Reaction(inputs = [sp2, sp1], outputs = [sp2, sp2], k = 1) - rxn3 = Reaction(inputs = [sp2, sp1], outputs = [sp2, sp2], k = 10) - rxn4 = Reaction(inputs = [sp2, sp1], outputs = [sp2], k = 1) - self.assertTrue(rxn1 == rxn2) - self.assertFalse(rxn1 == rxn3) - self.assertFalse(rxn1 == rxn4) - - #Test for reaction list flattening - rxn1 = Reaction(inputs = [sp1, [sp1, sp2]], outputs = [[sp2, sp2], sp1], k = 1) - rxn2 = Reaction(inputs = [sp1, sp1, sp2], outputs = [sp1, sp2, sp2], k = 1) - self.assertTrue(rxn1 == rxn2) - - - def test_complex_set_equality(self): + # test WeightedSpecies inputs sp1 = Species(name='test_species_a') sp2 = Species(name='test_species_b') - - # test whether two reactions with the same species are equal - rxn1 = Reaction(inputs=[sp1], outputs=[], k=0.1, input_coefs=[1]) - - rtn = Reaction.complex_set_equality(c1=rxn1.inputs, c1_coefs=rxn1.input_coefs, - c2=rxn1.inputs, c2_coefs=rxn1.input_coefs) - self.assertTrue(rtn) - - # test that two reactions have the two species with equal coefficients are equal - rxn2 = Reaction(inputs=[sp1], outputs=[sp2], k=0.1, input_coefs=[1], output_coefs=[1]) - rtn = Reaction.complex_set_equality(c1=rxn1.inputs, c1_coefs=rxn1.input_coefs, - c2=rxn2.inputs, c2_coefs=rxn2.input_coefs) - self.assertTrue(rtn) - - # test that two reactions have the two species with different coefficients are not equal - rxn1 = Reaction(inputs=[sp1], outputs=[], k=0.1, input_coefs=[1]) - rxn2 = Reaction(inputs=[sp2], outputs=[], k=0.1, input_coefs=[2]) - - rtn2 = Reaction.complex_set_equality(c1=rxn1.inputs, c1_coefs=rxn1.input_coefs, - c2=rxn2.inputs, c2_coefs=rxn2.input_coefs) - self.assertFalse(rtn2) - - # test that two reactions with different species are not equal - rxn1 = Reaction(inputs=[sp1,sp2], outputs=[], k=0.1, input_coefs=[1,2]) - rxn2 = Reaction(inputs=[sp2], outputs=[], k=0.1, input_coefs=[2]) - - rtn3 = Reaction.complex_set_equality(c1=rxn1.inputs, c1_coefs=rxn1.input_coefs, - c2=rxn2.inputs, c2_coefs=rxn2.input_coefs) - self.assertFalse(rtn3) + chem_com_sp1 = WeightedSpecies(species=sp1, stoichiometry=2) + chem_com_sp2 = WeightedSpecies(species=sp2, stoichiometry=1) + Reaction(inputs=[chem_com_sp1], outputs=[chem_com_sp2], propensity_type=MassAction(k_forward=1)) + + # test different input and output lists + Reaction(inputs=[chem_com_sp1], outputs=[sp2], propensity_type=MassAction(k_forward=1)) + + # mixing WeightedSpecies and Species is not allowed + with self.assertRaises(TypeError): + Reaction(inputs=[chem_com_sp1, sp2], outputs=[sp1], propensity_type=MassAction(k_forward=1)) + + +def test_species_merging(): + sp1 = Species(name='test_species_a') + chem_complexes = [WeightedSpecies(species=sp1, stoichiometry=2), + WeightedSpecies(species=sp1, stoichiometry=1)] + rxn = Reaction(inputs=chem_complexes, outputs=[], propensity_type=MassAction(k_forward=1)) + # same species with different stoichiometry gets merged into one species + assert len(rxn.inputs) == 1 + + sp1 = Species(name='test_species_a') + chem_complexes = [WeightedSpecies(species=sp1, stoichiometry=2), + WeightedSpecies(species=sp1, stoichiometry=1)] + rxn = Reaction(inputs=[], outputs=chem_complexes, propensity_type=MassAction(k_forward=1)) + + # same species with different stoichiometry gets merged into one species + assert len(rxn.outputs) == 1 + + +def test_reaction_equality(): + """test for the_equality operator""" + sp1 = Species(name='test_species_a') + sp2 = Species(name='test_species_b') + rxn1 = Reaction(inputs=[sp1, sp2], outputs=[sp2, sp2], propensity_type=MassAction(k_forward=1)) + rxn2 = Reaction(inputs=[sp2, sp1], outputs=[sp2, sp2], propensity_type=MassAction(k_forward=1)) + rxn3 = Reaction(inputs=[sp2, sp1], outputs=[sp2, sp2], propensity_type=MassAction(k_forward=10)) + rxn4 = Reaction(inputs=[sp2, sp1], outputs=[sp2], propensity_type=MassAction(k_forward=1)) + assert rxn1 == rxn2 + assert rxn1 != rxn3 + assert rxn1 != rxn4 + + +def test_reaction_list_flattening(): + sp1 = Species(name='test_species_a') + sp2 = Species(name='test_species_b') + k_f = 1 + mak = MassAction(k_forward=k_f) + rxn1 = Reaction(inputs=[sp1, [sp1, sp2]], outputs=[[sp2, sp2], sp1], propensity_type=mak) + rxn2 = Reaction(inputs=[sp1, sp1, sp2], outputs=[sp1, sp2, sp2], propensity_type=mak) + assert rxn1 == rxn2 + + +def test_old_reaction_interface_massaction(): + A = Species(name="A") + + with pytest.deprecated_call(): + Reaction([], [A, A], k=100) + + with pytest.deprecated_call(): + Reaction([A, A], [], k=1, k_rev=0.1) + + +def test_old_reaction_interface_non_massaction(): + kb = 100 + ku = 10 + kex = 1. + + G = Species(name="G", material_type="dna") #DNA + A = Species(name="A", material_type="protein") #Activator + X = Species(name="X", material_type="protein") + + # hill positive + with pytest.deprecated_call(): + Reaction([G], [G, X], propensity_type="hillpositive", + propensity_params={"k": kex, "n": 2.0, "K": float(kb/ku), "s1": A}) + + # proportional hill positive + with pytest.deprecated_call(): + Reaction([G], [G, X], propensity_type="proportionalhillpositive", + propensity_params={"k": kex, "n": 2.0, "K": float(kb/ku), "s1": A, "d": G}) + + # hill Negative + with pytest.deprecated_call(): + Reaction([G], [G, X], propensity_type="hillnegative", + propensity_params={"k": kex, "n": 2.0, "K": float(kb/ku), "s1": A}) + + # proportional hill negative + with pytest.deprecated_call(): + Reaction([G], [G, X], propensity_type="proportionalhillnegative", + propensity_params={"k": kex, "n": 2.0, "K": float(kb/ku), "s1": A, "d": G}) diff --git a/Tests/test_sbml.py b/Tests/test_sbml.py new file mode 100644 index 00000000..30fe8deb --- /dev/null +++ b/Tests/test_sbml.py @@ -0,0 +1,298 @@ +import pytest +from biocrnpyler.sbmlutil import * +from biocrnpyler.species import Species, Complex +from biocrnpyler.propensities import MassAction, HillPositive, HillNegative, ProportionalHillPositive, ProportionalHillNegative, GeneralPropensity +from biocrnpyler.parameter import ParameterEntry, ParameterKey +from biocrnpyler.chemical_reaction_network import Reaction, ChemicalReactionNetwork + + +def test_create_sbml_model(): + #tests creating an SBML model + + document, model = create_sbml_model() + + +def test_add_all_species(): + #Tests add_species via add_all_species + + document, model = create_sbml_model() + + #Some Species + S1, S2, S3, S4 = Species("S1"), Species("S2"), Species("S3"), Species("S4") + + #These two Complexes push the naming convention to its limits + C1 = Complex([Complex([S1, S2, S3]), S4]) + C2 = Complex([Complex([S1, S2]), S3, S4]) + + species = [S1, S2, S3, S4, C1, C2] + add_all_species(model, species) + + assert len(model.getListOfSpecies()) == len(species) + assert validate_sbml(document) == 0 + + +def test_add_reaction(): + """ + Test adding reaction to SBML for combinatorially created list of models + """ + #create species + S1, S2, S3 = Species("S1"), Species("S2"), Species("S3") + species = [S1, S2, S3] + #create some parameters + key1 = ParameterKey(name = "k", mechanism = "m", part_id = "pid") + k1 = ParameterEntry("k1", 1.11, key1) + k2 = ParameterEntry("k2", 2.22) + stochiometries = [([], [S1]), ([S1], []), ([S1], [S2]), (2*[S1], [S2, S3])] + propensities = [MassAction(k_forward = 1.), MassAction(k_forward = 1, k_reverse = .1), MassAction(k_forward = k1), MassAction(k_forward = k1, k_reverse = k2), + HillPositive(k = 1, n = 2., K = 3., s1 = S1), HillPositive(k = k1, n = 2., K = k2, s1 = S1), + HillNegative(k = 1, n = 2., K = 3., s1 = S1), HillNegative(k = k1, n = k2, K = 3., s1 = S1), + ProportionalHillPositive(k = 1, n = 2, K = 3., s1 = S1, d = S2), ProportionalHillPositive(k = k1, n = 2, K = k2, s1 = S1, d = S2), + ProportionalHillNegative(k = 1, n = 2, K = 3., s1 = S1, d = S2), ProportionalHillNegative(k = k1, n = 2, K = k2, s1 = S1, d = S2), + GeneralPropensity('k1*2 - k2/S1^2', propensity_species=[S1], propensity_parameters=[k1, k2]), GeneralPropensity('S1^2 + S2^2 + S3^2', propensity_species=[S1, S2, S3], propensity_parameters=[]) + ] + + for prop in propensities: #Cycle through different propensity types + for inputs, outputs in stochiometries: #cycle through different stochiometries + for stochastic in [True, False]: #Toggle Stochastic + rxn_num = 0 + model_id = f"{prop.name}_model_with_stochastic_{stochastic}" + document, model = create_sbml_model(model_id = model_id) + add_all_species(model, species) + rxn = Reaction(inputs, outputs, propensity_type = prop) #create a reaction + try: + sbml_reaction = add_reaction(model, rxn, f"r{rxn_num}", stochastic = stochastic) #add reaction to SBML Model + rxn_num += 1 #increment reaction id + crn_reactants = [str(s) for s in inputs] + crn_products = [str(s) for s in outputs] + sbml_products = [p.getSpecies() for p in sbml_reaction.getListOfProducts()] + sbml_reactants = [p.getSpecies() for p in sbml_reaction.getListOfReactants()] + + #test that the reaction has the right inputs and outputs + assert set(crn_reactants) == set(sbml_reactants) + assert set(crn_products) == set(sbml_products) + + if len(crn_reactants) > 0: + assert all(crn_reactants.count(s.getSpecies()) == int(s.getStoichiometry()) for s in sbml_reaction.getListOfReactants()) + + if len(crn_products) > 0: + assert all(crn_products.count(s.getSpecies()) == int(s.getStoichiometry()) for s in sbml_reaction.getListOfProducts()) + assert not sbml_reaction.getReversible() + #TODO is there a smart way to test that the rate formula is correct? + assert validate_sbml(document) == 0 # Validate the SBML model + except Exception as e: #collect errors to display + error_txt = f"Unexpected Error: in sbmlutil.add_reaction {rxn} for {model_id}. \n {str(e)}." + raise Exception(error_txt) + +def test_add_reaction_for_bioscrape(): + """ + Generates models for bioscrape including the particular annotations needed. + """ + S1, S2, S3 = Species("S1"), Species("S2"), Species("S3") + species = [S1, S2, S3] + for_bioscrape = True #Toggle for_bioscrape + propensities = [MassAction(k_forward = 1, k_reverse = .1), HillPositive(k = 1, n = 2., K = 3., s1 = S1), + HillNegative(k = 1, n = 2., K = 3., s1 = S1), + ProportionalHillPositive(k = 1, n = 2, K = 3., s1 = S1, d = S2), + ProportionalHillNegative(k = 1, n = 2, K = 3., s1 = S1, d = S2)] + for prop in propensities: + rxn_num = 0 + model_id = f"{prop.name}_model_with_for_bioscrape_{for_bioscrape}" + document, model = create_sbml_model(model_id = model_id) + add_all_species(model, species) + rxn = Reaction([S1], [S2, S3], propensity_type = prop) #create a reaction + try: + sbml_reaction = add_reaction(model, rxn, f"r{rxn_num}", for_bioscrape = for_bioscrape) #add reaction to SBML Model + rxn_num += 1 #increment reaction id + crn_reactants = [str(S1)] + crn_products = [str(S2), str(S3)] + sbml_products = [p.getSpecies() for p in sbml_reaction.getListOfProducts()] + sbml_reactants = [p.getSpecies() for p in sbml_reaction.getListOfReactants()] + + #test that the reaction has the right inputs and outputs + assert set(crn_reactants) == set(sbml_reactants) + assert set(crn_products) == set(sbml_products) + + if len(crn_reactants) > 0: + assert all(crn_reactants.count(s.getSpecies()) == int(s.getStoichiometry()) for s in sbml_reaction.getListOfReactants()) + + if len(crn_products) > 0: + assert all(crn_products.count(s.getSpecies()) == int(s.getStoichiometry()) for s in sbml_reaction.getListOfProducts()) + + assert not sbml_reaction.getReversible() + # Check annotations: + sbml_annotation = sbml_reaction.getAnnotationString() + check_var = f"type={prop.name}" in str(sbml_annotation) + assert check_var == True + #Test that the sbml annotation has keys for all species and parameters + for k in prop.propensity_dict["parameters"]: + #convert k_reverse and k_forward to just k + k = k.replace("_reverse", "").replace("_forward", "") + check_var = f"{k}=" in sbml_annotation + assert check_var == True + for s in prop.propensity_dict["species"]: + check_var = f"{s}=" in sbml_annotation + assert check_var == True + #TODO is there a smart way to test that the rate formula is correct? + assert validate_sbml(document) == 0 # Validate the SBML model + except Exception as e: #collect errors + error_txt = f"Unexpected Error: in sbmlutil.add_reaction {rxn} for {model_id}. \n {str(e)}." + raise Exception(error_txt) + + +def test_generate_sbml_model(): + + #Test a non-reversible reaction + s1 = Species("S1") + s2 = Species("S2") + rx0 = Reaction.from_massaction(inputs=[s1], outputs=[s2], k_forward=0.1) + crn = ChemicalReactionNetwork(species = [s1, s2], reactions = [rx0]) + + # generate an sbml model + document, model = crn.generate_sbml_model() + # all species from the CRN are accounted for + assert len(model.getListOfSpecies()) == len(crn.species) + # all reactions from the CRN are accounted for + assert len(model.getListOfReactions()) == len(crn.reactions) + + #reversible needs to be off! + # assert not model.getListOfReactions()[0].isSetReversible() + + # test a reversible reaction + rx1 = Reaction.from_massaction(inputs=[s1], outputs=[s2], k_forward=0.1, k_reverse=0.1) + rxn_list = [rx1] + crn = ChemicalReactionNetwork(species=[s1, s2], reactions=rxn_list) + + # generate an sbml model + document, model = crn.generate_sbml_model() + # all species from the CRN are accounted for + assert len(model.getListOfSpecies())==len(crn.species) + # all reactions from the CRN are accounted for + assert len(model.getListOfReactions())== 2 + # although sbml represents a reverisble reaction with reversible flag + # BioCRNpyler always creates two reactions, because this is correct + # for stochastic simulation with SBML. + sbml_rxn = model.getListOfReactions() + # assert not sbml_rxn[0].isSetReversible() + # assert not sbml_rxn[1].isSetReversible() + + #Test propagation for for_bioscrape keyword + # generate an sbml model with for_bioscrape = True + document, model = crn.generate_sbml_model(for_bioscrape = True) + for r in model.getListOfReactions(): + assert r.getAnnotation() is not None + assert validate_sbml(document) == 0 + # generate an sbml model with for_bioscrape = False + document, model = crn.generate_sbml_model(for_bioscrape = False) + for r in model.getListOfReactions(): + assert r.getAnnotation() is None + assert validate_sbml(document) == 0 + + +def test_generate_sbml_model_parameter_names(): + + s1 = Species("S1") + s2 = Species("S2") + + #The correct parameter formating should be: "name_partid_mechanism" + key0 = ParameterKey(mechanism = "m", part_id = "p", name = "n") + k0 = ParameterEntry("n", 1.0, parameter_key = key0) + + #Tests 3 Parameter entries with seemingly redundant keys. + #In SBML parameter id, None will be kept blank, resulting in + #different numbers of underscores between the V's + k1 = ParameterEntry("v", 1.0, parameter_key = None) + + key2 = ParameterKey(mechanism = None, part_id = "v", name = "v") + k2 = ParameterEntry("v", 2.0, parameter_key = key2) + + key3 = ParameterKey(mechanism = "v", part_id = None, name = "v") + k3 = ParameterEntry("v", 2.0, parameter_key = key3) + + key4 = ParameterKey(mechanism = "v", part_id = "v", name = "v") + k4 = ParameterEntry("v", 2.0, parameter_key = key4) + + rx0 = Reaction.from_massaction(inputs = [], outputs = [s1], k_forward = k0, k_reverse = k1) #Throw a duplicate key for good measure! + rx1 = Reaction.from_massaction(inputs=[s1], outputs=[s2], k_forward=k1, k_reverse=k2) + rx2 = Reaction.from_massaction(inputs=2*[s1], outputs=2*[s2], k_forward=k3, k_reverse=k4) + rxn_list = [rx0, rx1, rx2] + crn = ChemicalReactionNetwork(species=[s1, s2], reactions=rxn_list) + + document, model = crn.generate_sbml_model() + assert validate_sbml(document) == 0 + correct_ids = set(["v_v_", "v__v", "v_v_v", "v__", "n_p_m"]) + ids = set([p.getId() for p in model.getListOfParameters()]) + assert ids == correct_ids + +def test_sbml_basics(): + """ + This test aims to test all Python libSBML functions and their return values. + It will catch errors if certain libSBML functions are not working as expected. + For example: At times, if the reaction rate law string is mis-formatted, it is + ignored by the SBML writing code and not caught by any other tests. Similarly, this + test will catch modifier reference, parameter values etc. + """ + def check(value, message): + """If 'value' is None, prints an error message constructed using + 'message' and then exits with status code 1 (for libsbml). If 'value' is an integer, + it assumes it is a libSBML return status code. If the code value is + LIBSBML_OPERATION_SUCCESS, returns without further action; if it is not, + prints an error message constructed using 'message' along with text from + libSBML explaining the meaning of the code, and exits with status code 1. + """ + if value == None: + raise SystemExit( + 'LibSBML returned a null value trying to ' + message + '.') + elif type(value) is int: + if value == libsbml.LIBSBML_OPERATION_SUCCESS: + return + else: + err_msg = 'Error encountered trying to ' + message + '.' \ + + 'LibSBML returned error code ' + str(value) + ': "' \ + + libsbml.OperationReturnValue_toString(value).strip() + '"' + raise SystemExit(err_msg) + else: + return + + from biocrnpyler.sbmlutil import _create_global_parameter, _create_local_parameter + from biocrnpyler.sbmlutil import _create_modifiers, _create_products, _create_reactants + # generate an sbml model + document, model = create_sbml_model() + + # If the document/model creation failed the following two lines + # will catch it: + check(document, 'create SBMLDocument object') + check(model, 'create SBML Model object') + S1 = Species("S1") + S2 = Species("S2") + compartment = model.getCompartment(0) + check(compartment, 'get compartment in SBML model') + sbml_species = add_species(model, compartment, S1, initial_concentration= 10) + sbml_species2 = add_species(model, compartment, S2, initial_concentration= 10) + check(sbml_species.getId(), 'get ID for SBML species') + check(sbml_species.getInitialConcentration(), 'get concentration for SBML species') + + prop_hill = HillPositive(k = 1, s1 = S2, K = 10, n = 2) + crn_rxn = Reaction([S1],[], propensity_type = prop_hill) + check(model.createReaction(), 'create a new SBML reaction') + rx1 = model.getReaction(0) + check(rx1, 'get the created reaction') + check(rx1.setId('r1'), 'set ID for reaction') + check(rx1.setReversible(False), 'set reversible attribute for reaction') + _create_reactants(crn_rxn.inputs, rx1, model) + _create_products(crn_rxn.outputs, rx1, model) + _create_modifiers(crn_rxn, rx1, model) + + check(rx1.getModifier(0), 'create species modifier') + modifier = rx1.getModifier(0) + check(modifier.getSpecies(), 'get the species id for the modifier reference') + rateLaw = rx1.createKineticLaw() + check(rateLaw, 'create kineticLaw for reaction') + local_param = _create_local_parameter(rateLaw, 'k_local', 10) + check(local_param, 'create local parameter in SBML model') + global_param = _create_global_parameter(model, 'k_global', 10) + check(global_param, 'create global parameter in SBML model') + check(rateLaw.setFormula('k_local*10 - k_global/2'), 'set rate formula for reaction') + validator = validateSBML(ucheck = False) + validation_result = validator.validate(document, print_results = True) + if validation_result > 0: + raise Exception('Invalid SBML model.') \ No newline at end of file diff --git a/Tests/test_simulation_packages_import.py b/Tests/test_simulation_packages_import.py new file mode 100644 index 00000000..fbb99f52 --- /dev/null +++ b/Tests/test_simulation_packages_import.py @@ -0,0 +1,73 @@ +# Copyright (c) 2020, Build-A-Cell. All rights reserved. +# See LICENSE file in the project root directory for details. + +import pytest + + +def test_bioscrape_import_simulate(): + from biocrnpyler import ChemicalReactionNetwork, Species + try: + import numpy as np + + X = Species("X") + CRN = ChemicalReactionNetwork(species=[X],reactions=[]) + with pytest.warns(None) as record: + sim_result = CRN.simulate_with_bioscrape(timepoints=np.linspace(0, 10, 100), initial_condition_dict = {str(X):1}) + + + #In the case bioscrape is not imported + if sim_result is None: + # check the warning message + assert "simulate_with_bioscrape is depricated and will cease working in a future release." in str(record[0].message) + #In the case bioscrape is imported + else: + assert str(X) in sim_result + except ModuleNotFoundError: + print('test skipped') + + +def test_bioscrape_import_simulate_via_sbml(): + from biocrnpyler import ChemicalReactionNetwork, Species + try: + import numpy as np + + X = Species("X") + CRN = ChemicalReactionNetwork(species=[X],reactions=[]) + with pytest.warns(None) as record: + sim_result, bioscrape_model = CRN.simulate_with_bioscrape_via_sbml(timepoints=np.linspace(0, 10, 100), initial_condition_dict={str(X):1}, return_model=True) + + + #In the case bioscrape is not imported + if sim_result is None and bioscrape_model is None: + # only one warning was triggered + assert len(record) == 1 + # check the warning message + assert str(record[0].message) == "bioscrape was not found, please install bioscrape" + + #In the case bioscrape is imported + else: + assert str(X) in sim_result + assert bioscrape_model is not None + except ModuleNotFoundError: + print('test skipped') + + +def test_libroadrunner_import(): + from biocrnpyler import ChemicalReactionNetwork + try: + import numpy as np + + CRN = ChemicalReactionNetwork(species=[],reactions=[]) + with pytest.warns(None) as record: + sim_results = CRN.runsim_roadrunner(timepoints=np.linspace(0, 10, 100), filename=None) + + assert sim_results is None + + # only one warning was triggered + assert len(record) == 1 + # check the warning message + assert str(record[0].message) == "libroadrunner was not found, please install libroadrunner" + except ModuleNotFoundError: + print('test skipped') + + diff --git a/Tests/test_species.py b/Tests/test_species.py index 02e8df76..3a08a455 100644 --- a/Tests/test_species.py +++ b/Tests/test_species.py @@ -2,16 +2,13 @@ # See LICENSE file in the project root directory for details. from unittest import TestCase -from biocrnpyler import Species +from biocrnpyler import Species, WeightedSpecies +import pytest class TestSpecies(TestCase): def test_species_initialization(self): - # species should not have type 'complex' should use ComplexSpecies class - with self.assertWarnsRegex(Warning, f'species which are formed of two species or more should be called using'): - Species(name='test_species', material_type='complex') - # tests naming convention repr without species type or attributes species = Species(name='test_species') self.assertEqual(repr(species), species.name) @@ -46,10 +43,15 @@ def test_species_initialization(self): species = Species(name='test_species', initial_concentration=initial_concentration) self.assertEqual(species.initial_concentration, initial_concentration) + #test OrderedMonomer subclass + self.assertTrue(species.parent is None) + self.assertTrue(species.position is None) + self.assertTrue(species.direction is None) + def test_add_attribute(self): species = Species(name='test_species') # an attribute must be a string - with self.assertRaisesRegexp(AssertionError,f'must be an alpha-numeric string'): + with self.assertRaisesRegex(AssertionError,f'must be an alpha-numeric string'): species.add_attribute({'k': 'v'}) species.add_attribute('attribute') @@ -74,3 +76,72 @@ def test_species_equality(self): s5 = Species(name='a', material_type='mat1', attributes=['red', 'large']) # different attributes: not the same species self.assertFalse(s1 == s5) + + +def test_weighted_species_init(): + s1 = Species(name='a') + # normal operations + ws1 = WeightedSpecies(species=s1) + assert ws1.species == s1 + assert ws1.stoichiometry == 1 + + with pytest.raises(ValueError, match='Stoichiometry must be positive integer!'): + WeightedSpecies(species=s1, stoichiometry=0) + + with pytest.raises(ValueError, match='Stoichiometry must be positive integer!'): + WeightedSpecies(species=s1, stoichiometry=-1) + + ws2 = WeightedSpecies(species=s1, stoichiometry=1.34) + assert ws2.stoichiometry == 1 + + +def test_merging_weighted_species(): + s1 = Species(name='a') + + ws1 = WeightedSpecies(species=s1, stoichiometry=2) + ws2 = WeightedSpecies(species=s1, stoichiometry=5) + ws_list = [ws1, ws2] + + freq_dict = WeightedSpecies._count_weighted_species(ws_list) + assert len(freq_dict) == 1 + ws_merged = list(freq_dict.values()) + assert ws_merged[0] == 7 + + s2 = Species(name='b') + + ws1 = WeightedSpecies(species=s1, stoichiometry=2) + ws2 = WeightedSpecies(species=s2, stoichiometry=5) + ws_list = [ws1, ws2] + freq_dict = WeightedSpecies._count_weighted_species(ws_list) + assert len(freq_dict) == 2 + + ws_merged = list(freq_dict.values()) + assert ws_merged[0] == 2 + assert ws_merged[1] == 5 + + +def test_weighted_species_equality(): + s1 = Species(name='a') + ws1 = WeightedSpecies(species=s1, stoichiometry=1) + + s2 = Species(name='a') + ws2 = WeightedSpecies(species=s2, stoichiometry=3) + assert ws1 != ws2 + + s2 = Species(name='b') + ws3 = WeightedSpecies(species=s2, stoichiometry=1) + + assert ws1 != ws3 + + + + + + + + + + + + + diff --git a/biocrnpyler/__init__.py b/biocrnpyler/__init__.py index 3e1f0a92..660024ab 100644 --- a/biocrnpyler/__init__.py +++ b/biocrnpyler/__init__.py @@ -1,38 +1,39 @@ # __init__.py - initialization of biocrnpyler toolbox # RMM, 11 Aug 2018 -# Core classes -from .mixture import * -from .mechanism import * -from .component import * -from .parameter import * -from .global_mechanism import * from .chemical_reaction_network import * +from .component import * +# Core components +from .components_basic import * +#CRNlab imports +from .crnlab import * +from .dna_assembly import * +from .dna_construct import * +from .dna_part import * +from .dna_part_cds import * +from .dna_part_misc import * +from .dna_part_promoter import * +from .dna_part_rbs import * +from .dna_part_terminator import * +from .global_mechanism import * +from .mechanism import * #core mechanisms from .mechanisms_binding import * from .mechanisms_enzyme import * from .mechanisms_txtl import * - -# Core components -from .components_basic import * -from .mixtures_extract import * +# Core classes +from .mixture import * from .mixtures_cell import * -from .dna_assembly import * -from .dna_assembly_promoter import * -from .dna_assembly_rbs import * - -#CRNlab imports -from .crnlab import * - -#specialized components - maybe these shouldn't be auto-imported? -from .components_dcas9 import * - +from .mixtures_extract import * +from .parameter import * +from .plotting import * +from .polymer import * +from .propensities import * +from .reaction import * -# Additional functions from .sbmlutil import * -try: - from .plotting import * -except ModuleNotFoundError as e: - warn(str(e)) - warn("plotting is disabled because you are missing some libraries") \ No newline at end of file +from .species import * +from .utils import * + +#checking for nonexistant plotting-related modules now happens in plotting.py diff --git a/biocrnpyler/chemical_reaction_network.py b/biocrnpyler/chemical_reaction_network.py index 26b976c5..d810a8dc 100644 --- a/biocrnpyler/chemical_reaction_network.py +++ b/biocrnpyler/chemical_reaction_network.py @@ -1,908 +1,119 @@ -# Copyright (c) 2019, Build-A-Cell. All rights reserved. + +# Copyright (c) 2020, Build-A-Cell. All rights reserved. # See LICENSE file in the project root directory for details. -from warnings import warn -from .sbmlutil import * +import copy import warnings -import numpy as np -from typing import List, Union, Dict - - - -class Species(object): - """ A formal species object for a CRN - A Species must have a name. They may also have a material_type (such as DNA, - RNA, Protein), and a list of attributes. - """ - - def __init__(self, name: str, material_type="", attributes=[], - initial_concentration=0): - - self.name = self.check_name(name) - self.material_type = self.check_material_type(material_type) - self.initial_concentration = initial_concentration - if material_type == "complex": - warn("species which are formed of two species or more should be " - "called using the chemical_reaction_network.ComplexSpecies " - "constructor for attribute inheritance purposes.") - - self.attributes = [] - - if attributes is not None: - for attribute in attributes: - self.add_attribute(attribute) - - #Check that the string contains is alpha-numeric characters or "_" and that the first character is a letter. IF the name is a starts with a number, there must be a material type. - def check_material_type(self, material_type): - - - if material_type in [None, ""] and self.name[0].isnumeric(): - raise ValueError(f"species name: {self.name} contains a number as the first character and therefore requires a material_type.") - elif material_type == None: - return "" - elif (material_type.replace("_", "").isalnum() and material_type.replace("_", "")[0].isalpha()) or material_type == "": - return material_type - else: - raise ValueError(f"material_type {material_type} must be alpha-numeric and start with a letter.") - - - #Check that the string contains only underscores and alpha-numeric characters - def check_name(self, name): - no_underscore_string = name.replace("_", "") - if no_underscore_string.isalnum(): - return name - else: - raise ValueError(f"name attribute {name} must consist of letters, numbers, or underscores.") - - def __repr__(self): - txt = "" - if self.material_type not in ["", None]: - txt = self.material_type + "_" - - txt += self.name - - if len(self.attributes) > 0 and self.attributes != []: - for i in self.attributes: - if i is not None: - txt += "_" + str(i) - txt.replace("'", "") - return txt - - def replace_species(self, species, new_species): - if not isinstance(species, Species): - raise ValueError('species argument must be an instance of Species!') - - if not isinstance(new_species, Species): - raise ValueError('species argument must be an instance of Species!') - - if self == species: - return new_species - else: - return self - - #A more powerful printing function - def pretty_print(self, show_material = True, show_attributes = True, **kwargs): - txt = "" - if self.material_type not in ["", None] and show_material: - txt = self.material_type + "[" - - txt += self.name - - if len(self.attributes) > 0 and self.attributes != [] and show_attributes: - txt += "(" - for i in self.attributes: - if i is not None: - txt += str(i)+", " - txt = txt[:-2]+")" - - txt.replace("'", "") - - if self.material_type not in ["", None] and show_material: - txt += "]" - - return txt +from typing import Dict, List, Tuple, Union +from warnings import warn - def add_attribute(self, attribute: str): - assert isinstance(attribute, str) and attribute is not None and attribute.isalnum(), "Attribute: %s must be an alpha-numeric string" % attribute - self.attributes.append(attribute) +import libsbml - def __eq__(self, other): - """ - Overrides the default implementation - Two species are equivalent if they have the same name, type, and attributes - :param other: Species instance - :return: boolean - """ +from .reaction import Reaction +from .sbmlutil import add_all_reactions, add_all_species, create_sbml_model +from .species import Species - if isinstance(other, Species) \ - and self.material_type == other.material_type \ - and self.name == other.name \ - and set(self.attributes) == set(other.attributes): - return True - else: - return False - def __gt__(self,Species2): - return self.name > Species2.name - def __lt__(self,Species2): - return self.name < Species2.name - - def __hash__(self): - return str.__hash__(repr(self)) +class ChemicalReactionNetwork(object): + """A chemical reaction network is a container of species and reactions + chemical reaction networks can be compiled into SBML. -class ComplexSpecies(Species): - """ A special kind of species which is formed as a complex of two or more species. - Used for attribute inheritance and storing groups of bounds Species. - Note taht in a ComplexSpecies, the order of the species list does not matter. - This means that ComplexSpecies([s1, s2]) = ComplexSpecies([s2, s1]). - This is good for modelling order-indpendent binding complexes. - For a case where species order matters (e.g. polymers) use OrderedComplexSpecies + reaction types: + mass action: standard mass action semantics where the propensity of a + reaction is given by deterministic propensity = + .. math:: + k \Prod_{inputs i} [S_i]^a_i + stochastic propensity = + .. math:: + k \Prod_{inputs i} (S_i)!/(S_i - a_i)! + where a_i is the spectrometric coefficient of species i """ - def __init__(self, species: List[Union[Species,str]], name = None, material_type = "complex", attributes = None, initial_concentration = 0, **keywords): - if len(species) <= 1: - raise ValueError("chemical_reaction_network.complex requires 2 " - "or more species in its constructor.") - - + def __init__(self, species: List[Species], reactions: List[Reaction], show_warnings=False): self.species = [] - for s in flatten_list(species): - if isinstance(s, Species): - self.species.append(s) - elif isinstance(s, str): - self.species.append(Species(s)) - else: - raise ValueError("ComplexSpecies must be defined by (nested) list of Species (or subclasses thereof).") - - - self.species_set = list(set(self.species)) - - if name is not None: - self.custom_name = True - elif name is None: - self.custom_name = False - name = "" - list.sort(self.species, key = lambda s:repr(s)) - - list.sort(self.species_set, key = lambda s:repr(s)) - for s in self.species_set: - count = self.species.count(s) - if count > 1: - name+=f"{count}x_" - if not (isinstance(s, ComplexSpecies) or s.material_type == ""): - name+=f"{s.material_type}_{s.name}_" - else: - name+=f"{s.name}_" - name = name[:-1] - - self.name = self.check_name(name) - self.material_type = self.check_material_type(material_type) - self.initial_concentration = initial_concentration - - if attributes is None: - attributes = [] - for s in self.species: - attributes += s.attributes - attributes = list(set(attributes)) - - while None in attributes: - attributes.remove(None) - - self.attributes = attributes + self.reactions = [] + self.add_species(species) + self.add_reactions(reactions) + ChemicalReactionNetwork.check_crn_validity(self.reactions, self.species, show_warnings=show_warnings) - def __contains__(self,item): - if not isinstance(item, Species): - raise ValueError("Operator 'in' requires chemical_reaction_network.Species (or a subclass). Received: "+str(item)) - if item in self.species: - #this is the base case - return True - else: - #this is the recursive part. We want to check all - #internal complexes for the thing we're looking for - for content in self.species: - if isinstance(content,ComplexSpecies) : - if item in content: - return True - #if we got here then we've failed to find it - return False - - #Replaces species with new_species in the entire Complex Species. Acts recursively on nested ComplexSpecies - def replace_species(self, species: Species, new_species: Species): - if not isinstance(species, Species): - raise ValueError('species argument must be an instance of Species!') - - if not isinstance(new_species, Species): - raise ValueError('species argument must be an instance of Species!') - - new_species_list = [] - for s in self.species: - if s == species: - new_species_list.append(new_species) - elif isinstance(s, ComplexSpecies): - new_s = s.replace_species(species, new_species) - new_species_list.append(new_s) - else: - new_species_list.append(s) - - new_name = None - if self.custom_name == True: - new_name = self.name - - return ComplexSpecies(species = new_species_list, name = new_name, material_type = self.material_type, attributes = self.attributes) - - def pretty_print(self, show_material = True, show_attributes = True, **kwargs): - txt = "" - if self.material_type not in ["", None] and show_material: - txt += self.material_type - txt += "[" - for s in self.species_set: - count = self.species.count(s) - if count > 1: - txt += f"{count}x_" - txt += s.pretty_print(show_material = show_material, show_attributes = False)+":" - txt = txt[:-1] - - if len(self.attributes) > 0 and self.attributes != [] and show_attributes: - txt += "(" - for i in self.attributes: - if i is not None: - txt += str(i)+", " - txt = txt[:-2]+")" - - txt.replace("'", "") - - txt += "]" - - return txt - - -class Multimer(ComplexSpecies): - """A subclass of ComplexSpecies for Complexes made entirely of the same kind of species, - eg dimers, tetramers, etc. - """ - def __init__(self, species, multiplicity, name = None, material_type = "complex", attributes = None, initial_concentration = 0): - - if isinstance(species, str): - species = [Species(name = species)] - elif not isinstance(species, Species): - raise ValueError("Multimer must be defined by a Species (or subclasses thereof) and a multiplicity (int).") - else: + def add_species(self, species, show_warnings=False): + if not isinstance(species, list): species = [species] - ComplexSpecies.__init__(self, species = species*multiplicity, name = name, material_type = material_type, attributes = attributes, initial_concentration = initial_concentration) - -class OrderedComplexSpecies(ComplexSpecies): - """ A special kind of species which is formed as a complex of two or more species. - In OrderedComplexSpecies the order in which the complex subspecies are is defined - denote different species, eg [s1, s2, s3] != [s1, s3, s2]. - Used for attribute inheritance and storing groups of bounds Species. - """ - - def __init__(self, species, name = None, material_type = "ordered_complex", attributes = None, initial_concentration = 0): - if len(species) <= 1: - raise ValueError("chemical_reaction_network.complex requires 2 " - "or more species in its constructor.") - - - new_species = flatten_list(species) - self.species = [] - for s in new_species: - if isinstance(s, Species): - self.species.append(s) - elif isinstance(s, str): - self.species.append(Species(s)) - else: - raise ValueError("OrderedComplexSpecies must be defined by (nested) list of Species (or subclasses thereof).") - - if name is not None: - self.custom_name = True - elif name is None: - self.custom_name = False - name = "" - for s in self.species: - if isinstance(s, str): - s = Species(name = s) - if s.material_type not in ["complex", "ordered_complex", ""]: - name+=f"{s.material_type}_{s.name}_" - else: - name+=f"{s.name}_" - name = name[:-1] - - self.name = self.check_name(name) - self.material_type = self.check_material_type(material_type) - self.initial_concentration = initial_concentration - - if attributes is None: - attributes = [] - for s in self.species: - attributes += s.attributes - attributes = list(set(attributes)) - - while None in attributes: - attributes.remove(None) - - self.attributes = attributes - - #Replaces species with new_species in the entire Complex Species. Acts recursively on nested ComplexSpecies - def replace_species(self, species: Species, new_species: Species): - if not isinstance(species, Species): - raise ValueError('species argument must be an instance of Species!') - - if not isinstance(new_species, Species): - raise ValueError('species argument must be an instance of Species!') - - new_species_list = [] - for s in self.species: - if s == species: - new_species_list.append(new_species) - elif isinstance(s, ComplexSpecies): - new_s = s.replace_species(species, new_species) - new_species_list.append(new_s) - else: - new_species_list.append(s) - - new_name = None - if self.custom_name == True: - new_name = self.name - - return OrderedComplexSpecies(species = new_species_list, name = new_name, material_type = self.material_type, attributes = self.attributes) - - def pretty_print(self, show_material = True, show_attributes = True, **kwargs): - txt = "" - if self.material_type not in ["", None] and show_material: - txt += self.material_type+"[" - - txt += "[" - - for s in self.species: - txt += s.pretty_print(show_material = show_material, show_attributes = False)+":" - txt = txt[:-1] - - if len(self.attributes) > 0 and self.attributes != [] and show_attributes: - txt += "(" - for i in self.attributes: - if i is not None: - txt += str(i)+", " - txt = txt[:-2]+")" - - txt.replace("'", "") - txt += "]" - - return txt - - -class Reaction(object): - """ An abstract representation of a chemical reaction in a CRN - A reaction has the form: - \sum_i n_i I_i --> \sum_i m_i O_i @ rate = k - where n_i is the count of the ith input, I_i, and m_i is the count of the - ith output, O_i. - If the reaction is reversible, the reverse reaction is also included: - \sum_i m_i O_i --> \sum_i n_i I_i @ rate = k_rev - """ - def __init__(self, inputs, outputs, k = 0, input_coefs = None, - output_coefs = None, k_rev = 0, propensity_type = "massaction", - rate_formula = None, propensity_params = None): - - if len(inputs) == 0 and len(outputs) == 0: - warn("Reaction Inputs and Outputs both contain 0 Species.") - - if k != 0 and propensity_params is not None and "k" not in propensity_params: - propensity_params["k"] = k - elif k == 0 and propensity_params is not None and "k" in propensity_params: - k = propensity_params["k"] - elif k != 0 and propensity_params is not None and k != propensity_params['k']: - print("k=", k, "propensity_params[k]", propensity_params["k"], "propensity_params", propensity_params) - raise ValueError("Inconsistent rate constants: propensity_params['k'] != k.") - - if propensity_type == "massaction" and propensity_params is not None: - warn("ValueWarning: propensity_params dictionary passed into a " - "massaction propensity. Massaction propensities do not " - "require a param dictionary.") - elif propensity_type != "massaction" and propensity_params is None: - raise ValueError("Non-massaction propensities require a propensity_params dictionary passed to the propensity_params keyword.") - elif propensity_type != "massaction" and k_rev != 0: - raise ValueError("Invalid reversible reaction for propensity " - f"type = {propensity_type}. Only massaction " - "propensities support the reversible rate k_rev. " - "Consider creating two seperate reactions " - "instead.") - elif propensity_type == "hillpositive": - if not ("k" in propensity_params and "s1" in propensity_params and "K" in propensity_params \ - and "n" in propensity_params): - raise ValueError("hillpositive propensities, p(s1; k, K, n) " - "= k*s1^n/(s1^n + K), require the following " - "propensity_params: " - "'k':rate constant (float)" - "'s1':species (chemical_reaction_network.species), " - "'n':cooperativity(float), " - "and 'K':dissociationc constant (float).") - elif propensity_type == "hillnegative": - if not ("k" in propensity_params and "s1" in propensity_params and "K" in propensity_params \ - and "n" in propensity_params): - raise ValueError("hillnegative propensities, " - "p(s1; k, K, n) = k*1/(s1^n + K), require " - "the following propensity_params:" - "'k':rate constant (float)" - "'s1':species (chemical_reaction_network.species), " - "'n':cooperativity(float), " - "and 'K':dissociationc constant (float)") - elif propensity_type == "proportionalhillpositive": - if not ("k" in propensity_params and "s1" in propensity_params and "d" in propensity_params \ - and "K" in propensity_params \ - and "n" in propensity_params): - raise ValueError("proportionalhillpositive propensities, " - "p(s1, d; k, K, n) = k*d*s1^n/(s1^n + K), require the " - "following propensity_params: " - "'k':rate constant (float)" - "'s1':species (chemical_reaction_network.species), " - "'d':species (chemical_reaction_network.species), " - "'n':cooperativity(float), " - "and 'K':dissociationc onstant (float)") - elif propensity_type == "proportionalhillnegative": - if not ("k" in propensity_params and "s1" in propensity_params and "d" in propensity_params \ - and "K" in propensity_params \ - and "n" in propensity_params): - raise ValueError("proportionalhillnegative propensities, " - "p(s1, d; k, K, n) = k*d/(s1^n + K), require the " - "following propensity_params: " - "'k':rate constant (float)" - "'s1':species (chemical_reaction_network.species), " - "'d':species (chemical_reaction_network.species), " - "'n':cooperativity(float), " - "and 'K':dissociationc onstant (float)") - elif propensity_type == "general": - if "rate" not in propensity_params: - raise ValueError("general propensities, p(s) = k * f(s), " - "require the propensity_params: " - "'rate':f(s) where f(s) is an SBML compatable function " - "of arbitrary species, " - "s (use repr(chemical_reaction_network.species) to get " - "the proper text representation of a species name).") - elif propensity_type != "massaction": - raise ValueError(f"Unknown propensity type: {propensity_type}.") - self.propensity_type = propensity_type - self.propensity_params = propensity_params - - # Check that inputs and outputs only contain species - #if inputs or outputs is a nested list, flatten that list - new_inputs = [] - for s in flatten_list(inputs): - if isinstance(s, Species): - new_inputs.append(s) - else: - raise ValueError(f"A non-species object was used as a species: {s}!") - inputs = new_inputs - - new_outputs = [] - for s in flatten_list(outputs): - if isinstance(s, Species): - new_outputs.append(s) - else: - raise ValueError(f"A non-species object was used as a species: {s}!") - outputs = new_outputs - - #OLD CHECK - # Check that inputs and outputs only contain species - #if any(not isinstance(s, Species) for s in inputs + outputs): - # raise ValueError("A non-species object was used as a species.") - - # internal representation of a reaction - - #self.inputs and self.outputs should be ordered lists. - self.inputs = [] - for s in inputs: - if s not in self.inputs: - self.inputs.append(s) - self.outputs = [] - for s in outputs: - if s not in self.outputs: - self.outputs.append(s) - - #self.input_coefs[i] is the number of self.inputs[i] into the reaction - self.input_coefs = None - #self.output coefs is analogous to above - self.output_coefs = None - - # Check that rates are valid - if k <= 0: - raise ValueError(f"Reaction rate <= 0: k={k}") - else: - self.k = k - if k_rev > 0: - self.reversible = True - self.k_r = k_rev - else: - self.k_r = 0 - self.reversible = False - - # TODO input coefficients should be stored with the species a dictionary (same for the output ) - # Set input coefficients - if input_coefs is None: - self.input_coefs = [inputs.count(s) for s in self.inputs] - elif input_coefs is not None and len(input_coefs) == len(self.inputs): - self.input_coefs = input_coefs - elif len(input_coefs) == len(inputs) \ - and len(self.inputs) != len(inputs): - raise ValueError("Input species and input_coefs contain " - "contradictory counts.") - else: - raise ValueError(f"len(input_coefs) ({len(input_coefs)}) doesn't " - f"match len(self.inputs) ({len(self.inputs)}).") - - # Set Output Coefs - if output_coefs is None: - self.output_coefs = [outputs.count(s) for s in self.outputs] - elif output_coefs is not None \ - and len(output_coefs) == len(self.outputs): - self.output_coefs = output_coefs - elif len(output_coefs) == len(outputs) \ - and len(self.outputs) != len(outputs): - raise ValueError(f"Output species ({self.outputs}) and output_coefs ({output_coefs}) contain " - "contradictory counts.") - else: - raise ValueError(f"len(output_coefs) ({len(output_coefs)}) doesn't " - f"match len(self.outputs) ({len(self.outputs)}).") - - - #Replaces species with new_species in the entire CRN - def replace_species(self, species: Species, new_species: Species): - if not isinstance(species, Species): - raise ValueError('species argument must be an instance of Species!') - - if not isinstance(new_species, Species): - raise ValueError('species argument must be an instance of Species!') - - new_inputs = [] - for s in self.inputs: - if s == species: - new_inputs.append(new_species) - elif isinstance(s, ComplexSpecies): - new_s = s.replace_species(species, new_species) - new_inputs.append(new_s) - else: - new_inputs.append(s) - self.inputs = new_inputs - - new_outputs = [] - for s in self.outputs: - if s == species: - new_outputs.append(new_species) - elif isinstance(s, ComplexSpecies): - new_s = s.replace_species(species, new_species) - new_outputs.append(new_s) - else: - new_outputs.append(s) - self.outputs = new_outputs + species = Species.flatten_list(species) #Flatten the list - if self.propensity_params is not None: - new_params = {} - for key in self.propensity_params: - if isinstance(self.propensity_params[key], ComplexSpecies): - new_params[key] = self.propensity_params[key].replace_species(species, new_species) - elif isinstance(self.propensity_params[key], Species) and self.propensity_params[key] == species: - new_params[key] = new_species - else: - new_params[key] = self.propensity_params[key] - - new_r = Reaction(inputs = self.inputs, outputs = self.outputs, input_coefs = self.input_coefs, output_coefs = self.output_coefs, propensity_type = self.propensity_type, propensity_params = self.propensity_params, k = self.k, k_rev = self.k_r) - return new_r - - #Helper function to print the text of a rate function - def rate_func_text(self, pretty_print = False, show_material = True, show_attributes = True, **kwargs): - tab = (" " * 8) - txt = "" - if self.propensity_type == "massaction": - input_func_args = "" - input_prod = f"{self.k}" - for i in range(len(self.inputs)): - if pretty_print: - sin = self.inputs[i].pretty_print(show_material = show_material, show_attributes = show_attributes, **kwargs) - else: - sin = repr(self.inputs[i]) - - input_func_args += f"{sin}" - - if self.input_coefs[i] > 1: - input_prod+=f"*{sin}^{self.input_coefs[i]}" - else: - input_prod+=f"*{sin}" - - if i < len(self.inputs)-1: - input_func_args += "," - - if len(self.inputs) > 0: - input_func_args = "("+input_func_args+")" - txt += f"massaction: k_f{input_func_args}={input_prod}" - - if self.reversible: - output_func_args = "" - output_prod = f"{self.k_r}" - - for i in range(len(self.outputs)): - if pretty_print: - sout = self.outputs[i].pretty_print(show_material = show_material, show_attributes = show_attributes, **kwargs) - else: - sout = repr(self.outputs[i]) - - output_func_args += f"{sout}" - - if self.output_coefs[i] > 1: - output_prod+=f"*{sout}^{self.output_coefs[i]}" - else: - output_prod+=f"*{sout}" - - if i < len(self.outputs)-1: - output_func_args += "," - - if len(self.outputs) > 0: - output_func_args = "("+output_func_args+")" - txt += f" k_r{output_func_args}={output_prod}" - - elif self.propensity_type == "hillpositive": - if pretty_print: - s1 = self.propensity_params["s1"].pretty_print(show_material = show_material, show_attributes = show_attributes, **kwargs) - else: - s1 = repr(self.propensity_params["s1"]) - - kd = str(self.propensity_params["K"]) - n = str(self.propensity_params["n"]) - txt += f"hillpositive: k({s1})={self.k}*{s1}^{n}/({kd}+{s1}^{n})" - elif self.propensity_type == "hillnegative": - - if pretty_print: - s1 = self.propensity_params["s1"].pretty_print(show_material = show_material, show_attributes = show_attributes, **kwargs) - else: - s1 = repr(self.propensity_params["s1"]) - - kd = str(self.propensity_params["K"]) - n = str(self.propensity_params["n"]) - txt += f"hillnegative: k({s1})={self.k}*1/({kd}+{s1}^{n})" - elif self.propensity_type == "proportionalhillpositive": - if pretty_print: - s1 = self.propensity_params["s1"].pretty_print(show_material = show_material, show_attributes = show_attributes, **kwargs) - s2 = self.propensity_params["d"].pretty_print(show_material = show_material, show_attributes = show_attributes, **kwargs) - else: - s1 = repr(self.propensity_params["s1"]) - s2 = repr(self.propensity_params["d"]) - - kd = str(self.propensity_params["K"]) - n = str(self.propensity_params["n"]) - txt += (f"proportionalhillpositive: k({s1}, " - f"{s2})={self.k}*{s2}*{s1}^{n}/({kd}+{s1}^{n})") - elif self.propensity_type == "proportionalhillnegative": - if pretty_print: - s1 = self.propensity_params["s1"].pretty_print(show_material = show_material, show_attributes = show_attributes, **kwargs) - s2 = self.propensity_params["d"].pretty_print(show_material = show_material, show_attributes = show_attributes, **kwargs) - else: - s1 = repr(self.propensity_params["s1"]) - s2 = repr(self.propensity_params["d"]) - - kd = str(self.propensity_params["K"]) - n = str(self.propensity_params["n"]) - txt += (f"proportionalhillnegative: k({s1}, " - f"{s2})={self.k}*{s2}/({kd}+{s1}^{n})") - elif self.propensity_type == "general": - eq = self.propensity_params["rate"] - txt += f"general: k(x)={self.k}*{eq}" - else: - raise ValueError("Unknown Propensity Type: " - f"{self.propensity_type}.") - - return txt - - def __repr__(self, **kwargs): - tab = (" " * 8) - txt = "" - for i in range(len(self.inputs)): - if self.input_coefs[i] > 1: - txt += str(self.input_coefs[i]) + " " + str(self.inputs[i]) - else: - txt += str(self.inputs[i]) - if i < len(self.inputs) - 1: - txt += " + " - if self.reversible: - txt += " <--> " - else: - txt += " --> " - for i in range(len(self.outputs)): - if self.output_coefs[i] > 1: - txt += str(self.output_coefs[i]) + " " + str(self.outputs[i]) - else: - txt += str(self.outputs[i]) - if i < len(self.outputs) - 1: - txt += " + " - txt += tab - txt += self.rate_func_text(**kwargs) - - return txt + for s in species: + if not isinstance(s, Species): #check species are Species + raise ValueError("A non-species object was used as a species!") + if s not in self.species: #Do not add duplicate Species + self.species.append(copy.deepcopy(s)) #copy the species and add it to the CRN + + #This case matters when Species are inside an OrderedPolymerSpecies, in which case there can be duplicates (in terms of name) + if s in self.species: + s_duplicates = [S for S in self.species if s == S] + pass + #Code will go here for testing s.parent and s.position - def pretty_print(self, show_rates = True, show_material = True, show_attributes = True, **kwargs): - tab = (" " * 8) - txt = "" - for i in range(len(self.inputs)): - if self.input_coefs[i] > 1: - txt += str(self.input_coefs[i]) + " " + self.inputs[i].pretty_print(show_material = show_material, show_attributes = show_attributes, **kwargs) - else: - txt += self.inputs[i].pretty_print(show_material = show_material, show_attributes = show_attributes, **kwargs) - if i < len(self.inputs) - 1: - txt += " + " - if self.reversible: - txt += " <--> " - else: - txt += " --> " - for i in range(len(self.outputs)): - if self.output_coefs[i] > 1: - txt += str(self.output_coefs[i]) + " " + self.outputs[i].pretty_print(show_material = show_material, show_attributes = show_attributes, **kwargs) - else: - txt += self.outputs[i].pretty_print(show_material = show_material, show_attributes = show_attributes, **kwargs) - if i < len(self.outputs) - 1: - txt += " + " - txt += tab - if show_rates: - if self.reversible: - rate_txt = self.rate_func_text(pretty_print = True, show_material = show_material, show_attributes = show_attributes, **kwargs) - rate_txt = rate_txt.replace(" k_r", "\n"+tab+"k_r") - txt += "\n"+tab+rate_txt - else: - txt += "\n"+tab+self.rate_func_text(pretty_print = True, show_material = show_material, show_attributes = show_attributes, **kwargs) + def add_reactions(self, reactions: Union[Reaction,List[Reaction]], show_warnings=True) -> None: + """Adds a reaction or a list of reactions to the CRN object - return txt + :param reactions: Reaction instance or list of Reaction instances + :param show_warnings: whether to show warning when duplicated reactions/species was found + :return: None + """ + if not isinstance(reactions, list): + reactions = [reactions] + for r in reactions: + if not isinstance(r, Reaction): # check reactions and Reactions + raise ValueError("A non-reaction object was used as a reaction!") - def __eq__(self, other): - """Overrides the default implementation. - Two reactions are equivalent if they have the same inputs, outputs, - and rates.""" - complexes_equal = Reaction.complex_set_equality(self.inputs, - self.input_coefs, - other.inputs, - other.input_coefs) \ - and Reaction.complex_set_equality(self.outputs, - self.output_coefs, - other.outputs, - other.output_coefs) - rates_equal = (other.k == self.k and other.k_r == self.k_r) - propensity_types_equal = (self.propensity_type == other.propensity_type) + # add all the Species in the reaction to the CRN + reaction_species = list(set([w.species for w in r.inputs + r.outputs])) + self.add_species(reaction_species, show_warnings=show_warnings) - # must both be reactions with the same rates and numbers of inputs and - # outputs. - if not isinstance(other, Reaction): - return False - if complexes_equal and rates_equal and propensity_types_equal: - return True - elif complexes_equal and propensity_types_equal: - #warn("Two reactions with the same inputs and outputs but different " - #"rates are formally different, but may be undesired:" - #f"{repr(self)} and {repr(other)}.") - return False + self.reactions.append(copy.deepcopy(r)) #copy the Reaction and add it to the CRN - # If the reactions are reversible inverses of eachother, one's forward - # reaction could be the other's reverse - elif self.reversible and other.reversible: - reverse_complex_equal = Reaction.complex_set_equality(self.inputs, - self.input_coefs, - other.outputs, - other.output_coefs)\ - and Reaction.complex_set_equality(self.outputs, - self.output_coefs, - other.inputs, - other.input_coefs) - reverse_rates_equal = (other.k == self.k_r and other.k_r == self.k) - if reverse_complex_equal and reverse_rates_equal: - return True - elif reverse_complex_equal: - warn("Two reversible reactions with the same inputs and outputs" - " (reversed) but different rates are formally equal, but " - f"may be undesired:{repr(self)} and {repr(other)}") - return True - else: - return False - else: - return False + #TODO synchronize Species in the CRN @staticmethod - def complex_set_equality(c1, c1_coefs, c2, c2_coefs): - """Checks to see if two formal complexes (reaction input or output sets) are equal.""" - if len(c1) != len(c2): - return False - else: - for i in range(len(c1)): - s1 = c1[i] - coef1 = c1_coefs[i] - if s1 not in c2 or coef1 != c2_coefs[c2.index(s1)]: - return False - return True - - def pyrepr(self): - if self.reversible: - return [ - ([repr(i) for i in self.inputs], self.input_coefs, - [repr(i) for i in self.outputs], self.output_coefs, - self.k), - ([repr(i) for i in self.outputs], self.output_coefs, - [repr(i) for i in self.inputs], self.input_coefs, - self.k_r)] - else: - return [([repr(i) for i in self.inputs], self.input_coefs, - [repr(i) for i in self.outputs], - self.output_coefs, self.k)] - - -class ChemicalReactionNetwork(object): - """ A chemical reaction network is a container of species and reactions - chemical reaction networks can be compiled into SBML or represented - conveniently as python tuple objects. - reaction types: - mass action: standard mass action semantics where the propensity of a - reaction is given by deterministic propensity = - k \Prod_{inputs i} [S_i]^a_i - stochastic propensity = - k \Prod_{inputs i} (S_i)!/(S_i - a_i)! - where a_i is the spectrometric coefficient of species i - """ - def __init__(self, species: List[Species], reactions: List[Reaction], warnings = False): - self.species, self.reactions = ChemicalReactionNetwork.check_crn_validity(reactions, species, warnings=warnings) + def check_crn_validity(reactions: List[Reaction], species: List[Species], show_warnings=True) -> Tuple[List[Reaction],List[Species]]: + """Checks that the given list of reactions and list of species can form a valid CRN. - # TODO check whether we need this data structure - self.species2index = {} - for i in range(len(self.species)): - self.species2index[str(self.species[i])] = i - - def add_species(self, species, warnings = False): - if not isinstance(species, list): - species = [species] - self.species, self.reactions = ChemicalReactionNetwork.check_crn_validity(self.reactions, self.species+species, warnings=warnings) + :param reactions: list of reaction + :param species: list of species + :param show_warnings: whether to show warning when duplicated reactions/species was found + :return: tuple(reaction,species) + """ - def add_reactions(self, reactions, warnings = False): - if not isinstance(reactions, list): - reactions = [reactions] - self.species, self.reactions = ChemicalReactionNetwork.check_crn_validity(self.reactions+reactions, self.species, warnings=warnings) + if not all(isinstance(r, Reaction) for r in reactions): + raise ValueError("A non-reaction object was used as a reaction!") - @staticmethod - def check_crn_validity(reactions: List[Reaction], species: List[Species], warnings = False): - # Check to make sure species are valid and only have a count of 1 - checked_species = [] if not all(isinstance(s, Species) for s in species): - print(f"A non-species object was used as a species: {species}!") raise ValueError("A non-species object was used as a species!") - for s in species: - if species.count(s) > 1: - pass - #warn("Species "+str(s)+" duplicated in CRN definition. - # Duplicates have been removed.") - if s not in checked_species: - checked_species.append(s) - - # Check to make sure reactions are valid meaning: - # only have a count of 1 - # all species in the inputs/outputs are also in the species list - checked_reactions = [] - - if not all(isinstance(r, Reaction) for r in reactions): - raise ValueError("A non-reaction object was used as a reaction!") - for r in reactions: - if reactions.count(r) > 1: - warn(f"Reaction {r} may be duplicated in CRN definitions. Duplicates " - "have NOT been removed.") - - checked_reactions.append(r) - #if r not in checked_reactions: - # checked_reactions.append(r) + if reactions.count(r) > 1 and show_warnings: + warn(f"Reaction {r} may be duplicated in CRN definitions. " + f"Duplicates have NOT been removed.") - for s in r.inputs: - if s not in checked_species and warnings: - warn(f"Reaction {repr(r)} contains a species {repr(s)} " - "which is not in the CRN.") - - for s in r.outputs: - if s not in checked_species and warnings: - warn(f"Reaction {repr(r)} contains a species {repr(s)} " - "which is not in the CRN.") - - return checked_species, checked_reactions + for s in species: + if species.count(s) > 1 and show_warnings: + warn(f"Species {s} is duplicated in the CRN definition. " + f"Duplicates have NOT been removed.") + + # check that all species in the reactions are also in the species list and vice versa + unique_species = set(species) + all_species_in_reactions = set(Species.flatten_list([r.species for r in reactions])) + if unique_species != all_species_in_reactions: + species_without_reactions = unique_species - all_species_in_reactions + if species_without_reactions and show_warnings: + warn(f'These Species {list(species_without_reactions)} are not part of any reactions in the CRN!') + unlisted_reactions = all_species_in_reactions - unique_species + if unlisted_reactions and show_warnings: + warn(f'These Species {list(unlisted_reactions)} are not listed in the Species list, but part of the reactions!') + + return reactions, species def __repr__(self): txt = "Species = " @@ -916,13 +127,21 @@ def __repr__(self): txt += "]" return txt - def pretty_print(self, show_rates = True, show_material = True, show_attributes = True, **kwargs): + def pretty_print(self, show_rates = True, show_material = True, show_attributes = True, show_initial_condition = True, **kwargs): + """A more powerful printing function. + + Useful for understanding CRNs but does not return string identifiers. + show_material toggles whether species.material is printed. + show_attributes toggles whether species.attributes is printed + show_rates toggles whether reaction rate functions are printed + """ + txt = f"Species ({len(self.species)}) = "+"{" for sind in range(len(self.species)): s = self.species[sind] - txt += f"{sind}. "+s.pretty_print(show_material = show_material, show_attributes = show_attributes, **kwargs) + ", " + txt += f"{sind}. "+s.pretty_print(show_material = show_material, show_attributes = show_attributes, show_initial_condition = show_initial_condition, **kwargs) + ", " txt = txt[:-2] + '}\n' - txt += f"Reactions ({len(self.reactions)}) = [\n" + txt += f"\nReactions ({len(self.reactions)}) = [\n" for rind in range(len(self.reactions)): r = self.reactions[rind] @@ -930,22 +149,7 @@ def pretty_print(self, show_rates = True, show_material = True, show_attributes txt += "]" return txt - def pyrepr(self): - reactions = [] - for r in self.reactions: - reactions += r.pyrepr() - species = [str(s) for s in self.species] - return species, reactions - - # TODO check whether we need this method - def species_index(self, species: Species): - if len(self.species2index) != len(self.species): - self.species2index = {} - for i in range(len(self.species)): - self.species2index[str(self.species[i])] = i - return self.species2index[str(species)] - - def initial_condition_vector(self, init_cond_dict: Dict[str,float]): + def initial_condition_vector(self, init_cond_dict: Union[Dict[str, float], Dict[Species, float]]): x0 = [0.0] * len(self.species) for idx, s in enumerate(self.species): if s in init_cond_dict: @@ -961,15 +165,19 @@ def get_all_species_containing(self, species: Species, return_as_strings = False raise ValueError('species argument must be an instance of Species!') for s in self.species: - if species == s or (isinstance(s, ComplexSpecies) and species in s.species): + if species in s.get_species(recursive = True): if return_as_strings: return_list.append(repr(s)) else: return_list.append(s) return return_list - #Replaces species with new_species in the entire CRN def replace_species(self, species: Species, new_species: Species): + """Replaces species with new_species in the entire CRN. + + Does not act in place: returns a new CRN. + """ + if not isinstance(species, Species): raise ValueError('species argument must be an instance of Species!') @@ -978,193 +186,128 @@ def replace_species(self, species: Species, new_species: Species): new_species_list = [] for s in self.species: - if s == species: - new_species_list.append(new_species) - elif isinstance(s, ComplexSpecies): - new_s = s.replace_species(species, new_species) - new_species_list.append(new_s) - else: - new_species_list.append(s) + new_s = s.replace_species(species, new_species) + new_species_list.append(new_s) new_reaction_list = [] - for r in self.reactions: new_r = r.replace_species(species, new_species) new_reaction_list.append(new_r) - return ChemicalReactionNetwork(new_species_list, new_reaction_list) + def generate_sbml_model(self, stochastic_model=False, show_warnings = False, **keywords): + """Creates an new SBML model and populates with the species and + reactions in the ChemicalReactionNetwork object - def generate_sbml_model(self, stochastic_model=False, **keywords): - document, model = create_sbml_model(**keywords) - - for s in self.species: - - add_species(model=model, compartment=model.getCompartment(0), - species=s, initial_concentration=s.initial_concentration) + :param stochastic_model: whether the model is stochastic + :param show_warnings: of from check crn validity + :param keywords: extra keywords pass onto create_sbml_model() and add_all_reactions() + :return: tuple: (document,model) SBML objects + """ + ChemicalReactionNetwork.check_crn_validity(self.reactions, self.species, show_warnings=show_warnings) - rxn_count = 0 - for r in self.reactions: - rxn_id = "r" + str(rxn_count) - add_reaction(model, r.inputs, r.input_coefs, r.outputs, - r.output_coefs, rxn_id, r.k, - stochastic = stochastic_model, - propensity_type=r.propensity_type, - propensity_params = r.propensity_params) - rxn_count += 1 + document, model = create_sbml_model(**keywords) + + add_all_species(model=model, species=self.species) - if r.reversible and r.propensity_type == "massaction": - add_reaction(model, r.outputs, r.output_coefs, r.inputs, - r.input_coefs, rxn_id, r.k_r, - stochastic=stochastic_model, - propensity_type=r.propensity_type) - rxn_count += 1 + add_all_reactions(model=model, reactions=self.reactions, stochastic_model=stochastic_model, **keywords) if document.getNumErrors(): warn('SBML model generated has errors. Use document.getErrorLog() to print all errors.') return document, model - def write_sbml_file(self, file_name=None, **keywords): - document, _ = self.generate_sbml_model(**keywords) + def write_sbml_file(self, file_name=None, stochastic_model = False, **keywords) -> bool: + """"Writes CRN object to a SBML file + + :param file_name: name of the file where the SBML model gets written + :param stochastic_model: export an SBML file which ready for stochastic simulations + :param keywords: keywords that passed into generate_sbml_model() + :return: bool, show whether the writing process was successful + """ + + document, _ = self.generate_sbml_model(stochastic_model = stochastic_model, **keywords) sbml_string = libsbml.writeSBMLToString(document) with open(file_name, 'w') as f: f.write(sbml_string) return True - def create_bioscrape_model(self): - from bioscrape.types import Model - - species_list = [] - initial_condition_dict = {} - for s in self.species: - species_list.append(repr(s)) - if s.initial_concentration is None: - initial_condition_dict[repr(s)] = 0 - else: - initial_condition_dict[repr(s)] = s.initial_concentration - - reaction_list = [] - reaction_counter = 0 - rate_list = [] - for rxn in self.reactions: - - reactants = [] - for i in range(len(rxn.inputs)): - reactants += [repr(rxn.inputs[i])]*int(rxn.input_coefs[i]) - products = [] - for i in range(len(rxn.outputs)): - products += [repr(rxn.outputs[i])]*int(rxn.output_coefs[i]) - - prop_type = rxn.propensity_type - if rxn.propensity_params is None: - prop_params = {} - else: - prop_params = {} - for k in rxn.propensity_params: - v = rxn.propensity_params[k] - if isinstance(v, Species): - prop_params[k] = repr(v) - elif isinstance(v, str): - prop_params[k] = v - else: - prop_params[k] = float(v) - - - prop_params['propensity_type'] = rxn.propensity_type - prop_params['k'] = rxn.k - - reaction_list.append((reactants, products, prop_type, - dict(prop_params))) - - if rxn.reversible and rxn.propensity_type == "massaction": - prop_params['k'] = rxn.k_r - reaction_list.append((products, reactants, prop_type, - dict(prop_params))) - elif rxn.reversible: - raise ValueError("Only massaction irreversible reactions are " - "supported for automatic bioscrape simulation." - " Consider creating two seperate reactions.") - model = Model(species = species_list, reactions = reaction_list, - initial_condition_dict = initial_condition_dict) - return model - - def simulate_with_bioscrape(self, timepoints, initial_condition_dict = {}, + def simulate_with_bioscrape(self, timepoints, initial_condition_dict=None, stochastic = False, return_dataframe = True, - safe = False, **kwargs): - ''' - Simulate CRN model with bioscrape (https://github.com/biocircuits/bioscrape). + safe = False): + + """Simulate CRN model with bioscrape (https://github.com/biocircuits/bioscrape). Returns the data for all species as Pandas dataframe. - ''' + """ + result = None + warnings.warn("simulate_with_bioscrape is depricated and will cease working in a future release. Instead, please use simulate_with_bioscrape_via_sbml.") - from bioscrape.simulator import py_simulate_model - m = self.create_bioscrape_model() - m.set_species(initial_condition_dict) - if not stochastic and safe: - safe = False - result = py_simulate_model(timepoints, Model = m, - stochastic = stochastic, - return_dataframe = return_dataframe, - safe = safe) + result = self.simulate_with_bioscrape_via_sbml(timepoints, filename = None, + initial_condition_dict = initial_condition_dict, return_dataframe = return_dataframe, + safe = safe, stochastic = stochastic) return result + def simulate_with_bioscrape_via_sbml(self, timepoints, filename = None, + initial_condition_dict = None, return_dataframe = True, + stochastic = False, safe = False, return_model = False, **kwargs): + """Simulate CRN model with bioscrape via writing a SBML file temporarily. + [Bioscrape on GitHub](https://github.com/biocircuits/bioscrape). - def simulate_with_bioscrape_via_sbml(self, timepoints, file = None, - initial_condition_dict = {}, return_dataframe = True, - stochastic = False, **kwargs): - ''' - Simulate CRN model with bioscrape via writing a SBML file temporarily.(https://github.com/biocircuits/bioscrape). Returns the data for all species as Pandas dataframe. - ''' - if file is None: - self.write_sbml_file(file_name ="temp_sbml_file.xml") - file_name = "temp_sbml_file.xml" - elif isinstance(file, str): - file_name = file - else: - file_name = file.name + """ + result = None + m = None + try: + from bioscrape.simulator import py_simulate_model + from bioscrape.types import Model + + if filename is None: + self.write_sbml_file(file_name ="temp_sbml_file.xml", stochastic_model = stochastic, for_bioscrape = True) + file_name = "temp_sbml_file.xml" + elif isinstance(filename, str): + file_name = filename + else: + raise ValueError(f"filename must be None or a string. Recievied: {filename}") - if 'sbml_warnings' in kwargs: - sbml_warnings = kwargs.get('sbml_warnings') + if 'sbml_warnings' in kwargs: + sbml_warnings = kwargs.get('sbml_warnings') + else: + sbml_warnings = False + m = Model(sbml_filename = file_name, sbml_warnings = sbml_warnings) + # m.write_bioscrape_xml('temp_bs'+ file_name + '.xml') # Uncomment if you want a bioscrape XML written as well. + if initial_condition_dict is not None: + m.set_species(initial_condition_dict) + result = py_simulate_model(timepoints, Model = m, stochastic = stochastic, safe = safe, + return_dataframe = return_dataframe) + except ModuleNotFoundError: + warnings.warn('bioscrape was not found, please install bioscrape') + + if return_model: + return result, m else: - sbml_warnings = False - m = bioscrape.types.Model(sbml_filename = file_name, sbml_warnings = sbml_warnings) - # m.write_bioscrape_xml('temp_bs'+ file_name + '.xml') # Uncomment if you want a bioscrape XML written as well. - m.set_species(initial_condition_dict) - result = bioscrape.simulator.py_simulate_model(timepoints, Model = m, - stochastic = stochastic, - return_dataframe = return_dataframe) - return result, m - + return result - def runsim_roadrunner(self, timepoints, filename, species_to_plot = []): - ''' - To simulate using roadrunner. + def runsim_roadrunner(self, timepoints, filename, species_to_plot = None): + """To simulate using roadrunner. Arguments: timepoints: The array of time points to run the simulation for. filename: Name of the SBML file to simulate - Returns the results array as returned by RoadRunner. + + Returns the results array as returned by RoadRunner. + Refer to the libRoadRunner simulator library documentation - for details on simulation results: http://libroadrunner.org/ + for details on simulation results: (http://libroadrunner.org/)[http://libroadrunner.org/] NOTE : Needs roadrunner package installed to simulate. - ''' + """ + res_ar = None try: import roadrunner - except: - raise ModuleNotFoundError - rr = roadrunner.RoadRunner(filename) - result = rr.simulate(timepoints[0],timepoints[-1],len(timepoints)) - res_ar = np.array(result) + rr = roadrunner.RoadRunner(filename) + result = rr.simulate(timepoints[0],timepoints[-1],len(timepoints)) + # TODO fix roadrunner output + res_ar = result + except ModuleNotFoundError: + warnings.warn('libroadrunner was not found, please install libroadrunner') return res_ar - -#Helper function to flatten lists -def flatten_list(in_list): - out_list = [] - for element in in_list: - if isinstance(element, list): - out_list += flatten_list(element) - else: - out_list += [element] - return out_list diff --git a/biocrnpyler/component.py b/biocrnpyler/component.py index ca4f7acf..b147497f 100644 --- a/biocrnpyler/component.py +++ b/biocrnpyler/component.py @@ -1,30 +1,51 @@ + # Copyright (c) 2019, Build-A-Cell. All rights reserved. # See LICENSE file in the project root directory for details. -from warnings import warn as pywarn -from .chemical_reaction_network import Species, ComplexSpecies, Reaction -from .parameter import Parameter +import copy +from numbers import Real from typing import List, Union +from warnings import warn - -def warn(txt): - pywarn(txt) +from .global_mechanism import GlobalMechanism +from .mechanism import Mechanism +from .parameter import Parameter, ParameterDatabase +from .species import Species -# Component class for core components class Component(object): + """Component class for core components. + These subclasses of Component represent different kinds of biomolecules. + + This class must be Subclassed to provide functionality with the functions get_species and get_reactions overwritten. + """ def __init__(self, name: Union[str, Species], - mechanisms={}, # custom mechanisms + mechanisms=None, # custom mechanisms parameters=None, # parameter configuration - parameter_file=None, #custom parameter file + parameter_file=None, # custom parameter file mixture=None, - attributes=[], - initial_conc=0, - parameter_warnings = True, + attributes=None, + initial_conc=None, + initial_condition_dictionary=None, **keywords # parameter keywords ): - + """Initializes a Component object. + + :param name: + :param mechanisms: + :param parameters: + :param parameter_file: + :param mixture: + :param attributes: + :param initial_conc: + :param initial_condition_dictionary: + :param keywords: + """ + if mechanisms is None: + self.mechanisms = {} + else: + self.mechanisms = mechanisms if isinstance(name, Species): self.name = name.name elif isinstance(name, str): @@ -32,41 +53,25 @@ def __init__(self, name: Union[str, Species], else: raise ValueError("name must be a Species or string") - # Toggles whether warnings will be sent when parameters aren't found by - # the default name. - self.set_parameter_warnings(parameter_warnings) - self._initial_conc = initial_conc - - # Check to see if a subclass constructor has overwritten default - # mechanisms. # Attributes can be used to store key words like protein deg-tags for # components that mimic CRN species. self.attributes = [] self.set_attributes(attributes) - # Check to see if a subclass constructor has overwritten default - # mechanisms. - if not hasattr(self, 'default_mechanisms'): - self.default_mechanisms = {} - - self.custom_mechanisms = {} - self.mechanisms = {} if mixture is not None: - mixture_mechanisms = mixture.mechanisms + self.set_mixture(mixture) else: - mixture_mechanisms = {} - self.update_mechanisms(mechanisms=mechanisms, - mixture_mechanisms=mixture_mechanisms) + self.set_mixture(None) - self.custom_parameters = {} - self.parameters = {} - if mixture is not None: - mixture_parameters = mixture.parameters - else: - mixture_parameters = {} + self.parameter_database = ParameterDatabase(parameter_file=parameter_file, parameter_dictionary=parameters) - parameters = Parameter.create_parameter_dictionary(parameters, parameter_file) - self.update_parameters(mixture_parameters=mixture_parameters, parameters=parameters) + # A component can store an initial concentration used for self.get_species() species + self._initial_conc = initial_conc + # Components can also store initial conditions, just like Mixtures + if initial_condition_dictionary is None: + self.initial_condition_dictionary = {} + else: + self.initial_condition_dictionary = dict(initial_condition_dictionary) @property def initial_concentration(self) -> float: @@ -81,21 +86,35 @@ def initial_concentration(self, initial_conc: float): else: self._initial_conc = initial_conc + def set_mixture(self, mixture) -> None: + """Set the mixture the Component is in. + + :param mixture: + :return: None + """ + self.mixture = mixture + # TODO implement as an abstractmethod def get_species(self) -> None: - """ - the child class should implement this method + """The subclasses should implement this method! + :return: None """ - #warn(f"get_species is not defined for component {self.name}, None returned.") return None - #If allows species to be set from strings, species, or Components - def set_species(self, species: Union[Species, str], material_type = None, attributes = None): + def set_species(self, species: Union[Species, str], material_type=None, attributes=None) -> Species: + """Helper function that allows species to be set from strings, species, or Components + + :param species: Species, str, Component + :param material_type: + :param attributes: + :return: Species + """ + if isinstance(species, Species): return species elif isinstance(species, str): - return Species(name = species, material_type = material_type, attributes = attributes) + return Species(name=species, material_type=material_type, attributes=attributes) elif isinstance(species, Component) and species.get_species() is not None: return species.get_species() else: @@ -118,136 +137,139 @@ def add_attribute(self, attribute: str): else: raise Warning(f"Component {self.name} has no internal species and therefore no attributes") - #This function gives Components their own parameter dictionary. By default, components get all the parameters from Mixture - #Parameters passed in from mixture are superceded by parameters passed in the parameters keyword - #parameters already saved as custom parameters also supersede parameters from the Mixture - #In other words, the component remembers custom changes to parameters and mixture parameters will never overwrite those changes - #Mixture parameters are only ever used by default when no other component-level parameter has ever been given with the same key. - #the overwrite_custom_parameters keyword lets this function overwrite the existing custom Component-level parameters, - def update_parameters(self, mixture_parameters = {}, parameters = {}, - overwrite_custom_parameters = True): + def update_parameters(self, parameter_file = None, parameters = None, parameter_database = None, overwrite_parameters = True): + """Updates the ParameterDatabase inside a Component + + Possible inputs: + parameter_file (string) + parameters (dict) + parameter_database (ParameterDatabase) + """ + + if parameter_file is not None: + self.parameter_database.load_parameters_from_file(parameter_file, overwrite_parameters = overwrite_parameters) + + if parameters is not None: + self.parameter_database.load_parameters_from_dictionary(parameters, overwrite_parameters = overwrite_parameters) + if parameter_database is not None: + self.parameter_database.load_parameters_from_database(parameter_database, overwrite_parameters = overwrite_parameters) - for p in parameters: - if overwrite_custom_parameters or p not in self.custom_parameters: - self.parameters[p] = parameters[p] - if p in self.custom_parameters: - self.custom_parameters[p] = parameters[p] + def get_mechanism(self, mechanism_type, optional_mechanism=False): + """Searches the Component for a Mechanism of the correct type. + If the Component does not have the mechanism, searches the Components' Mixture for the Mechanism. - for p in mixture_parameters: - if p not in self.parameters: - self.parameters[p] = mixture_parameters[p] + :param mechanism_type: + :param optional_mechanism: toggles whether an error is thrown if no mechanism is found + :return: + """ + if not isinstance(mechanism_type, str): + raise TypeError(f"mechanism_type must be a string. Received {mechanism_type}.") + + mech = None + if mechanism_type in self.mechanisms: + return self.mechanisms[mechanism_type] + elif self.mixture is not None: + mech = self.mixture.get_mechanism(mechanism_type) + if mech is None and not optional_mechanism: + raise KeyError(f"Unable to find mechanism of type {mechanism_type} in Component {self} or Mixture {self.mixture}.") + else: + return mech - def update_mechanisms(self, mixture_mechanisms={}, mechanisms={}, overwrite_custom_mechanisms=True): + @property + def mechanisms(self): + return self._mechanisms + @mechanisms.setter + def mechanisms(self, mechanisms): + self._mechanisms = {} if isinstance(mechanisms, dict): for mech_type in mechanisms: - if overwrite_custom_mechanisms \ - or mech_type not in self.custom_mechanisms: - self.mechanisms[mech_type] = mechanisms[mech_type] - self.custom_mechanisms[mech_type] = mechanisms[mech_type] + self.add_mechanism(mechanisms[mech_type], mech_type, overwrite = True) elif isinstance(mechanisms, list): for mech in mechanisms: - if overwrite_custom_mechanisms \ - or mech not in self.custom_mechanisms: - self.mechanisms[mech.mechanism_type] = mech - self.custom_mechanisms[mech.mechanism_type] = mech + self.add_mechanism(mech, overwrite = True) + + def add_mechanism(self, mechanism: Mechanism, mech_type=None, overwrite=False, optional_mechanism=False): + """adds a mechanism of type mech_type to the Component Mechanism dictionary. + + :param mechanism: + :param mech_type: + :param overwrite: toggles whether the mechanism is added overwriting any mechanism with the same key. + :param optional_mechanism: toggles whether an error is thrown if a Mechanism is added that conflicts with an exising Mechanism + :return: + """ + if not hasattr(self, "_mechanisms"): + self._mechanisms = {} + + if not isinstance(mechanism, Mechanism): + raise TypeError(f"mechanism must be a Mechanism. Received {mechanism}.") + + if mech_type is None: + mech_type = mechanism.mechanism_type + if not isinstance(mech_type, str): + raise TypeError(f"mechanism keys must be strings. Received {mech_type}") + + if mech_type not in self._mechanisms or overwrite: + self._mechanisms[mech_type] = copy.deepcopy(mechanism) + elif not optional_mechanism: + raise ValueError(f"mech_type {mech_type} already in component {self}. To overwrite, use keyword overwrite = True.") + + def add_mechanisms(self, mechanisms: Union[Mechanism, GlobalMechanism], overwrite=False, optional_mechanism=False): + """This function adds a list or dictionary of mechanisms to the mixture. + + :param mechanisms: Can take both GlobalMechanisms and Mechanisms + :param overwrite: toggles whether the mechanism is added overwriting any mechanism with the same key. + :param optional_mechanism: toggles whether an error is thrown if a Mechanism is added that conflicts with an exising Mechanism + :return: + """ + + if isinstance(mechanisms, Mechanism): + self.add_mechanism(mechanisms, overwrite=overwrite, optional_mechanism=optional_mechanism) + elif isinstance(mechanisms, dict): + for mech_type in mechanisms: + self.add_mechanism(mechanisms[mech_type], mech_type, overwrite=overwrite, optional_mechanism=optional_mechanism) + elif isinstance(mechanisms, list): + for mech in mechanisms: + self.add_mechanism(mech, overwrite=overwrite, optional_mechanism=optional_mechanism) else: - raise ValueError("Mechanisms must be passed as a list of " - "instantiated objects or a dictionary " - "{mechanism_type:mechanism instance}") - - # The mechanisms used during compilation are stored as their own - # dictionary - for mech_type in self.default_mechanisms: - if mech_type not in self.custom_mechanisms: - self.mechanisms[mech_type] = self.default_mechanisms[mech_type] - - for mech_type in mixture_mechanisms: - if mech_type not in self.custom_mechanisms: - self.mechanisms[mech_type] = mixture_mechanisms[mech_type] - - - - - - - #Set get_parameter property - def set_parameter_warnings(self, parameter_warnings): - self.parameter_warnings = parameter_warnings - - # Get Parameter Hierarchy: - def get_parameter(self, param_name: str, part_id=None, mechanism=None): - return_val = None - warning_txt = None - - # Ideally parameters can be found - # (mechanism.name/mechanism_type, part_id, param_name) --> val - if part_id is not None and mechanism is not None: - if mechanism is not None \ - and (mechanism.name, part_id, param_name) in self.parameters: - return_val = self.parameters[(mechanism.name, - part_id, param_name)] - elif mechanism is not None \ - and (mechanism.mechanism_type, part_id, param_name) \ - in self.parameters: - return_val = self.parameters[(mechanism.mechanism_type, part_id, - param_name)] - - # Next try (part_id, param_name) --> val - if part_id is not None and return_val is None: - if (part_id, param_name) in self.parameters: - return_val = self.parameters[(part_id, param_name)] - - if mechanism is not None: - warning_txt = ("No Parameter found with " - f"param_name={param_name} and part_id={part_id} and " - f"mechanism={repr(mechanism)}. Parameter found under " - f"the key (part_id, param_name)=({part_id}, " - f"{param_name}).") - # Next try (Mechanism.name/mechanism_type, param_name) --> val - if mechanism is not None and return_val is None: - if (mechanism.name, param_name) in self.parameters: - return_val = self.parameters[((mechanism.name, param_name))] - if part_id is not None: - warning_txt = ("No Parameter found with " - f"param_name={param_name} and part_id={part_id} and " - f"mechanism={repr(mechanism)}. Parameter found under " - f"the key (mechanism.name, " - f"param_name)=({mechanism.name}, {param_name})") - elif (mechanism.mechanism_type, param_name) in self.parameters: - return_val = self.parameters[(mechanism.mechanism_type, - param_name)] - if part_id is not None: - warning_txt = ("No Parameter found with " - f"param_name={param_name} and part_id={part_id} and " - f"mechanism={repr(mechanism)}. Parameter found under " - f"the key (mechanism.name, " - f"param_name)=({mechanism.name}, {param_name})") - # Finally try (param_name) --> return val - if param_name in self.parameters and return_val is None: - return_val = self.parameters[param_name] - if mechanism is not None or part_id is not None: - warning_txt = (f"No parameter found with " - f"param_name={param_name} and part_id={part_id} " - f"and mechanism={repr(mechanism)}. Parameter " - f"found under the key param_name={param_name}") - if return_val is None: + raise ValueError(f"add_mechanisms expected a list of Mechanisms. Received {mechanisms}") + + def get_parameter(self, param_name: str, part_id=None, mechanism=None, return_numerical=False) -> Union[Parameter, Real]: + """Get a parameter from different objects that hold parameters. + + Hierarchy: + 1. tries to find the Parameter in Component.parameter_database + 2. tries to find the parameter in Component.mixture.parameter_database + + :param param_name: + :param part_id: + :param mechanism: + :param return_numerical: numerical value or the parameter object is returned + :return: Parameter object or a Real number + """ + # Try the Component ParameterDatabase + param = self.parameter_database.find_parameter(mechanism, part_id, param_name) + + # Next try the Mixture ParameterDatabase + if param is None and self.mixture is not None: + param = self.mixture.get_parameter(mechanism, part_id, param_name) + + if param is None: raise ValueError("No parameters can be found that match the " "(mechanism, part_id, " - f"param_name)=({repr(mechanism)}, {part_id}, " - f"{param_name})") - + f"param_name)=({repr(mechanism)}, {part_id}, " + f"{param_name})") + elif return_numerical and isinstance(param, Parameter): + return param.value else: - if warning_txt is not None and self.parameter_warnings: - warn(warning_txt) - return return_val + return param # TODO implement abstractmethod - def update_species(self) -> List: - """ - the child class should implement this method + def update_species(self) -> List[Species]: + """The subclasses should implement this method! + :return: empty list """ species = [] @@ -255,15 +277,51 @@ def update_species(self) -> List: return species # TODO implement abstractmethod - def update_reactions(self) -> List: - """ - the child class should implement this method + def update_reactions(self) -> List[Species]: + """The subclasses should implement this method! + :return: empty list """ reactions = [] warn("Unsubclassed update_reactions called for " + repr(self)) return reactions + def get_initial_condition(self, s): + """Tries to find an initial condition of species s using the parameter hierarchy + + 1. mixture.name, repr(s) in self.initial_condition_dictionary + 2. repr(s) in self.initial_condition_dictionary + 3. If s == self.get_species and self.initial_con is not None: self.initial_conc + 4. IF s == self.get_species(): mixture.name, self.name in initial_condition_dictionary + 5. IF s == self.get_species(): self.name in initial_condition_dictionary + Repeat 1-2, 4-5 in self.parameter_database + Note: Mixture will also repeat this same order in it's own initial_condition_dictionary and ParameterDatabase after Component. + """ + # First try all conditions in initial_condition_dictionary + if (self.mixture is not None and (self.mixture.name, repr(s)) in self.initial_condition_dictionary): + return self.initial_condition_dictionary[(self.mixture.name, repr(s))] + elif repr(s) in self.initial_condition_dictionary: + return self.initial_condition_dictionary[repr(s)] + # Then try all conditions using self.name (if s is self.get_species()) + elif s == self.get_species(): + if self.initial_concentration is not None: + return self.initial_concentration + elif self.mixture is not None and (self.mixture.name, self.name) in self.initial_condition_dictionary: + return self.initial_condition_dictionary[(self.mixture.name, self.name)] + elif self.name in self.initial_condition_dictionary: + return self.initial_condition_dictionary[(self.mixture.name, self.name)] + # Then try above in self.parameter_database + elif self.mixture is not None and self.parameter_database.find_parameter(None, self.mixture.name, repr(s)) is not None: + return self.parameter_database.find_parameter(None, self.mixture.name, repr(s)).value + elif self.parameter_database.find_parameter(None, None, repr(s)) is not None: + return self.parameter_database.find_parameter(None, None, repr(s)).value + elif s == self.get_species(): + if self.mixture is not None and self.parameter_database.find_parameter(None, self.mixture.name, self.name) is not None: + return self.parameter_database.find_parameter(None, self.mixture.name, self.name).value + elif self.parameter_database.find_parameter(None, None, self.name) is not None: + return self.parameter_database.find_parameter(None, None, self.name).value + else: + return None + def __repr__(self): return type(self).__name__ + ": " + self.name - diff --git a/biocrnpyler/components_basic.py b/biocrnpyler/components_basic.py index bf817e18..681d4db5 100644 --- a/biocrnpyler/components_basic.py +++ b/biocrnpyler/components_basic.py @@ -1,246 +1,257 @@ -from .component import * -from .chemical_reaction_network import Species, ComplexSpecies, OrderedComplexSpecies -from .mechanism import * -from .mechanisms_binding import * -# These subclasses of Component represent different kinds of biomolecules. -class DNA(Component): - """DNA class - - The DNA class is used to represent a DNA sequence that has a given - length. Its main purpose is as the parent object for DNA - fragments and DNA assemblies. - - Note: for initialization of members of this class, the arguments - should be as follows: - - DNA(name, length, [mechanisms], [config_file], [prefix]) +# Copyright (c) 2019, Build-A-Cell. All rights reserved. +# See LICENSE file in the project root directory for details. - DNAtype(name, required_arguments, [length], [mechanisms], - [config_file], [prefix], [optional_arguments]) +from typing import List, Union - DNAelement(name, required_arguments, [length], [mechanisms], - [config_file], [optional_arguments]) +from .component import Component +from .reaction import Reaction +from .species import Complex, Species - Data attributes - --------------- - name Name of the sequence (str) - length Length of the sequence (int) - assy DNA assembly that we are part of - mechanisms Local mechanisms for this component (overrides defaults) - parameters Parameter dictionary for the DNA element +class DNA(Component): + """The DNA class is used to represent a DNA sequence that has a given length. + Produces no reactions. """ - def __init__( - self, name: str, length=0, # positional arguments - mechanisms={}, # custom mechanisms - parameters={}, # customized parameters - attributes=[], - initial_conc=None, - parameter_warnings = True, - **keywords - ): - self.species = Species(name, material_type="dna", - attributes=list(attributes)) - self._length = length - Component.__init__(self=self, name=name, mechanisms=mechanisms, - parameters=parameters, attributes=attributes, - initial_conc=initial_conc, - parameter_warnings = parameter_warnings, **keywords) + def __init__(self, name: str, length=0, attributes=None, **keywords): + """Initialize a DNA object to store DNA related information. - def get_species(self): + :param name: Name of the sequence (str) + :param length: length of the basepairs (int) + :param attributes: Species attribute + :param keywords: pass into the parent's (Component) initializer + """ + self.species = self.set_species(name, material_type="dna", attributes=attributes) + self.length = length + Component.__init__(self=self, name=name, **keywords) + + def get_species(self) -> Species: return self.species - def update_species(self): + def update_species(self) -> List[Species]: species = [self.get_species()] return species - def update_reactions(self): + def update_reactions(self) -> List: return [] @property def length(self): - return self._length + return self._length @length.setter def length(self, dna_length): - if dna_length >= 0: + if dna_length is None: + self._length = dna_length + elif dna_length >= 0 and isinstance(dna_length, int): self._length = dna_length else: raise ValueError("Length cannot be negative!") class RNA(Component): - def __init__( - self, name: str, length=0, # positional arguments - mechanisms={}, # custom mechanisms - parameters={}, # customized parameters - attributes=[], - initial_conc=None, - **keywords - ): + """A class to represent Components made of RNA. Produces no reactions.""" + + def __init__(self, name: str, length=0, attributes=None, **keywords): + """Initialize a RNA object to store RNA related information + + :param name: name of the rna + :param length: number of basepairs (int) + :param attributes: Species attribute + :param keywords: pass into the parent's (Component) initializer + """ + self.length = length - self.species = Species(name, material_type="rna", - attributes=list(attributes)) - Component.__init__(self=self, name=name, mechanisms=mechanisms, - parameters=parameters, attributes=attributes, - initial_conc=initial_conc, **keywords) + self.species = self.set_species(name, material_type="rna", + attributes=attributes) + Component.__init__(self=self, name=name, **keywords) - def get_species(self): + def get_species(self) -> Species: return self.species - def update_species(self): + def update_species(self) -> List[Species]: species = [self.get_species()] return species - def update_reactions(self): + def update_reactions(self) -> List: return [] class Protein(Component): - def __init__( - self, name: str, length=0, # positional arguments - mechanisms={}, # custom mechanisms - parameters={}, # customized parameters - attributes=[], - initial_conc=None, - **keywords - ): + """A class to represent Components made of Protein. Produces no reactions.""" + + def __init__(self, name: str, length=0, attributes=None, **keywords): + """Initialize a Protein object to store Protein related information. + + :param name: name of the protein + :param length: length of the protein in number of amino acids + :param attributes: Species attribute + :param keywords: pass into the parent's (Component) initializer + """ + self.length = length - self.species = Species(name, material_type="protein", - attributes=attributes) + self.species = self.set_species(name, material_type="protein", + attributes=attributes) - Component.__init__(self=self, name=name, mechanisms=mechanisms, - parameters=parameters, attributes=attributes, - initial_conc=initial_conc, **keywords) + Component.__init__(self=self, name=name, **keywords) - def get_species(self): + def get_species(self) -> Species: return self.species - def update_species(self): + def update_species(self) -> List[Species]: species = [self.get_species()] return species - def update_reactions(self): + def update_reactions(self) -> List: return [] class ChemicalComplex(Component): - """ - A complex forms when two or more species bind together - Complexes inherit the attributes of their species - """ - def __init__( - self, species, # positional arguments - name = None, #Override the default naming convention for a complex - mechanisms={}, # custom mechanisms - parameters={}, # customized parameters, - attributes=[], - initial_conc=None, - material_type = "complex", - **keywords - ): - - if len(species) < 2 or not isinstance(species, list): - raise ValueError("Species must be a list of Species, strings, Component objects.") - - self.internal_species = [] #a list of species inside the complex + """A complex forms when two or more species bind together Complexes inherit the attributes of their species.""" - for s in species: - self.internal_species.append(self.set_species(s)) + def __init__(self, species: List[Species], name: str=None, material_type="complex", + attributes=None, **keywords): + """Initialize a ChemicalComplex object to store ChemicalComplex related information. - self.species = ComplexSpecies(species = self.internal_species, name = name, material_type=material_type, attributes=list(attributes)) + :param species: list of species inside a complex + :param name: name of the complex + :param material_type: option to rename the material_type, default: complex + :param attributes: Species attribute + :param keywords: pass into the parent's (Component) initializer + """ + if not isinstance(species, list) or len(species) < 2: + raise ValueError(f"Invalid Species {species}. Species must be a list of Species, strings, Component objects.") + self.internal_species = [] # a list of species inside the complex + + for s in species: + self.internal_species.append(self.set_species(s)) + if attributes is None: + attributes = [] + self.species = Complex(species=self.internal_species, name=name, material_type=material_type, attributes=attributes) + if name is None: name = self.species.name - Component.__init__(self=self, name=name, mechanisms=mechanisms, - parameters=parameters, attributes=attributes, - initial_conc=initial_conc, **keywords) + Component.__init__(self=self, name=name, **keywords) - def get_species(self): + def get_species(self) -> List[Species]: return self.species def update_species(self) -> List[Species]: - mech_b = self.mechanisms['binding'] - - species = mech_b.update_species(self.internal_species, complex_species = self.get_species(), component = self, part_id = self.name) + mech_b = self.get_mechanism('binding') + bindee = self.internal_species[0] + binder = self.internal_species[1:] + species = mech_b.update_species(binder, bindee, complex_species=self.get_species(), component=self, part_id=self.name) return species def update_reactions(self) -> List[Reaction]: - mech_b = self.mechanisms['binding'] - - reactions = mech_b.update_reactions(self.internal_species, complex_species = self.get_species(), component = self, part_id = self.name) + mech_b = self.get_mechanism('binding') + bindee = self.internal_species[0] + binder = self.internal_species[1:] + reactions = mech_b.update_reactions(binder, bindee, complex_species=self.get_species(), component=self, part_id=self.name) return reactions + class Enzyme(Component): - def __init__(self, enzyme, substrate, product, **keywords): + """A class to represent Enzymes. + + Assumes the enzyme converts a single substrate to a single product. + Uses a mechanism called "catalysis" + """ + def __init__(self, enzyme: Union[Species, str, Component], + substrate: Union[Species, str, Component], + product: Union[Species,str, Component], attributes=None, **keywords): + """Initialize an Enzyme object to store Enzyme related information. + + :param enzyme: name of the enzyme, reference to an Species or Component + :param substrate: name of the enzyme, reference to an Species or Component + :param product: name of the product, reference to an Species or Component + :param attributes: Species attribute + :param keywords: pass into the parent's (Component) initializer + """ # ENZYME NAME - self.enzyme = self.set_species(enzyme, material_type = 'protein') + self.enzyme = self.set_species(enzyme, material_type='protein', attributes=attributes) # SUBSTRATE if substrate is None: self.substrate = None else: self.substrate = self.set_species(substrate) + + # PRODUCT if product is None: self.product = None else: self.product = self.set_species(product) - - Component.__init__(self = self, name = self.enzyme.name, **keywords) + Component.__init__(self=self, name=self.enzyme.name, **keywords) def get_species(self): return self.enzyme def update_species(self): - mech_cat = self.mechanisms['catalysis'] + mech_cat = self.get_mechanism('catalysis') return mech_cat.update_species(self.enzyme, self.substrate, self.product) - - + def update_reactions(self): - mech_cat = self.mechanisms['catalysis'] + mech_cat = self.get_mechanism('catalysis') - return mech_cat.update_reactions(self.enzyme, self.substrate, self.product, component = self, part_id = self.name) + return mech_cat.update_reactions(self.enzyme, self.substrate, self.product, component=self, part_id=self.name) class MultiEnzyme(Component): - def __init__(self, enzyme, substrates, products, **keywords): + """A class to represent Enzymes with multiple substrates and products. + + Assumes the enzyme converts all substrates to a all products at once. + For example: S1 + S2 + E --> P1 + P2 + E. + For enzymes with multiple enzymatic reactions, create multiple Enzyme Components with the same internal species. + Uses a mechanism called "catalysis" + """ + def __init__(self, enzyme: Union[Species, str, Component], + substrates: List[Union[Species, str, Component]], + products: List[Union[Species, str, Component]], attributes=None, **keywords): + """Initialize an MultiEnzyme object to store MultiEnzyme related information. + + :param enzyme: name of the enzyme, reference to an Species or Component + :param substrate: list of (name of the enzyme, reference to an Species or Component) + :param product: list of (name of the product, reference to an Species or Component) + :param attributes: Species attribute + :param keywords: pass into the parent's (Component) initializer + """ # ENZYME NAME - self.enzyme = self.set_species(enzyme, material_type = 'protein') - - # SUBSTRATE + self.enzyme = self.set_species(enzyme, material_type='protein', attributes=attributes) + + # SUBSTRATE(s) self.substrates = [] for substrate in substrates: self.substrates.append(self.set_species(substrate)) + # PRODUCT(s) self.products = [] for product in products: self.products.append(self.set_species(product)) - Component.__init__(self = self, name = self.enzyme.name, **keywords) + Component.__init__(self=self, name=self.enzyme.name, **keywords) def get_species(self): return self.enzyme def update_species(self): - mech_cat = self.mechanisms['catalysis'] + mech_cat = self.get_mechanism('catalysis') - return mech_cat.update_species(self.enzyme, self.substrates, self.products) - - - def update_reactions(self): - mech_cat = self.mechanisms['catalysis'] + return mech_cat.update_species(self.enzyme, self.substrates, self.products) - return mech_cat.update_reactions(self.enzyme, self.substrates, self.products, component = self, part_id = self.name) + def update_reactions(self): + mech_cat = self.get_mechanism('catalysis') + return mech_cat.update_reactions(self.enzyme, self.substrates, self.products, component=self, part_id=self.name) diff --git a/biocrnpyler/components_dcas9.py b/biocrnpyler/components_dcas9.py deleted file mode 100644 index 5da7ba00..00000000 --- a/biocrnpyler/components_dcas9.py +++ /dev/null @@ -1,56 +0,0 @@ -# Copyright (c) 2019, Build-A-Cell. All rights reserved. -# See LICENSE file in the project root directory for details. - -from .component import Component -from .components_basic import DNA, RNA, Protein -from .mechanisms_binding import Reversible_Bimolecular_Binding -from .chemical_reaction_network import Species, ComplexSpecies - - -class guideRNA(RNA): - def __init__(self, guide_name, dCas9 = "dCas9", **keywords): - - if isinstance(dCas9, Species): - self.dCas = dCas9 - elif isinstance(dCas9, str): - self.dCas = Species(dCas9, material_type ="protein") - elif isinstance(dCas9, Component) and dCas9.get_species() is not None: - self.dCas = dCas9.get_species() - else: - raise ValueError("dCas9 parameter must be a " - "chemical_reaction_network.species, Component " - "with get_species(), or a string") - - - self.default_mechanisms = { - "dCas9_binding" : - Reversible_Bimolecular_Binding(name = "dCas9_binding", - mechanism_type = "bimolecular binding") - } - - RNA.__init__(self, name = guide_name, **keywords) - self.gRNA = self.get_species() - - def get_dCasComplex(self): - binding_species = self.mechanisms['dCas9_binding'].update_species(self.gRNA, self.dCas) - - complexS = None - for c in [b for b in binding_species if isinstance(b, ComplexSpecies)]: - if self.gRNA in c and self.dCas in c: - if complexS is None: - complexS = c - else: - raise ValueError("dCas9_binding mechanisms " - f"{self.mechanisms['dCas9_binding'].name} returned " - "multiple complexes containing dCas9 and the guideRNA. Unclear which is correct." ) - - return complexS - - def update_species(self): - species = [self.gRNA, self.dCas] - species += self.mechanisms['dCas9_binding'].update_species(self.gRNA, self.dCas, component = self, part_id = self.name) - return species - - def update_reactions(self): - rxns = self.mechanisms['dCas9_binding'].update_reactions(self.gRNA, self.dCas, component = self, part_id = self.name) - return rxns diff --git a/biocrnpyler/crnlab.py b/biocrnpyler/crnlab.py index de70b8fb..1b7f43af 100644 --- a/biocrnpyler/crnlab.py +++ b/biocrnpyler/crnlab.py @@ -1,15 +1,16 @@ # Copyright (c) 2019, Build-A-Cell. All rights reserved. # See LICENSE file in the project root directory for details. -# from .extracts import * -from .mixture import Mixture -from .dna_assembly import DNAassembly -from .mixtures_cell import * -from .mixtures_extract import * -import libsbml -import warnings + import inspect import sys +import warnings + +import libsbml + +from .dna_assembly import DNAassembly +from .mixtures_extract import Mixture + class CRNLab(object): ''' diff --git a/biocrnpyler/dna_assembly.py b/biocrnpyler/dna_assembly.py index 9acfa0f4..c770068a 100644 --- a/biocrnpyler/dna_assembly.py +++ b/biocrnpyler/dna_assembly.py @@ -1,106 +1,168 @@ # Copyright (c) 2019, Build-A-Cell. All rights reserved. # See LICENSE file in the project root directory for details. +import copy +from typing import List, Union + from .component import Component from .components_basic import DNA, RNA, Protein -from .chemical_reaction_network import ComplexSpecies, Species -from .mechanisms_binding import One_Step_Cooperative_Binding, Combinatorial_Cooperative_Binding -from warnings import warn as pywarn -import itertools as it -import numpy as np -from .dna_assembly_promoter import * -from .dna_assembly_rbs import * - -def warn(txt): - pywarn(txt) +from .dna_part_promoter import Promoter +from .dna_part_rbs import RBS +from .mechanism import Mechanism +from .mixture import Mixture +from .parameter import ParameterDatabase +from .reaction import Reaction +from .species import Species class DNAassembly(DNA): - def __init__(self, name: str, dna = None, promoter = None, transcript = None, - rbs = None, protein = None, length = None, - attributes = [], mechanisms = {}, parameters = {}, initial_conc = None, - parameter_warnings = True, **keywords): + """A class that contains a Promoter, RBS, transcript, and protein.""" + + def __init__(self, name: str, dna=None, promoter=None, transcript=None, + rbs=None, protein=None, length=None, + attributes=None, mechanisms=None, parameters=None, initial_conc=None, **keywords): + """ + Note: + If transcript is None and protein is not None, + the DNAassembly will use its transcription mechanisms to produce the protein. + This is used by Expression Mixtures. + :param name: name of the DNA assembly + :param dna: + :param promoter: + :param transcript: + :param rbs: + :param protein: + :param length: + :param attributes: + :param mechanisms: + :param parameters: + :param initial_conc: + :param keywords: passed into the parent object (DNA) + """ self.promoter = None self.rbs = None self.transcript = None self.initial_concentration = initial_conc self.name = name + + # This has to be called at the end so mechanisms are set for the promoter, RBS, etc. + DNA.__init__(self, name, length=length, mechanisms=mechanisms, + parameters=parameters, initial_conc=initial_conc, + attributes=attributes, **keywords) - DNA.__init__(self, name, length = length, mechanisms = mechanisms, - parameters = parameters, initial_conc = initial_conc, - parameter_warnings = parameter_warnings, - attributes = list(attributes), **keywords) - - self.update_dna(dna, attributes = list(attributes)) + self.update_dna(dna, attributes=attributes) self.update_transcript(transcript) self.update_protein(protein) - self.update_promoter(promoter, transcript = self.transcript) - self.update_rbs(rbs, transcript = self.transcript, - protein = self.protein) - - self.set_parameter_warnings(parameter_warnings) + self.update_promoter(promoter, transcript=self.transcript, protein=self.protein) + self.update_rbs(rbs, transcript=self.transcript, protein=self.protein) - + def set_mixture(self, mixture: Mixture) -> None: + """Set the mixture the Component is in. - def set_parameter_warnings(self, parameter_warnings): - self.parameter_warnings = parameter_warnings - - if self.parameter_warnings is not None: - if self.promoter is not None: - self.promoter.set_parameter_warnings(parameter_warnings) - if self.rbs is not None: - self.rbs.set_parameter_warnings(parameter_warnings) + :param mixture: reference to a Mixture instance + :return: None + """ + self.mixture = mixture + if self.promoter is not None: + self.promoter.set_mixture(mixture) + if self.rbs is not None: + self.rbs.set_mixture(mixture) + def update_dna(self, dna: Union[None, DNA, str], attributes=None) -> None: + """sets up the dna attribute with a valid DNA instance. - def update_dna(self, dna, attributes = None): + :param dna: name of a dna sequence or a DNA instance + :param attributes: Species attribute + :return: None + """ if dna is None: - self.dna = self.set_species(self.name, material_type = "dna", attributes = attributes) + self.dna = self.set_species(self.name, material_type="dna", attributes=attributes) else: - self.dna = self.set_species(dna, material_type = "dna", attributes = attributes) + self.dna = self.set_species(dna, material_type="dna", attributes=attributes) + + if self.promoter is not None: + self.promoter.dna = self.dna + if self.rbs is not None: + self.rbs.dna = self.dna + def update_transcript(self, transcript: Union[None, RNA, str, bool], attributes=None) -> None: + """sets up the transcript attribute with a valid RNA instance. - def update_transcript(self, transcript, attributes = None): + :param transcript: name of a RNA transcript or RNA instance + :param attributes: Species attribute + :return: None + """ if transcript is None: - self.transcript = self.set_species(self.name, material_type = "rna", attributes = attributes) + self.transcript = self.set_species(self.name, material_type="rna", attributes=attributes) + + # this is used for expression mixtures where there is no transcript! + elif transcript is False: + self.transcript = None else: - self.transcript = self.set_species(transcript, material_type = "rna", attributes = attributes) + self.transcript = self.set_species(transcript, material_type="rna", attributes=attributes) if self.promoter is not None: self.promoter.transcript = self.transcript if self.rbs is not None: self.rbs.transcript = self.transcript - def update_protein(self, protein, attributes = None): + def update_protein(self, protein: Union[None, Protein, str], attributes=None) -> None: + """sets up the protein attribute with a valid Protein instance. + + :param protein: name of a protein or Protein instance + :param attributes: Species attribute + :return: None + """ if protein is None: - self._protein = self.set_species(self.name, material_type = "protein", attributes = attributes) + self.protein = self.set_species(self.name, material_type="protein", attributes=attributes) else: - self._protein = self.set_species(protein, material_type = "protein", attributes = attributes) + self.protein = self.set_species(protein, material_type="protein", attributes=attributes) if self.rbs is not None: - self.rbs.transcript = self.protein + self.rbs.protein = self.protein + if self.promoter is not None: + self.promoter.protein = self.protein + + def update_promoter(self, promoter: Union[Protein, str], transcript: RNA=None, protein: Protein=None) -> None: + """sets up the promoter attribute with a valid Promoter instance. - def update_promoter(self, promoter, transcript=None): + :param promoter: name of a promoter or Promoter instance + :param transcript: reference to the RNA transcript + :param protein: + :return: None + """ if transcript is not None: self.update_transcript(transcript) if isinstance(promoter, str): - self.promoter = Promoter(assembly = self, name = promoter, - transcript = self.transcript, - parameters = self.parameters) + self.promoter = Promoter(assembly=self, name=promoter, + transcript=self.transcript, + protein=protein) elif isinstance(promoter, Promoter): - self.promoter = promoter + self.promoter = copy.deepcopy(promoter) self.promoter.assembly = self self.promoter.transcript = self.transcript + self.promoter.protein = protein elif promoter is not None: - raise ValueError("Improper promoter type recieved by DNAassembly. " + raise ValueError("Improper promoter type received by DNAassembly. " "Expected string or promoter object. " - f"Recieved {repr(promoter)}.") - if promoter is not None: - self.promoter.update_parameters( - mixture_parameters = self.parameters, - overwrite_custom_parameters = False) + f"Received {repr(promoter)}.") + else: + self.promoter = None - def update_rbs(self, rbs, transcript = None, protein = None): + if self.promoter is not None: + self.promoter.update_parameters(parameter_database=self.parameter_database, overwrite_parameters=False) + self.promoter.set_mixture(self.mixture) + self.promoter.add_mechanisms(self.mechanisms, optional_mechanism=True) + + def update_rbs(self, rbs: Union[RBS, str], transcript: RNA=None, protein: Protein=None) -> None: + """sets up the rbs attribute with a valid RBS instance. + + :param rbs: name of the ribosome binding site or RBS instance + :param transcript: RNA that contains the ribosome binding site + :param protein: protein that RNA contains + :return: None + """ if protein is not None: self.update_protein(protein) @@ -108,95 +170,95 @@ def update_rbs(self, rbs, transcript = None, protein = None): self.update_transcript(transcript) if isinstance(rbs, str): - self.rbs = RBS(assembly = self, name = rbs, protein = self._protein, - transcript = self.transcript, - parameters = self.parameters) + self.rbs = RBS(assembly=self, name=rbs, protein=self.protein, + transcript=self.transcript) elif isinstance(rbs, RBS): - self.rbs = rbs + self.rbs = copy.deepcopy(rbs) self.rbs.assembly = self self.rbs.transcript = self.transcript - self.rbs.protein = self._protein + self.rbs.protein = self.protein elif rbs is not None: - raise ValueError("Improper rbs type recieved by DNAassembly. " - "Expected string or RBS object. Recieved " - f"{repr(rbs)}.") + raise ValueError(f"Improper rbs type received by DNAassemby. Expected string or RBS object. Received {repr(rbs)}.") + else: + self.rbs = None - if rbs is not None: - self.rbs.update_parameters(mixture_parameters = self.parameters, - overwrite_custom_parameters = False) + if self.rbs is not None: + self.rbs.update_parameters(parameter_database=self.parameter_database, overwrite_parameters=False) + self.rbs.set_mixture(self.mixture) + self.rbs.add_mechanisms(self.mechanisms, optional_mechanism=True) - @property - def protein(self): - return self._protein + def update_species(self) -> List[Species]: + """collects the list of Species that a DNAassemlby instance holds. - def update_species(self): + :return: list of Species that a DNAassemlby instance holds + """ species = [] species.append(self.dna) - if self.promoter is not None and self.rbs is not None: + if self.promoter is not None: species += self.promoter.update_species() + + if self.rbs is not None: species += self.rbs.update_species() - elif self.promoter is not None and self.rbs is None: - species += self.promoter.update_species() + #deg_mech = self.get_mechanism("rna_degredation", optional_mechanism=True) + #if deg_mech is not None and self.promoter is not None and self.transcript is not None: + # species += deg_mech.update_species(rna=self.transcript, component=self.promoter, part_id=self.transcript.name) - if "rna_degredation" in self.mechanisms and self.promoter is not None: - deg_mech = self.mechanisms["rna_degredation"] - species += deg_mech.update_species(rna = self.transcript, component = self.promoter, part_id = self.transcript.name) + return species - # TODO raise a warning if there were duplicate species - return list(set(species)) + def update_reactions(self) -> List[Reaction]: + """collects the list of Reactions that a DNAassemlby instance holds. - def update_reactions(self): + :return: list of Reactions that a DNAassemlby instance holds. + """ reactions = [] if self.promoter is not None: - self.promoter.parameter_warnings = self.parameter_warnings reactions += self.promoter.update_reactions() if self.rbs is not None: - self.rbs.parameter_warnings = self.parameter_warnings reactions += self.rbs.update_reactions() - if "rna_degredation" in self.mechanisms and self.promoter is not None: - deg_mech = self.mechanisms["rna_degredation"] - + #deg_mech = self.get_mechanism("rna_degredation", optional_mechanism=True) + #if deg_mech is not None and self.promoter is not None and self.transcript is not None: + # reactions += deg_mech.update_reactions(rna=self.transcript, component=self.promoter, part_id=self.transcript.name) - reactions += deg_mech.update_reactions(rna = self.transcript, component = self.promoter, part_id = self.transcript.name) - # TODO check that the reaction list is unique return reactions - def update_parameters(self, mixture_parameters = {}, parameters = {}, - overwrite_custom_parameters = True): - DNA.update_parameters(self = self, - mixture_parameters = mixture_parameters, - parameters = parameters, - overwrite_custom_parameters = overwrite_custom_parameters) + def update_parameters(self, parameter_file: str=None, parameters:ParameterDatabase=None, overwrite_parameters: bool=True) -> None: + """updates the parameters stored in dna, promoter and rbs. + + :param parameter_file: valid parameter file + :param parameters: a parameter database instance + :param overwrite_parameters: whether to overwrite existing parameters + :return: None + """ + + DNA.update_parameters(self=self, parameter_file=parameter_file, parameters=parameters, overwrite_parameters=overwrite_parameters) if self.promoter is not None: - self.promoter.update_parameters( - mixture_parameters = mixture_parameters, - parameters = parameters, - overwrite_custom_parameters = overwrite_custom_parameters) + self.promoter.update_parameters(parameter_file=parameter_file, parameters=parameters, overwrite_parameters=overwrite_parameters) + + if self.rbs is not None: + self.rbs.update_parameters(parameter_file=parameter_file, parameters=parameters, overwrite_parameters=overwrite_parameters) + + def add_mechanism(self, mechanism: Mechanism, mech_type: str=None, overwrite: bool=False, optional_mechanism: bool=False) -> None: + """adds a mechanism of type mech_type to the Component Mechanism dictionary. + + DNA_assembly also adds the mechanisms to its promoter and rbs (but never overwrites them!) + + :param mechanism: reference to a Mechanism instance + :param mech_type: type of mechanism + :param overwrite: whether to overwrite the mechanism in Component + :param optional_mechanism: + :return: None + """ + Component.add_mechanism(self, mechanism, mech_type=mech_type, overwrite=overwrite, optional_mechanism=optional_mechanism) + + if self.promoter is not None: + self.promoter.add_mechanism(mechanism, mech_type=mech_type, optional_mechanism=True) + if self.rbs is not None: - self.rbs.update_parameters(mixture_parameters = mixture_parameters, - parameters = parameters, - overwrite_custom_parameters = overwrite_custom_parameters) - - def update_mechanisms(self, mixture_mechanisms = {}, mechanisms = {}, - overwrite_custom_mechanisms = False): - DNA.update_mechanisms(self = self, - mixture_mechanisms = mixture_mechanisms, - mechanisms = mechanisms) - - if self.promoter is not None and "transcription" in self.mechanisms: - mech_tx = self.mechanisms["transcription"] - mechs = {"transcription": mech_tx} - self.promoter.update_mechanisms(mechanisms = mechs, - overwrite_custom_mechanisms = overwrite_custom_mechanisms) - if self.rbs is not None and "translation" in self.mechanisms: - mech_tl = self.mechanisms["translation"] - mechs = {"translation": mech_tl} - self.rbs.update_mechanisms(mechanisms = mechs, - overwrite_custom_mechanisms = overwrite_custom_mechanisms) + self.rbs.add_mechanism(mechanism, mech_type=mech_type, optional_mechanism=True) def __str__(self): return type(self).__name__ + ": " + self.name @@ -208,5 +270,5 @@ def __repr__(self): txt += "\n\ttranscript = " + repr(self.transcript) if self.rbs is not None: txt += "\n\t" + repr(self.rbs) - txt += "\n\tprotein = " + repr(self._protein) - return txt \ No newline at end of file + txt += "\n\tprotein = " + repr(self.protein) + return txt diff --git a/biocrnpyler/dna_assembly_rbs.py b/biocrnpyler/dna_assembly_rbs.py deleted file mode 100644 index ea8aeb54..00000000 --- a/biocrnpyler/dna_assembly_rbs.py +++ /dev/null @@ -1,44 +0,0 @@ -from .component import Component -from .components_basic import DNA, RNA, Protein -from .chemical_reaction_network import ComplexSpecies, Species -from .mechanisms_binding import * -from .mechanisms_txtl import * - -class RBS(Component): - def __init__(self, name: str, assembly = None, - transcript = None, protein = None, length = 0, - mechanisms = {}, parameters = {}, **keywords): - self.assembly = assembly - self.length = length - - Component.__init__(self, name = name, mechanisms = mechanisms, - parameters = parameters, **keywords) - - if transcript is None and assembly is None: - self.transcript = None - elif transcript is None: - self.transcript = Species(assembly.name, material_type = "rna") - else: - self.transcript = self.set_species(transcript, material_type = "rna") - - if protein is None: - self.protein = Species(assembly.name, material_type = "protein") - else: - self.protein = self.set_species(protein, material_type = "protein") - - Component.__init__(self, name = name, mechanisms = mechanisms, - parameters = parameters, **keywords) - - def update_species(self): - mech_tl = self.mechanisms['translation'] - species = [] - species += mech_tl.update_species(transcript = self.transcript, protein = self.protein, component = self, part_id = self.name) - return species - - def update_reactions(self): - mech_tl = self.mechanisms['translation'] - reactions = [] - - reactions += mech_tl.update_reactions(transcript = self.transcript, - protein = self.protein, component = self, part_id = self.name) - return reactions diff --git a/biocrnpyler/dna_construct.py b/biocrnpyler/dna_construct.py new file mode 100644 index 00000000..1bf77db4 --- /dev/null +++ b/biocrnpyler/dna_construct.py @@ -0,0 +1,781 @@ +################################################################ +# DNA_construct: a higher level for construct compilation +# Author: Andrey Shur +# Latest update: 7/31/2020 +# +################################################################ + + +# Copyright (c) 2020, Build-A-Cell. All rights reserved. +# See LICENSE file in the project root directory for details. + +import copy +from warnings import warn + +from .component import Component +from .components_basic import DNA, RNA +from .dna_part import DNA_part +from .dna_part_cds import CDS +from .dna_part_misc import AttachmentSite +from .dna_part_promoter import Promoter +from .dna_part_rbs import RBS +from .dna_part_terminator import Terminator +from .species import (ComplexSpecies, OrderedMonomer, OrderedPolymer, + OrderedPolymerSpecies) +from .utils import all_comb, remove_bindloc, rev_dir + +#integrase_sites = ["attB","attP","attL","attR","FLP","CRE"] + + +class Construct(Component,OrderedPolymer): + def __init__(self, + parts_list, + name=None, + circular=False, + mechanisms=None, # custom mechanisms + parameters=None, # customized parameters + attributes=None, + initial_conc=None, + copy_parts=True, + **keywords): + """this represents a bunch of parts in a row. + A parts list has [[part,direction],[part,direction],...] + Each part must be an OrderedMonomer""" + #TODO get_part, dna_part search engine like get_component from mixture + myparts = [] + for part in parts_list: + newpart = [] + if(type(part)==list or type(part)==tuple): + if(copy_parts): + newpart = [copy.deepcopy(part[0]).remove(),part[1]] + else: + newpart = [part[0].remove(),part[1]] + elif(isinstance(part,OrderedMonomer)): + npartd = None + npart = None + if(part.direction is not None): + #remember the direction that is in the part + npartd = copy.deepcopy(part.direction) + else: + #if no direction is specified, forward is default + npartd = "forward" + if(copy_parts): + #we have to copy the part + npart = copy.deepcopy(part) + else: + npart = part + #forget everything about being part of a polymer + npart.remove() + #for the purposes of OrderedPolymer, you still need [part,direction] + newpart = [npart,npartd] + myparts += [newpart] + OrderedPolymer.__init__(self,myparts) + #self.parts_list = self._polymer + self.circular=circular + if(name is None): + name = self.make_name() #automatic naming + self.name = name + Component.__init__(self=self,name=name,length = len(parts_list), + mechanisms=mechanisms,parameters=parameters, + attributes=attributes,initial_conc = initial_conc, + **keywords) + self.update_parameters() + self.transcripts = [] + if(not hasattr(self,"material_type")): + self.material_type=None #set this when you inherit this class + self.update_base_species(self.name) + self.out_components = None + self.predicted_rnas = None + self.predicted_proteins = None + @property + def parts_list(self): + return self._polymer + def make_name(self): + output = "" + outlst = [] + for part in self.parts_list: + pname = part.name + if(part.direction=="reverse"): + pname+="_r" + outlst += [pname] + output = '_'.join(outlst) + if(self.circular): + output+="_o" + return output + def get_part(self,part = None, part_type=None, name = None, index = None): + """ + Function to get parts from Construct.parts_list. + + One of the 3 keywords must not be None. + + part: an instance of a DNA_part. Searches Construct.parts_list for a DNA_part with the same type and name. + part_type: a class of DNA_part. For example, Promoter. Searches Construct.parts_list for a DNA_part with the same type. + name: str. Searches Construct.parts_list for a DNA_part with the same name + index: int. returns Construct.parts_list[index] + + if nothing is found, returns None. + """ + + if [part, name, index,part_type].count(None) != 3: + raise ValueError(f"get_component requires a single keyword. Recieved component={part}, name={name}, index={index}.") + if not (isinstance(part, DNA_part) or part is None): + raise ValueError(f"component must be of type DNA_part. Recieved {part}.") + if not (type(part_type) == type or part_type is None): + raise ValueError(f"part_type must be a type. Recieved {part_type}.") + if not (isinstance(name, str) or name is None): + raise ValueError(f"name must be of type str. Recieved {name}.") + if not (isinstance(index, int) or index is None): + raise ValueError(f"index must be of type int. Recieved {index}.") + + matches = [] + if index is not None: + matches.append(self.parts_list[index]) + else: + for comp in self.parts_list: + if part is not None: + if type(part) == type(comp) and comp.name == part.name: + matches.append(comp) + elif name is not None: + if comp.name == name: + matches.append(comp) + elif part_type is not None: + if(isinstance(comp,part_type)): + matches.append(comp) + if len(matches) == 0: + return None + elif len(matches) == 1: + return matches[0] + else: + warn("get_part found multiple matching components. A list has been returned.") + return matches + + + def reverse(self): + """reverses everything, without actually changing the DNA. + also updates the name and stuff, since this is now a different Construct""" + OrderedPolymer.reverse(self) + self.reset_stored_data() + self.name = self.make_name() + self.update_base_species() + return self + def set_mixture(self, mixture): + self.mixture = mixture + for part in self.parts_list: + part.set_mixture(mixture) + def update_base_species(self, base_name=None, attributes = None): + if base_name is None: + self.base_species = self.set_species(self.name, material_type = self.material_type, attributes = attributes) + else: + self.base_species = self.set_species(base_name, material_type = self.material_type, attributes = attributes) + def update_parameters(self, overwrite_parameters = True): + """update parameters of all parts in the construct""" + Component.update_parameters(self = self,parameter_database=self.parameter_database) + for part in self.parts_list: + part.update_parameters(parameter_database = self.parameter_database, + overwrite_parameters = overwrite_parameters) + + def add_mechanism(self, mechanism, mech_type = None, overwrite = False, optional_mechanism = False): + Component.add_mechanism(self, mechanism, mech_type = mech_type, \ + overwrite = overwrite, optional_mechanism = optional_mechanism) + for part in self.parts_list: + part.add_mechanism( mechanism, mech_type = mech_type, \ + overwrite = overwrite, optional_mechanism = optional_mechanism) + def explore_txtl(self): + """this function finds promoters and terminators and stuff in the construct""" + proteins = {} + rnas = {} + for direction in ["forward","reverse"]: + explorer = TxTl_Explorer() + explorer.direction=direction + if(direction == "reverse"): + #if we go backwards then also list the parts backwards + #deepcopy so we don't mangle the list + newlist = copy.deepcopy(self.parts_list)[::-1] + #TODO can we use the OrderedPolymer.reverse() function here? + else: + newlist = copy.deepcopy(self.parts_list) + part_index = 0 + keep_going = 1 + second_looping = 0 + while keep_going: #we may have to loop through the parts twice because the construct is circular. + #this does not account for infinite loops, RCA, etc. + part = newlist[part_index] #pull out the part + keep_going = explorer.see(part) #the explorer keeps track of everything + part_index+=1 #keep going+ + if(part_index==len(self.parts_list)): + part_index = 0 #this takes care of looping + if(self.circular and second_looping == 0): + #print('restart from beginning') + second_looping = 1 #during the second loop, we don't care about promoters + explorer.second_loop() #tell the explorer that we don't care about promoters + else: + explorer.end() #this completes all "in progress" RNAs and proteins + break + #proteins.update(explorer.get_proteins()) + rnas.update(explorer.get_rnas()) + proteins = {} + for promoter in rnas: + _,prots = rnas[promoter].explore_txtl() + proteins.update(prots) + return rnas,proteins + def __repr__(self): + """this is just for display purposes""" + return "DNA_construct = "+ self.make_name() + def show(self): + txt = self.name + rnas,proteins = self.explore_txtl() + if(len(rnas)>0): + for promoter in rnas: + txt += "\n\t"+repr(promoter) + txt += "\n\t" + repr(rnas[promoter]) + if(rnas[promoter] in proteins): + for rbs in proteins[rnas[promoter]]: + txt += "\n\t"+repr(rbs) + for protein in proteins[rnas[promoter]][rbs]: + txt += "\n\tprotein = "+repr(protein) + return txt + def __contains__(self,obj2): + """checks if this construct contains a certain part, or a copy of a certain part""" + if(isinstance(obj2,DNA_part)): + #if we got a DNA part it could mean one of two things: + #1 we want to know if a dna part is anywhere + #2 we want to know if a specific DNA part is in here + #this is complicated by the fact that we want to have the same DNA part be reusable + #in many locations + if(obj2.parent==self): + #the object should already know if it's a part of me + return True + elif(obj2.parent==None): + #this object has been orphaned. + #that means we are looking for matching objects in any position + new_obj2 = copy.deepcopy(obj2).unclone() + uncloned_list = [a.unclone() for a in copy.deepcopy(self.parts_list)] + return new_obj2 in uncloned_list + else: + return False + elif(isinstance(obj2,str)): + #if we get a string, that means we want to know if the name exists anywhere + return obj2 in str(self) + def get_species(self): + ocomplx = [] + for part in self.parts_list: + partspec = copy.copy(part.dna_species) + partspec.material_type = self.material_type + ocomplx += [partspec.set_dir(part.direction)] + out_species = OrderedPolymerSpecies(ocomplx,base_species = self.base_species,circular = self.circular,\ + name = self.name,material_type=self.material_type) + + return out_species + + def located_allcomb(self,spec_list): + """recursively trace all paths through a list + [[[part1,1],[part2,5]],[[part3,1]],[[part4,5],[part5,12]]] + ====================> + compacted_indexes = [1,5,12] + prototype_list = [[part1,part3],[part2,part4],[part5]] + comb_list = [[1],[5],[12],[1,5],[1,12],[5,12],[1,5,12]] + =========================== + then, take the lists from comb_list and create all possible lists + out of prototype_list that includes those elements""" + #first we have to construct the list we are tracing paths through + spec_indexes = [a.position for a in spec_list] #extract all indexes + compacted_indexes = sorted(list(set(spec_indexes))) + prototype_list = [None]*len(compacted_indexes) + for spec in spec_list: + #go through every element and put it in the right place + proto_ind = compacted_indexes.index(spec.position) #where to put it? + if(prototype_list[proto_ind] is None): + #if nothing's been placed here, then create a list + prototype_list[proto_ind] = [spec] + else: + #if something is already here, then add to the list + prototype_list[proto_ind]+= [spec] + # at this point we have a list that looks like this: + # [[[part1,0],[part2,0]],[[part2,3]],[[part3,12],[part5,12]] + # next step is to pick one of the first list (either [part1,0] or [part2,0]) + # one of the second list (only [part2,3] is our option), one of the third list, etc + # for all possible choices made this way + comb_list = all_comb(compacted_indexes) + def recursive_path(in_list): + if(len(in_list)==1): + out_list = [] + for a in in_list[0]: + out_list+= [[a]] + return out_list + elif(len(in_list)==0): + return [] + else: + out_list = [] + for a in in_list[0]: + out_list += [[a] + z for z in recursive_path(in_list[1:])] + return out_list + outlist = [] + for combo in comb_list: + combo_sublists = [] + for combo_index in combo: + combo_sublists += [prototype_list[compacted_indexes.index(combo_index)]] + outlist+= recursive_path(combo_sublists) + return outlist + def make_polymers(self,species_lists,backbone): + """makes polymers from lists of species + inputs: + species_lists: list of species which are to be assembled into a polymer + backbone: the base_species which all these polymers should have""" + polymers = [] + for combo in species_lists: + #members of allcomb are now OrderedMonomers, which contain direction and position + #there could be multiple OrderedPolymerSpecies we are making combinatorial. + #for example, RNAs + new_backbone = copy.deepcopy(backbone) + new_material = backbone.material_type + for spec in combo: + new_material = OrderedPolymerSpecies.default_material + new_backbone.replace(spec.position,spec) + newname = None + self_species = self.get_species() + if(new_backbone==self_species): + #if we have just re-created ourselves, then make sure to call it that + newname = self_species.name + polymers += [copy.deepcopy(self_species)] + else: + new_backbone.material_type = new_material + polymers += [new_backbone] #we make a new OrderedComplexSpecies + return polymers + def update_combinatorial_complexes(self,active_components): + """given an input list of components, we produce all complexes + yielded by those components, mixed and matched to make all possible combinatorial + complexes, where each component is assumed to only care about binding to one spot""" + species = [self.get_species()] + for part in active_components: + #first we make binary complexes + sp_list = part.update_species() + species+=remove_bindloc(sp_list) + #print("initial species") + #print(species) + unique_complexes = {} + possible_backbones = {self.base_species:self.get_species()} + #possible_backbones = {a.name:a.get_species() for a in [self]+[a for a in proteins]} + #species need to be uniqueified + #print(species) + unique_species = list(set(species)) + for specie in unique_species: + #in this list we extract all the variants of the complexes from possible_backbones + #that exist in our species list. + if(isinstance(specie,OrderedPolymerSpecies) and specie.base_species in possible_backbones): + #we only care about OrderedPolymerSpecies made from this construct + if(specie.base_species in unique_complexes): + unique_complexes[specie.base_species] += [specie] + else: + unique_complexes[specie.base_species] = [specie] + #unique_complexes now has a list of all the non-combinatorial complexes we can make + combinatorial_complexes = [] + for bb_name in unique_complexes: + #for each backbone, make all combinatorial combinations. + comp_binders = [] + for unit in unique_complexes[bb_name]: + #for each complex for this backbone, find out what is bound at which location + comp_bound = None + pos_i = 0 + for pos in unit: + #find the position that has a ComplexSpecies in it + if(isinstance(pos,ComplexSpecies) and comp_bound is None): + comp_bound = copy.deepcopy(pos) #this is how we record the location + elif(isinstance(pos,ComplexSpecies)): + raise ValueError("complex exists in two locations!") + #in this case a mechanism has somehow yielded a DNA with items bound at two spots. + #this really shouldn't happen because each component can only bind to one spot. + #TODO perhaps the thing to do here is to assume that these two locations are + #always bound together? For example if integrase binds in two seperate locations? + pos_i+=1 + if(comp_bound is not None): + comp_binders += [comp_bound] #record what is bound, and at what position + allcomb = self.located_allcomb(comp_binders) #all possible combinations of binders are made here + allcomb += [[]] #unbound dna should also be used + #now, all possibilities have been enumerated. + #we construct the OrderedPolymerSpecies + combinatorial_complexes += self.make_polymers(allcomb,possible_backbones[bb_name]) + + return combinatorial_complexes + def update_components(self,rnas=None,proteins=None): + multivalent_self = self.get_species() + self.update_parameters() + if((rnas is None) or (proteins is None)): + rnas = self.predicted_rnas + proteins = self.predicted_proteins + if(rnas is None or proteins is None): + warn("{} is running explore_txtl possibly more than once".format(str(self))) + rnas,proteins = self.explore_txtl() + active_components = [] + for part in self.parts_list: + if(hasattr(part,"update_component")): + updated_components = part.update_component(multivalent_self[part.position],\ + rnas,proteins) + if(updated_components is not None): + active_components += [updated_components] + combinatorial_complexes = self.update_combinatorial_complexes(active_components) + combinatorial_components = [] + for comb_specie in combinatorial_complexes: + if(isinstance(comb_specie,OrderedPolymerSpecies) and comb_specie.base_species == self.base_species): + for part in active_components: + part_pos = part.position + if(isinstance(comb_specie[part_pos],ComplexSpecies)): + #in this case the position of interest is already complexed. Skip! + pass + else: + combinatorial_components += [part.update_component(comb_specie[part_pos],\ + rnas,proteins)] + return combinatorial_components + def __hash__(self): + return hash(self.__repr__()) + def __eq__(self,construct2): + """equality means comparing the parts list in a way that is not too deep""" + if(self.__repr__()==construct2.__repr__()): + return True + else: + return False + + def update_species(self): + species = [self.get_species()] + rnas = None + proteins = None + rnas,proteins = self.explore_txtl() + self.predicted_rnas = rnas + self.predicted_proteins = proteins + #rnas: + #this is a dictionary of the form: + #{promoter:rna_construct,promoter2:rna_construct2} + #proteins: + #this is a dictionary of the form: + #{rna_construct:{RBS:[Product1,Product2],RBS2:[Product3]}} + out_components = self.update_components(rnas,proteins) + #TODO save out_components + for part in out_components: + + sp_list = part.update_species() + + species+=remove_bindloc(sp_list) + self.out_components = out_components + for rna in proteins: + if(not rna == self): + #this part makes sure we don't do an infinite loop if we are in fact an RNA_construct + species += rna.update_species() + return species + def reset_stored_data(self): + self.out_components = None + self.predicted_rnas = None + self.predicted_proteins = None + def changed(self): + self.reset_stored_data() + self.name = self.make_name() + def update_reactions(self,norna=False): + + reactions = [] + rnas = None + proteins = None + rnas = self.predicted_rnas + proteins = self.predicted_proteins + if((rnas is None) or (proteins is None)): + warn("{} is running explore_txtl possibly more than once".format(str(self))) + rnas,proteins = self.explore_txtl() + #rnas,proteins = self.explore_txtl() + + if(self.out_components is None): + raise AttributeError("construct "+str(self) +" has no components! This happens because update_reactions has been run before update_species") + for part in self.out_components: + rx_list = [] + #_ = part.update_species() + #update_components creates new components which are copies of the parts_list components + #but the dna_to_bind attribute has been changed. + #thus we need to make sure they have update_species() run on them before + #doing update_reactions, in case any of these parts have memory + reactions+= part.update_reactions() + for rna in proteins: + if(not rna == self): + #this part makes sure we don't do an infinite loop if we are in fact an RNA_construct + reactions += rna.update_reactions() + return reactions + +class DNA_construct(Construct,DNA): + def __init__(self, + parts_list, + name=None, + circular=False, + mechanisms=None, # custom mechanisms + parameters=None, # customized parameters + attributes=None, + initial_conc=None, + copy_parts=True, + **keywords): + + + self.material_type = "dna" + Construct.__init__(self=self, parts_list =parts_list, name = name, \ + circular=circular, mechanisms=mechanisms, \ + parameters=parameters, attributes=attributes, \ + initial_conc=initial_conc, \ + copy_parts=copy_parts, **keywords) + + + pind = 0 + for part in self.parts_list: + if(type(part.color)==type(None)): + #if the color isn't set, let's set it now! + part.color = pind + if(type(part.color2)==type(None)): + if(isinstance(part,AttachmentSite) and part.site_type in ["attL","attR"]): + #this is the only scenario in which we need a color2 + #TODO make this more general + pind+=1 + part.color2 = pind + pind+=1 + + + + +class TxTl_Explorer: + def __init__(self,possible_rxns=("transcription","translation"),direction="forward"): + """this class goes through a parts_list of a DNA_construct and decides what RNAs are made + and what proteins are made based on orientation and location of parts""" + self.current_rnas = {} + self.current_proteins = {} + self.made_rnas = {} + self.all_rnas = {} + self.made_proteins = {} + self.current_rbs = None + self.possible_rxns = possible_rxns + self.direction=direction + self.second_looping = False + def see(self,part): + """the explorer sees a part. This does different stuff depending on + 1) if there is a current rna or current rbs + 2) what the part is + it returns whether: + 1: not done, keep going + 0: done, stop + """ + effective_direction = part.direction + if(self.direction=="reverse"): + effective_direction = rev_dir(effective_direction) + if(self.current_rnas!={}): + #this means we are making an RNA + terminated = 0 + #TODO how do we know that promoters transcribe and RBSes translate? + #maybe you can transcribe or translate in both directions? + if(isinstance(part,RBS) and "translation" in self.possible_rxns and \ + effective_direction == "forward"): + + self.current_proteins[part]= [] + for promoter in self.current_rnas: + #this tells us that whatever RNAs are currently being made contain this RBS + if(part not in self.current_rnas[promoter][1]): + self.current_rnas[promoter][1] += [part] + if(self.current_rbs == None): + #this means nobody is translating yet + self.current_rbs = part + else: + #another RBS is translating. this could mean a few things: + #1: translational coupling. the previous translation ends and turns + # into this one, with an added coupling term when that gets implemented + #2: it terminates the previous translation. Chances are it would, right? + self.current_rbs = part + # TODO add coupling + elif(effective_direction in part.no_stop_codons and self.current_rbs != None): + #this means we can translate through the current part! + self.current_proteins[self.current_rbs] += [[part,effective_direction]] + elif(self.current_rbs != None): + #this means we CAN'T translate through the current part, but we are translating + self.current_proteins[self.current_rbs] += [[part,effective_direction]] + self.current_rbs = None #current RBS has done its work + for promoter in list(self.current_rnas.keys()): + self.current_rnas[promoter][0]+=[[part,effective_direction]] + #we add the current part + if(isinstance(part,Terminator) and effective_direction == "forward"): + terminated = 1 #a terminator ends everything. This does not account for leakiness + self.terminate_transcription(promoter) + if(terminated): + assert(self.current_rnas=={}) #this should be true if terminate_transcription() worked + # this means that all RNAs have been stopped. But, since the proteins didn't know + # which RNAs they belonged to, they are still hanging around so we have to + # clean them up + self.current_proteins = {} + self.current_rbs = None + terminated = 0 + if((effective_direction=="forward") and \ + (isinstance(part,Promoter) and "transcription" in self.possible_rxns)): + #this if statement makes sure that the current part wants to transcribe, and + #that is something that we are allowed to do + self.current_rnas.update({part:[[],[]]}) + return 1 + elif((("transcription" not in self.possible_rxns) or self.second_looping) and \ + self.current_rnas=={}): + return 0 #this means we are pretty sure there is nothing else left to do. + else: + return 1 #this means keep going! As far as we know there could be more to see + def second_loop(self): + """if we already went around the plasmid, then what we're checking for is continuing + transcripts or proteins. We don't want to start making new transcripts + because we already checked this area for promoters""" + if(self.second_looping==False): + new_rxns = [] + for rxn in self.possible_rxns: + if(rxn!="transcription"): + #remove transcription from the set of possible reactions! + new_rxns += [rxn] + self.possible_rxns = new_rxns + self.second_looping=True + else: + self.end() + def make_rna(self,promname="external"): + """we are making an rna! imposed by external force""" + if(promname in self.current_rnas): + warn("RNA already started; it looks like this: "+str(self.current_rnas[promname])) + else: + self.current_rnas.update({promname:[[],[]]}) + def terminate_transcription(self,promoter=None): + """this terminates the transcription of a specific RNA, started by the promoter + given in the argument. the RNA is deleted from the list of currently transcribing RNAs, + and any proteins that it was making are catalogued""" + if(promoter==None and len(self.current_rnas)>0): + #if you don't specify then it terminates the first one + promoter = list(self.current_rnas.keys())[0] + elif(len(self.current_rnas)==0): + #in this case you terminated transcription when nothing was transcribing + return + rna_partslist = self.current_rnas[promoter][0] + #print(self.current_rnas) + #print(self.current_proteins) + #TODO copy parts here and not in the constructor + rna_construct = RNA_construct(copy.deepcopy(rna_partslist),made_by = promoter) + rna_construct.set_mixture(promoter.mixture) + #current_rna_name = str(promoter)+"-"+str(rna_construct) + self.made_proteins[rna_construct]={} + #compile the name, keeping track of which promoter made the rna and all the parts on it + for rbs in self.current_rnas[promoter][1]: + #ending the RNA also ends all the proteins being generated here. + proteins_per_rbs = [] + # TODO this will run multiple times for each RNA. make it so it runs once! + for protein_part in self.current_proteins[rbs]: + if(protein_part[1] == "forward"): + #it is essential to be forwards + if(isinstance(protein_part[0],CDS) and protein_part[0].protein != None): + #this happens if we do in fact make a protein + proteins_per_rbs+=[protein_part[0]] + #print(rna_partslist) + #print("currently we are translating from "+str(rbs)+ " which is located at " + str(rbs.pos)) + #TODO correct_rbs is possibly not needed + #print(rbs) + #print(rna_partslist) + correct_rbs = rna_construct.parts_list[rna_partslist.index([rbs,"forward"])] + self.made_proteins[rna_construct].update({correct_rbs:proteins_per_rbs}) + + # so this has to be done at the end of the RNA only because only then do we know + # exactly what that full RNA is going to be. + # we want to clear the current proteins, but there could be multiple RNAs that run over the same proteins, + # so wait until we are done tallying all the RNAs before removing everything from current_proteins + del self.current_rnas[promoter] # this removes the current RNA from the list, because it's + # being terminated!! + self.all_rnas.update({promoter:rna_construct}) + return + def end(self): + """we've reached the end of the dna! End everything!""" + for promoter in list(self.current_rnas.keys()): + self.terminate_transcription(promoter) + self.current_rnas = {} + self.current_proteins = {} + self.current_rbs = None + def get_proteins(self): + """return all the proteins made during the latest exploration""" + return self.made_proteins + def get_rnas(self): + """return all RNAs made during the latest exploration""" + return self.all_rnas + + +class RNA_construct(Construct,RNA): + def __init__(self,parts_list,name=None,made_by="unknown",**keywords): + """an RNA_construct is a lot like a DNA_construct except it can only translate, and + can only be linear""" + self.material_type = "rna" + self.my_promoter = made_by + Construct.__init__(self=self,parts_list=parts_list,circular=False,name=name,**keywords) + + def explore_txtl(self): + """an RNA has no tx, only TL! central dogma exists, right?""" + # lets try to make this more modular shall we? + explorer = TxTl_Explorer(possible_rxns = ("translation",)) + explorer.make_rna(self.my_promoter) + part_index = 0 + keep_going = 1 + while keep_going: + + part = self.parts_list[part_index] + keep_going = explorer.see(part) + part_index+=1 + if(part_index==len(self.parts_list)): + part_index = 0 + if(self.circular): + explorer.second_loop() + else: + explorer.end() + break + proteins = explorer.get_proteins() + rnadict = {self.my_promoter:self} + return rnadict, proteins + #def get_species(self): + # outspec = Construct.get_species(self) + #for spec in outspec: + # spec.material_type = "rna" + #outspec.material_type="rna" + # return outspec + def __repr__(self): + """the name of an RNA should be different from DNA, right?""" + output = "rna = "+self.name + return output + + + +#NOT IMPLEMENTED circular matching code below +#apparently below won't work because you can't hash the parts_list + #this means the equality won't work for circular constructs. oops! + ''' + if(len(self.parts_list) != len(construct2.parts_list)): + return False + else: + if(self.circular == construct2.circular): + if(self.circular == False): + for p1,p2 in zip(self.parts_list,construct2.parts_list): + if((p1.name != p2.name) or type(p1)!=type(p2) or p1.pos!=p2.pos): + #name and type are the crucial elements + #the pos should always match up. If it doesn't, then one of the two + #DNA_constructs is super wrong somehow... + + return False + #if you look through the whole list and don't find a mismatch then it's a match + return True + elif(self.circular == True): + #in this case we need to rotate them until they align + #this opens up a can of worms though. How can we refer to positions of things + #if the sequence can be rotated??? + poslist = [a for a in range(len(construct2.parts_list))] + for part_id in range(len(construct2.parts_list)): + #try every possible rotation of the thing we're comparing against + permuted_id_list = poslist[part_id:]+poslist[:part_id] + #we're just making a new list with the parts_list rotated + permuted_p2list = [construct2.parts_list[a] for a in permuted_id_list] + match = True #if you make it through the loop, then the match is true + for p1,p2 in zip(self.parts_list,permuted_p2list): + #compare each element to each other element + if((p1.name != p2.name) or type(p1)!=type(p2)): + match = False + #as soon as you find something wrong, quit + break + if(match==False): + #try the next permutation + continue + else: + #if we made it all the way here then it matches! + return True + #if we are here then we've gone through all permutations and hit "continue" every time. + #that means there is no orientation in which it matches + return False + #''' diff --git a/biocrnpyler/dna_part.py b/biocrnpyler/dna_part.py new file mode 100644 index 00000000..997b4fdd --- /dev/null +++ b/biocrnpyler/dna_part.py @@ -0,0 +1,129 @@ +################################################################ +# DNA_part: a component-like intermediate class necessary for DNA_construct +# Author: Andrey Shur +# Latest update: 6/4/2020 +# +# +################################################################ + + +# Copyright (c) 2020, Build-A-Cell. All rights reserved. +# See LICENSE file in the project root directory for details. + +from .component import Component +from .polymer import OrderedMonomer, OrderedPolymer +from .species import Species + + +class DNA_part(Component, OrderedMonomer): + def __init__(self,name,mechanisms=None,parameters=None,**keywords): + """this represents a modular component sequence. These get compiled into working components""" + Component.__init__(self=self, name = name, mechanisms = mechanisms, + parameters = parameters, **keywords) + + self.name = name + #self.assembly = property(self._get_assembly,self._set_assembly) + assembly = None #this is already covered in self.assembly. Is this needed? + direction = None #orientation + self.color = None #this will be taken from higher up + self.color2 = None #this will be taken from higher up and only defined for attL/R sites + pos = None #position in the dna_construct + self.sequence = None #nucleotide sequence + self.no_stop_codons = [] #some parts will set this, others won't. Default is that it has stop codons + + for key, value in keywords.items(): + #goes through any extra parameters and sets them! + if(key=="assembly"): + assembly = value + elif(key=="direction"): + direction = value + elif(key=="color"): + self.color = value + elif(key=="color2"): + self.color2 = value + elif(key=="pos"): + pos = value + elif(key=="sequence"): + self.sequence = value + elif(key=="no_stop_codons"): + if(value is not None): + self.no_stop_codons = value + if(isinstance(assembly,OrderedPolymer)): + OrderedMonomer.__init__(self,position=pos,parent=assembly,direction=direction) + else: + self.assembly = assembly + OrderedMonomer.__init__(self) + @property + def dna_species(self): + return Species(self.name, material_type="dna") + def __repr__(self): + myname = self.name + if(self.position is not None): + myname+="_"+str(self.position) + if(self.direction =="reverse"): + myname += "_r" + return myname + def __hash__(self): + hval = 0 + if(hasattr(self,"assembly")): + if(self.assembly is None): + hval += hash(None) + else: + hval += hash(str(self.assembly)) + hval += hash(self.name) + if(self.parent is not None): + hval+= hash(str(self.parent)) + hval+= hash(self.position) + hval += hash(self.direction) + return hval + def __eq__(self,other): + if(type(other)==type(self)): + if(self.name==other.name): + if(self.assembly is not None and other.assembly is not None): + if(str(self.assembly)==str(other.assembly)): + return True + elif((self.assembly is not None) or (other.assembly is not None)): + #if one has an assembly and the other doesn't, then they aren't the same!! + return False + elif(((self.parent is None) and (other.parent is None)) or \ + ((self.parent is not None) and (other.parent is not None) and (str(self.parent)==str(other.parent)))): + #this is for when we are using the OrderedMonomer for its intended function + if(self.direction==other.direction and self.position==other.position): + return True + return False + + def clone(self,position,direction,parent_dna): + """this defines where the part is in what piece of DNA""" + #TODO add warning if DNA_part is not cloned + self.insert(parent_dna,position,direction) + #if(self.assembly is not None): + # warn(str(self) + " already belongs to "+str(self.assembly.name)+"! It will now be part of the new assembly") + # self.unclone() + + #self.pos = position + #self.direction = direction + #self.assembly = parent_dna + return self + def unclone(self): + """removes the current part from anything""" + self.remove() + #if(self.assembly is not None): + # rightparts = self.assembly.parts_list[self.pos+1:] + # for part in rightparts: + # part.pos -= 1 + # self.assembly.parts_list = self.assembly.parts_list[:self.pos]+rightparts + #self.pos = None + #self.direction = None + #self.assembly = None + return self + def reverse(self): + OrderedMonomer.reverse(self) + #if(self.direction=="forward"): + # self.direction = "reverse" + #elif(self.direction=="reverse"): + # self.direction = "forward" + #elif(self.direction==None): + # warn(str(self)+" has no direction. Perhaps it wasn't cloned?") + #else: + # raise ValueError("direction is not forward or reverse! It's "+self.direction) + return self diff --git a/biocrnpyler/dna_part_cds.py b/biocrnpyler/dna_part_cds.py new file mode 100644 index 00000000..6cefcc27 --- /dev/null +++ b/biocrnpyler/dna_part_cds.py @@ -0,0 +1,28 @@ + +# Copyright (c) 2020, Build-A-Cell. All rights reserved. +# See LICENSE file in the project root directory for details. + +from .chemical_reaction_network import Species +from .component import Component +from .dna_part import DNA_part + + +class CDS(DNA_part): + def __init__(self,name,protein,no_stop_codons=None, **keywords): + """a CDS is a sequence of DNA that codes for a protein""" + self.name = name + DNA_part.__init__(self,name,no_stop_codons=no_stop_codons,protein=None, **keywords) + #TODO make this contain a species and not a component + #TODO use set_species() + if(protein is None): + self.protein = Species(name,material_type="protein") + elif(isinstance(protein,str)): + self.protein = Species(protein,material_type="protein") + elif(isinstance(protein,Component)): + self.protein=protein.get_species() + def update_species(self): + return [self.protein] + def update_reactions(self): + return [] + def get_species(self): + return self.protein diff --git a/biocrnpyler/dna_part_misc.py b/biocrnpyler/dna_part_misc.py new file mode 100644 index 00000000..9613a7e9 --- /dev/null +++ b/biocrnpyler/dna_part_misc.py @@ -0,0 +1,78 @@ + +# Copyright (c) 2020, Build-A-Cell. All rights reserved. +# See LICENSE file in the project root directory for details. + +import copy +from warnings import warn + +from .dna_part import DNA_part +from .mechanisms_binding import One_Step_Cooperative_Binding +from .species import Species + +integrase_sites = ["attB","attP","attL","attR","FLP","CRE"] +class DNABindingSite(DNA_part): + def __init__(self,name,binders,no_stop_codons=None,assembly = None,**keywords): + """an integrase attachment site binds to integrase""" + + if(isinstance(binders,list)): + self.binders = [self.set_species(a) for a in binders] + else: + self.binders = [binders] + self.mechanisms = {"binding":One_Step_Cooperative_Binding()} + DNA_part.__init__(self,name,no_stop_codons=no_stop_codons,mechanisms = self.mechanisms,assembly = assembly,**keywords) + self.name = name + #self.assembly = None + + def __repr__(self): + myname = self.name + return myname + def update_species(self): + spec = [] + spec += self.binders + if(self.dna_to_bind is not None): + mech_b = self.mechanisms["binding"] + for binder in self.binders: + spec += mech_b.update_species(binder,self.dna_to_bind,component=self,part_id = self.name) + #TODO: different proteins probably have different affinity to bind this sequence + return spec + def update_reactions(self): + rxns = [] + if(self.dna_to_bind is not None): + mech_b = self.mechanisms["binding"] + for binder in self.binders: + rxns += mech_b.update_reactions(binder,self.dna_to_bind,component=self,part_id = self.name) + return rxns + def update_component(self,dna,rnas=None,proteins=None,mypos = None): + """returns a copy of this component, except with the proper fields updated""" + out_component = copy.deepcopy(self) + if(mypos is not None): + out_component.dna_to_bind = dna[mypos] + else: + out_component.dna_to_bind = dna + if(dna.material_type == "rna"): + #DNA binding sites only work with DNA + return None + elif(dna.material_type == "dna"): + return out_component +class AttachmentSite(DNABindingSite): + #TODO generalize to "DNA binding site" + def __init__(self,name, site_type = "attB",integrase = "int1", dinucleotide = 1,no_stop_codons=None,**keywords): + if(isinstance(integrase,Species)): + self.integrase_species = integrase + self.integrase = integrase.name + elif(isinstance(integrase,str)): + self.integrase_species = Species(integrase,material_type="protein") + self.integrase = integrase + #self.integrase = integrase + self.dinucleotide = dinucleotide + self.site_type = site_type + DNABindingSite.__init__(self,name,self.integrase_species,no_stop_codons=no_stop_codons,**keywords) + def __repr__(self): + myname = self.name + if(self.site_type in integrase_sites): + myname += "_" + self.integrase + if(self.dinucleotide != 1): + myname += "_"+str(self.dinucleotide) + else: + warn("warning! site {} has site_type {} which is not recognized".format(self.name,self.site_type)) + return myname diff --git a/biocrnpyler/dna_assembly_promoter.py b/biocrnpyler/dna_part_promoter.py similarity index 54% rename from biocrnpyler/dna_assembly_promoter.py rename to biocrnpyler/dna_part_promoter.py index 03e0ce1b..c2becdbc 100644 --- a/biocrnpyler/dna_assembly_promoter.py +++ b/biocrnpyler/dna_part_promoter.py @@ -1,50 +1,124 @@ -from .component import Component -from .components_basic import DNA, RNA, Protein, ChemicalComplex -from .chemical_reaction_network import ComplexSpecies, Species -from .mechanisms_binding import * -from .mechanisms_txtl import * -from warnings import warn as pywarn + +# Copyright (c) 2020, Build-A-Cell. All rights reserved. +# See LICENSE file in the project root directory for details. + +import copy import itertools as it -import numpy as np +from warnings import warn + +from .dna_part import DNA_part +from .mechanisms_binding import (Combinatorial_Cooperative_Binding, + One_Step_Cooperative_Binding) +from .mechanisms_txtl import (NegativeHillTranscription, + PositiveHillTranscription) +from .species import Species -class Promoter(Component): + +class Promoter(DNA_part): + """A basic Promoter class with no regulation. Needs to be included in a DNAassembly or DNAconstruct to function. + """ def __init__(self, name, assembly=None, transcript=None, length=0, - mechanisms={}, parameters={}, **keywords): - self.assembly = assembly + mechanisms=None, parameters=None, protein=None,dna_to_bind=None, **keywords): + self._dna_bind = dna_to_bind self.length = length + if transcript is None and assembly is None: self.transcript = None elif transcript is None: self.transcript = Species(assembly.name, material_type="rna") + elif type(transcript) == list: + self.transcript = transcript else: - self.transcript = self.set_species(transcript, material_type = 'rna') - - Component.__init__(self, name = name, mechanisms = mechanisms, - parameters = parameters, **keywords) - + self.transcript = self.set_species(transcript, material_type='rna') + + if(isinstance(protein,str)): + self.protein = [self.set_species(protein,material_type="protein")] + elif(isinstance(protein,Species)): + self.protein = [protein] + elif(isinstance(protein,list)): + self.protein = protein + else: + self.protein = None + #Promoter should not have initial conditions. These need to be in DNAAssembly or DNAConstruct + if "initial_conc" in keywords.values() and keywords["initial_conc"] is not None: + raise AttributeError("Cannot set initial_conc of a Promoter. Must set initial_conc for the DNAassembly or DNAConstruct.") + if "initial_condition_dictionary" in keywords.values() and keywords["initial_condition_dictionary"] is not None: + raise AttributeError("Cannot set initial_condition_dictionary of a Promoter. Must set initial_condition_dictionary for the DNAassembly or DNAconstruct.") + + DNA_part.__init__(self, name = name, mechanisms = mechanisms, + parameters = parameters, assembly=assembly, **keywords) def update_species(self): - mech_tx = self.mechanisms["transcription"] + mech_tx = self.get_mechanism("transcription") species = [] - species += mech_tx.update_species(dna = self.assembly.dna, \ - transcript = self.transcript, protein = self.assembly.protein, + species += mech_tx.update_species(dna = self.dna_to_bind, \ + transcript = self.transcript, protein = self.get_protein_for_expression(), component = self, part_id = self.name) - return species + return species + @property + def dna_to_bind(self): + if(self._dna_bind is None): + if(self.assembly is None): + return None + else: + self._dna_bind = self.assembly.dna + return self._dna_bind + @dna_to_bind.setter + def dna_to_bind(self,value): + self._dna_bind = value + def get_species(self): + return None def update_reactions(self): - mech_tx = self.mechanisms["transcription"] + mech_tx = self.get_mechanism("transcription") reactions = [] - reactions += mech_tx.update_reactions(dna = self.assembly.dna, \ + reactions += mech_tx.update_reactions(dna = self.dna_to_bind, \ component = self, part_id = self.name, complex = None, - transcript = self.transcript, protein = self.assembly.protein) + transcript = self.transcript, protein = self.get_protein_for_expression()) return reactions + def update_component(self,dna,rnas,proteins,mypos = None): + """returns a copy of this component, except with the proper fields updated""" + if(dna.material_type == "rna"): + #Promoters only work with DNA + return None + out_component = copy.deepcopy(self) + if(mypos is not None): + out_component.dna_to_bind = dna[mypos] + else: + out_component.dna_to_bind = dna + myrna = rnas[self] + out_component.transcript = myrna.get_species() + rbslist = proteins[myrna] + proteinlist = [] + for a in rbslist: + proteinlist += rbslist[a] + out_component.protein = proteinlist + return out_component + + + #Used for expression mixtures where transcripts are replaced by proteins + def get_protein_for_expression(self): + if self.transcript is None: + return self.protein + else: + return None class RegulatedPromoter(Promoter): - def __init__(self, name, regulators, leak = True, assembly = None, - transcript = None, length = 0, mechanisms = {}, - parameters = {}, **keywords): + """ + A Promoter class with simple regulation. + regulators = [list of species] + Each regulator binds independently to the Promoter to regulate it. + """ + def __init__(self, name: str, regulators, leak=True, assembly=None, + transcript=None, length=0, mechanisms=None, + parameters=None , **keywords): + + Promoter.__init__(self, name = name, assembly = assembly, + transcript = transcript, length = length, + mechanisms = mechanisms, parameters = parameters, + **keywords) if not isinstance(regulators, list): regulators = [regulators] @@ -55,122 +129,146 @@ def __init__(self, name, regulators, leak = True, assembly = None, self.leak = leak - self.default_mechanisms = {"binding": One_Step_Cooperative_Binding()} - - Promoter.__init__(self, name = name, assembly = assembly, - transcript = transcript, length = length, - mechanisms = mechanisms, parameters = parameters, - **keywords) - + self.add_mechanism(One_Step_Cooperative_Binding(), "binding") + self.complexes = [] + def update_species(self): - mech_tx = self.mechanisms["transcription"] - mech_b = self.mechanisms['binding'] + mech_tx = self.get_mechanism("transcription") + mech_b = self.get_mechanism('binding') species = [] + self.complexes = [] if self.leak is not False: - species += mech_tx.update_species(dna = self.assembly.dna, component = self, part_id = self.name+"_leak") + species += mech_tx.update_species(dna = self.dna_to_bind, transcript = self.transcript,\ + component = self, part_id = self.name+"_leak", protein = self.get_protein_for_expression()) for i in range(len(self.regulators)): regulator = self.regulators[i] - species_b = mech_b.update_species(regulator, self.assembly.dna, part_id = self.name+"_"+regulator.name, component = self) + species_b = mech_b.update_species(regulator, self.dna_to_bind, part_id = self.name+"_"+regulator.name,\ + component = self, protein = self.get_protein_for_expression()) species += species_b #Find complexes containing DNA and the regulator + #DNA should be *not* a part of an OrderedPolymer for this to work + dna_simple = copy.deepcopy(self.dna_to_bind) + dna_simple.remove() for s in species_b: - if isinstance(s, ComplexSpecies) and self.assembly.dna in s.species and regulator in s.species: + if dna_simple in s and regulator in s: self.complexes += [s] - species += mech_tx.update_species(dna = s, transcript = self.transcript, protein = self.assembly.protein, part_id = self.name+"_"+regulator.name, component = self) + species += mech_tx.update_species(dna = s, transcript = self.transcript, \ + protein = self.get_protein_for_expression(), part_id = self.name+"_"+regulator.name, component = self) return species def update_reactions(self): reactions = [] - mech_tx = self.mechanisms["transcription"] - mech_b = self.mechanisms['binding'] + mech_tx = self.get_mechanism("transcription") + mech_b = self.get_mechanism('binding') - if self.leak != False: - reactions += mech_tx.update_reactions(dna = self.assembly.dna, component = self, part_id = self.name+"_leak", \ - transcript = self.transcript, protein = self.assembly.protein) + if self.leak is not False: + reactions += mech_tx.update_reactions(dna = self.dna_to_bind, component = self, part_id = self.name+"_leak", \ + transcript = self.transcript, protein = self.get_protein_for_expression()) for i in range(len(self.regulators)): regulator = self.regulators[i] complex_ = self.complexes[i] - reactions += mech_b.update_reactions(regulator, self.assembly.dna, component = self, \ - part_id = self.name+"_"+regulator.name) + reactions += mech_b.update_reactions(regulator, self.dna_to_bind, component = self, \ + part_id = self.name+"_"+regulator.name,protein=self.protein) + reactions += mech_tx.update_reactions(dna = complex_, component = self, part_id = self.name+"_"+regulator.name, \ - transcript = self.transcript, protein = self.assembly.protein) + transcript = self.transcript, protein = self.get_protein_for_expression()) return reactions -#A class for a promoter which can be activated by a single species, modelled as a positive hill function -class ActivatablePromotor(Promoter): - def __init__(self, name, activator, transcript = None, **keywords): + +class ActivatablePromoter(Promoter): + """ + A class for a promoter which can be activated by a single species, modelled as a positive hill function + """ + def __init__(self, name, activator, transcript = None, leak = False, **keywords): + #Always call the superclass __init__() with **keywords passed through + Promoter.__init__(self, name = name, transcript = transcript, **keywords) + #Set the Regulator #Component.set_species(species, material_type = None, attributes = None) # is a helper function that allows the input to be a Species, string, or Component. self.activator = self.set_species(activator) + + self.leak = leak #toggles whether or not there is a leak reaction - #Mechanisms are inherited from the Mixture unless set specifically in self.default_mechanisms. - custom_mechanisms = {"transcription": PositiveHillTranscription()} + #Non-default Mechanisms are added to the Component with .add_mechanism + self.add_mechanism(PositiveHillTranscription(), "transcription", overwrite = True) - #Always call the superclass __init__() with **keywords passed through - Promoter.__init__(self, name = name, transcript = transcript, mechanisms = custom_mechanisms,**keywords) def update_species(self, **keywords): #Mechanisms are stored in an automatically created dictionary: mechanism_type --> Mechanism Instance. - mech_tx = self.mechanisms["transcription"] + mech_tx = self.get_mechanism("transcription") species = [] #A list of species must be returned - species += mech_tx.update_species(dna = self.assembly.dna, transcript = self.transcript, regulator = self.activator, part_id = self.name+"_"+self.activator.name, component = self) + species += mech_tx.update_species(dna = self.dna_to_bind, transcript = self.transcript, regulator = self.activator, + part_id = self.name+"_"+self.activator.name, leak = self.leak, component = self, protein = self.get_protein_for_expression()) return species def update_reactions(self, **keywords): - mech_tx = self.mechanisms["transcription"] + mech_tx = self.get_mechanism("transcription") reactions = [] #a list of reactions must be returned - reactions += mech_tx.update_reactions(dna = self.assembly.dna, transcript = self.transcript, regulator = self.activator, - component = self, part_id = self.name+"_"+self.activator.name, **keywords) + + + reactions += mech_tx.update_reactions(dna = self.dna_to_bind, transcript = self.transcript, regulator = self.activator, + component = self, part_id = self.name+"_"+self.activator.name, leak = self.leak, protein = self.get_protein_for_expression()) + + return reactions -#A class for a promoter which can be repressed by a single species, modelled as a negative hill function -class RepressablePromotor(Promoter): - def __init__(self, name, repressor, transcript = None, **keywords): +class RepressiblePromoter(Promoter): + """ + A class for a promoter which can be repressed by a single species, modelled as a negative hill function + """ + def __init__(self, name, repressor, transcript = None, leak = False, **keywords): + #Always call the superclass __init__() with **keywords passed through + Promoter.__init__(self, name = name, transcript = transcript, **keywords) + #Set the Regulator #Component.set_species(species, material_type = None, attributes = None) # is a helper function that allows the input to be a Species, string, or Component. self.repressor = self.set_species(repressor) + + self.leak = leak #toggles whether or not there is a leak reaction #Mechanisms are inherited from the Mixture unless set specifically in self.default_mechanisms. - custom_mechanisms = {"transcription": NegativeHillTranscription()} + self.add_mechanism(NegativeHillTranscription(), "transcription", overwrite = True) + - #Always call the superclass __init__() with **keywords passed through - Promoter.__init__(self, name = name, transcript = transcript, mechanisms = custom_mechanisms,**keywords) def update_species(self, **keywords): #Mechanisms are stored in an automatically created dictionary: mechanism_type --> Mechanism Instance. - mech_tx = self.mechanisms["transcription"] + mech_tx = self.get_mechanism("transcription") species = [] #A list of species must be returned - species += mech_tx.update_species(dna = self.assembly.dna, transcript = self.transcript, regulator = self.repressor, component = self, part_id = self.name+"_"+self.repressor.name) + species += mech_tx.update_species(dna = self.dna_to_bind, transcript = self.transcript, regulator = self.repressor, component = self, + part_id = self.name+"_"+self.repressor.name, leak = self.leak, protein = self.get_protein_for_expression(), **keywords) return species def update_reactions(self, **keywords): - mech_tx = self.mechanisms["transcription"] + mech_tx = self.get_mechanism("transcription") reactions = [] #a list of reactions must be returned - reactions += mech_tx.update_reactions(dna = self.assembly.dna, transcript = self.transcript, regulator = self.repressor, - component = self, part_id = self.name+"_"+self.repressor.name, **keywords) + + reactions += mech_tx.update_reactions(dna = self.dna_to_bind, transcript = self.transcript, regulator = self.repressor, + component = self, part_id = self.name+"_"+self.repressor.name, leak = self.leak, protein = self.get_protein_for_expression(), **keywords) return reactions + class CombinatorialPromoter(Promoter): def __init__(self, name, regulators, leak = False, assembly = None, - transcript = None, length = 0, mechanisms = {}, - parameters = {},tx_capable_list = None,cooperativity = None, **keywords): + transcript = None, length = 0, mechanisms = None, + parameters = None,protein=None,tx_capable_list = None,cooperativity = None, **keywords): """ A combinatorial promoter is something where binding multiple regulators result in qualitatively different transcription behaviour. For example, maybe it's an AND @@ -200,6 +298,12 @@ def __init__(self, name, regulators, leak = False, assembly = None, can be strings or Species cooperativity: a dictionary of cooperativity values. For example, {"regulator":2,"regulator2":1,....} """ + + Promoter.__init__(self, name = name, assembly = assembly, + transcript = transcript, length = length, + mechanisms = mechanisms, parameters = parameters, protein=protein, + **keywords) + if not isinstance(regulators, list): #you could give one string as a regulator regulators = [regulators] @@ -211,14 +315,14 @@ def __init__(self, name, regulators, leak = False, assembly = None, #after we've sanitized the inputs, then sort self.regulators = sorted(self.regulators) #now let's work out the tx_capable_list - if(tx_capable_list == None): + if tx_capable_list is None: #if nothing is passed, that means everything transcribes allcomb = [] for r in range(1,len(self.regulators)+1): #make all combinations of regulators allcomb += [set(a) for a in it.combinations([a.name for a in self.regulators],r)] self.tx_capable_list = allcomb - elif(type(tx_capable_list)==list): + elif isinstance(tx_capable_list, list): #if the user passed a list then the user knows what they want newlist = [] #this part converts any species in the tx_capable_list into a string @@ -233,44 +337,42 @@ def __init__(self, name, regulators, leak = False, assembly = None, self.tx_capable_list = [set(a) for a in newlist] self.leak = leak - - self.default_mechanisms = {"binding": Combinatorial_Cooperative_Binding()} - - Promoter.__init__(self, name = name, assembly = assembly, - transcript = transcript, length = length, - mechanisms = mechanisms, parameters = parameters, - **keywords) self.complex_combinations = {} self.tx_capable_complexes = [] self.leak_complexes = [] + self.add_mechanism(Combinatorial_Cooperative_Binding(), "binding", overwrite = True) + + + def update_species(self): - mech_tx = self.mechanisms["transcription"] - mech_b = self.mechanisms['binding'] + mech_tx = self.get_mechanism("transcription") + mech_b = self.get_mechanism('binding') #set the tx_capable_complexes to nothing because we havent updated species yet! self.tx_capable_complexes = [] self.leak_complexes = [] - species = [self.assembly.dna] + species = [self.dna_to_bind]+self.regulators self.complexes = [] - bound_species = mech_b.update_species(self.regulators,self.assembly.dna,\ - component = self,part_id = self.name,cooperativity=self.cooperativity) + bound_species = mech_b.update_species(self.regulators,self.dna_to_bind,\ + component = self,part_id = self.name,cooperativity=self.cooperativity,protein=self.protein) #above is all the species with DNA bound to regulators. Now, we need to extract only the ones which #are transcribable if self.leak is not False: #this part takes care of the promoter not bound to anything - species += mech_tx.update_species(dna = self.assembly.dna, transcript = self.transcript, protein = self.assembly.protein, component = self, part_id = self.name+"_leak") + species += mech_tx.update_species(dna = self.dna_to_bind, transcript = self.transcript, protein = self.get_protein_for_expression(), component = self, part_id = self.name+"_leak") #self.leak_complexes += [] for bound_complex in bound_species: species_inside = [] for regulator in self.regulators: - if(regulator in bound_complex.species): + if(regulator in bound_complex): species_inside += [regulator.name] if(set(species_inside) in [set(a) for a in self.tx_capable_list]): #only the transcribable complexes in tx_capable_list get transcription reactions - tx_capable_species = mech_tx.update_species(dna = bound_complex, transcript = self.transcript, protein = self.assembly.protein, component = self, part_id = self.name) - species +=tx_capable_species[1:] + tx_capable_species = mech_tx.update_species(dna = bound_complex, transcript = self.transcript, \ + protein = self.get_protein_for_expression(), component = self, part_id = self.name) + species +=tx_capable_species self.tx_capable_complexes +=[bound_complex] else: #in this case there's a combination of regulators which does not feature in tx_capable_list @@ -279,27 +381,30 @@ def update_species(self): # 2) we said we wanted leak, so then you should add this, but with the "_leak" parameters # (that happens in update_reactions) if(self.leak is not False): - leak_species = mech_tx.update_species(dna = bound_complex, transcript = self.transcript, protein = self.assembly.protein, component = self, part_id = self.name+"_leak") - species += leak_species[1:] + leak_species = mech_tx.update_species(dna = bound_complex, transcript = self.transcript, \ + protein = self.get_protein_for_expression(), component = self, part_id = self.name+"_leak") + species += leak_species self.leak_complexes += [bound_complex] species+=bound_species return species def update_reactions(self): + reactions = [] - mech_tx = self.mechanisms["transcription"] - mech_b = self.mechanisms['binding'] + mech_tx = self.get_mechanism("transcription") + mech_b = self.get_mechanism('binding') if self.leak is not False: #once again the DNA not bound to anything gets special treatment - reactions += mech_tx.update_reactions(dna = self.assembly.dna, component = self, part_id = self.name+"_leak", \ - transcript = self.transcript, protein = self.assembly.protein) + reactions += mech_tx.update_reactions(dna = self.dna_to_bind, component = self, part_id = self.name+"_leak", \ + transcript = self.transcript, protein = self.protein) #the binding reactions happen no matter what - reactions += mech_b.update_reactions(self.regulators,self.assembly.dna,component = self,\ - part_id = self.name,cooperativity=self.cooperativity) - if((self.tx_capable_complexes == None) or self.tx_capable_complexes == []): - #this could mean we haven't run update_species() yet + reactions += mech_b.update_reactions(self.regulators,self.dna_to_bind,component = self,\ + part_id = self.name,cooperativity=self.cooperativity, protein = self.protein) + if((self.tx_capable_complexes is None) or self.tx_capable_complexes == []): species = self.update_species() + #this could mean we haven't run update_species() yet + if(self.tx_capable_complexes == []): if(self.leak_complexes is None or self.leak_complexes == []): #if it's still zero after running update_species then we could be in trouble @@ -322,13 +427,12 @@ def update_reactions(self): #if it's bound to RNAP then it transcribes, right? tx_partid = tx_partid+"_RNAP" reactions += mech_tx.update_reactions(dna = specie, component = self, part_id = tx_partid, \ - transcript = self.transcript, protein = self.assembly.protein) + transcript = self.transcript, protein = self.get_protein_for_expression()) if(len(self.leak_complexes)>0): for specie in self.leak_complexes: #in this case every reaction uses the "promoter_leak" partid leak_partid = self.name+"_leak" reactions += mech_tx.update_reactions(dna = specie, component = self, part_id = leak_partid, \ - transcript = self.transcript, protein = self.assembly.protein) + transcript = self.transcript, protein = self.get_protein_for_expression()) - - return reactions \ No newline at end of file + return reactions diff --git a/biocrnpyler/dna_part_rbs.py b/biocrnpyler/dna_part_rbs.py new file mode 100644 index 00000000..b2ff726e --- /dev/null +++ b/biocrnpyler/dna_part_rbs.py @@ -0,0 +1,78 @@ + +# Copyright (c) 2020, Build-A-Cell. All rights reserved. +# See LICENSE file in the project root directory for details. + +import copy + +from .dna_part import DNA_part +from .species import Species + + +class RBS(DNA_part): + """ + A simple RBS class with no regulation. Must be included in a DNAconstruct or DNAassembly to do anything. + """ + def __init__(self, name: str, assembly=None, + transcript=None, protein=None, length=0, + mechanisms=None, parameters=None, **keywords): + self.assembly = assembly + self.length = length + + DNA_part.__init__(self, name = name, mechanisms = mechanisms, + parameters = parameters, **keywords) + + if transcript is None and assembly is None: + self.transcript = None + elif transcript is None: + self.transcript = Species(assembly.name, material_type = "rna") + else: + self.transcript = self.set_species(transcript, material_type = "rna") + + if protein is None and assembly is not None: + self.protein = Species(assembly.name, material_type = "protein") + elif protein is None and assembly is None: + self.protein = None + else: + self.protein = self.set_species(protein, material_type = "protein") + + def update_species(self): + mech_tl = self.get_mechanism('translation') + species = [] + if self.protein is not None: + species += mech_tl.update_species(transcript = self.transcript, protein = self.protein, component = self, part_id = self.name) + return species + + def update_reactions(self): + mech_tl = self.get_mechanism('translation') + reactions = [] + + if self.protein is not None: + reactions += mech_tl.update_reactions(transcript = self.transcript, protein = self.protein, component = self, part_id = self.name) + return reactions + def update_component(self,dna=None,rnas=None,proteins=None,mypos=None): + """returns a copy of this component, except with the proper fields updated""" + if(proteins is None): + raise ValueError("cannot update rbs {} when proteins is None".format(self)) + my_rna = None + if(len(proteins)==1): + my_rna = list(proteins.keys())[0] + else: + #if this happens, it means we are being called from DNA + if(self.parent.get_species().material_type is not "dna"): + raise ValueError("something went wrong") + return None + out_component = None + if(self in proteins[my_rna]): + my_proteins = proteins[my_rna][self] + out_component = copy.deepcopy(self) + protein_species = [] + for CDS in my_proteins: + protein_species += CDS.update_species() + + out_component.protein = protein_species + if(mypos is not None): + out_component.transcript = dna[mypos] + else: + out_component.transcript = dna + #my_rna.get_species() + return out_component diff --git a/biocrnpyler/dna_part_terminator.py b/biocrnpyler/dna_part_terminator.py new file mode 100644 index 00000000..b0505867 --- /dev/null +++ b/biocrnpyler/dna_part_terminator.py @@ -0,0 +1,15 @@ + +# Copyright (c) 2020, Build-A-Cell. All rights reserved. +# See LICENSE file in the project root directory for details.from .dna_part import DNA_part + +from .dna_part_misc import DNA_part + + +class Terminator(DNA_part): + def __init__(self,name, **keywords): + DNA_part.__init__(self,name, **keywords) + self.name = name + def update_species(self): + return [] + def update_reactions(self): + return [] diff --git a/biocrnpyler/global_mechanism.py b/biocrnpyler/global_mechanism.py index 709e0857..4745d005 100644 --- a/biocrnpyler/global_mechanism.py +++ b/biocrnpyler/global_mechanism.py @@ -1,190 +1,299 @@ -# Copyright (c) 2019, Build-A-Cell. All rights reserved. + +# Copyright (c) 2020, Build-A-Cell. All rights reserved. # See LICENSE file in the project root directory for details. +from typing import Dict, List from warnings import warn from .mechanism import Mechanism -from .chemical_reaction_network import Reaction, Species, ComplexSpecies -from typing import List, Union - -#Global mechanisms are a lot like mechanisms. They are called only by mixtures -# on a list of all species have been generated by components. Global mechanisms are meant -# to work as universal mechanisms that function on each species or all species of some -# type or with some attribute. Global mechanisms may only act on one species at a time. -# -#In order to decide which species a global mechanism acts upon, the filter_dict is used. -# filter_dict[species.material_type / specie.attributes / species.name / repr(species)] = True / False -# For each species, its material type, name, and attributes are sent through the filter_dict. If True -# is returned, the GlobalMechanism will act on the species. If False is returned, the -# the GlobalMechanism will not be called. If there are conflicts in the filter_dict, an error is raised. -# -#If the species's name, material type, and attributes are all not in the filter_dict, the GlobalMechanism will -# be called if default_on == True and not called if default_on == False. -#Note that the above filtering is done automatically. Any parameters needed by the global mechanism must be -# in the Mixture's parameter dictionary. These methods are assumed to take a single species -# as input. -# -#An example of a global mechanism is degradation via dilution which is demonstrated in the Tests folder. -# -#GlobalMechanisms should be used cautiously or avoided alltogether - the order in which they are called -# may have to be carefully user defined in the subclasses of Mixture in order to ensure expected behavior. - - -"""Global mechanisms are a lot like mechanisms. They are called only by mixtures - on a list of all species have been generated by components. Global mechanisms - are meant to work as universal mechanisms that function on each species or - all species of some material type or with some attribute. Global mechanisms - may only act on one species at a time. - - In order to decide which species a global mechanism acts upon, the filter_dict - is used. - filter_dict[species.material_type / species.attributes] = True / False - For each species, its material type or attributes are sent through the - filter_dict. If True is returned, the GlobalMechanism will act on the - species. If False is returned, the the GlobalMechanism will not be called. - If filter_dict[attribute] is different from filter_dict[material_type], - filter_dict[attribute] takes precedent. If multiple filter_dict[attribute] - contradict for different attributes, an error is raised. - - For ComplexSpecies, filter based upon all subspecies.type. If there is a conflict, - raise a warning and go with the default. - - If the species's name, material type, and attributes are all not in the - filter_dict, the GlobalMechanism will be called if default_on == True and - not called if default_on == False. - - Note that the above filtering is done automatically. Any parameters needed by - the global mechanism must be in the Mixture's parameter dictionary. These - methods are assumed to take a single species as input. - - An example of a global mechanism is degradation via dilution which is - demonstrated in the Tests folder. +from .mechanisms_enzyme import MichaelisMenten +from .reaction import Reaction +from .species import ComplexSpecies, OrderedPolymerSpecies, Species - GlobalMechanisms should be used cautiously or avoided alltogether - the order - in which they are called may have to be carefully user defined in the - subclasses of Mixture in order to ensure expected behavior. +""" +Global mechanisms are a lot like mechanisms. They are called only by mixtures + on a list of all species have been generated by components. Global mechanisms are meant + to work as universal mechanisms that function on each species or all species of some + type or with some attribute. Global mechanisms may only act on one species at a time. + +In order to decide which species a global mechanism acts upon, the filter_dict is used. + filter_dict[species.material_type / specie.attributes / species.name / repr(species)] = True / False + For each species, its material type, name, and attributes are sent through the filter_dict. If True + is returned, the GlobalMechanism will act on the species. If False is returned, the + the GlobalMechanism will not be called. If there are conflicts in the filter_dict, an error is raised. + +If the species's name, material type, and attributes are all not in the filter_dict, the GlobalMechanism will + be called if default_on == True and not called if default_on == False. +Note that the above filtering is done automatically. Any parameters needed by the global mechanism must be + in the Mixture's parameter dictionary. These methods are assumed to take a single species + as input. + +An example of a global mechanism is degradation via dilution which is demonstrated in the Tests folder. + +GlobalMechanisms should be used cautiously or avoided alltogether - the order in which they are called +may have to be carefully user defined in the subclasses of Mixture in order to ensure expected behavior. """ class GlobalMechanism(Mechanism): - def __init__(self, name: str, mechanism_type = "", filter_dict = {}, - default_on = False): - self.filter_dict = filter_dict + """Global mechanisms are a lot like mechanisms. They are called only by mixtures + on a list of all species have been generated by components. Global mechanisms + are meant to work as universal mechanisms that function on each species or + all species of some material type or with some attribute. Global mechanisms + may only act on one species at a time. + + In order to decide which species a global mechanism acts upon, the filter_dict + is used. + + An example of a global mechanism is degradation via dilution which is + demonstrated in the Tests folder. + + GlobalMechanisms should be used cautiously or avoided alltogether - the order + in which they are called may have to be carefully user-defined in the + subclasses of Mixture in order to ensure expected behavior. + """ + def __init__(self, name: str, mechanism_type: str="", filter_dict: Dict=None, + default_on: bool=False, recursive_species_filtering: bool=False): + """Creates a GlobalMechanisms instance. + + If the species's name, material type, and attributes are all not in the + filter_dict, the GlobalMechanism will be called if default_on == True and + not called if default_on == False. + + :param name: name of the GlobalMechanism + :param mechanism_type: + :param filter_dict: filter_dict[species.material_type / species.attributes] = True / False + For each species, its material type or attributes are sent through the + filter_dict. If True is returned, the GlobalMechanism will act on the + species. If False is returned, the the GlobalMechanism will not be called. + If filter_dict[attribute] is different from filter_dict[material_type], + filter_dict[attribute] takes precedent. If multiple filter_dict[attribute] + contradict for different attributes, an error is raised. + Note that the above filtering is done automatically. Any parameters needed by + the global mechanism must be in the Mixture's parameter dictionary. These + methods are assumed to take a single species as input. + :param default_on: + :param recursive_species_filtering: keyword determines how the material_type and name of ComplexSpecies is defined. + If True: the filter based upon all subspecies.type and name recursively going through + all ComplexSpecies. If False: the filter dict will act only on the ComplexSpecies. By default, this is False. + """ + if filter_dict is None: + self.filter_dict = {} + else: + self.filter_dict = filter_dict + self.default_on = default_on + self.recursive_species_filtering = recursive_species_filtering Mechanism.__init__(self, name=name, mechanism_type=mechanism_type) def apply_filter(self, s: Species): - """ - applies the filter dictionary to determine if a global mechanism acts on a species - :param s: + """applies the filter dictionary to determine if a global mechanism acts on a species. + + :param s: Species :return: """ fd = self.filter_dict use_mechanism = None - - if isinstance(s, ComplexSpecies): - species_list = [s]+s.species - else: - species_list = [s] - + species_list = s.get_species(recursive=self.recursive_species_filtering) for subs in species_list: - for a in s.attributes+[subs.material_type, repr(subs), subs.name]: + for a in subs.attributes+[subs.material_type, subs.name]: if a in fd: - if use_mechanism == None: + if use_mechanism is None: use_mechanism = fd[a] elif use_mechanism != fd[a]: - raise AttributeError(f"species {repr(s)} has multiple attributes(or material type) which conflict with global mechanism filter {repr(self)}.") + warn(f"species {repr(s)} has multiple attributes(or material type) which conflict with global mechanism filter {repr(self)}. Using default value {self.default_on}.") + use_mechanism = self.default_on if use_mechanism is None: use_mechanism = self.default_on - return use_mechanism - def update_species_global(self, species_list: List[Species], parameters): + def update_species_global(self, species_list: List[Species], mixture): new_species = [] for s in species_list: use_mechanism = self.apply_filter(s) if use_mechanism: - new_species += self.update_species(s, parameters) + new_species += self.update_species(s, mixture) return new_species - def update_reactions_global(self, species_list: List[Species], parameters): + def update_reactions_global(self, species_list: List[Species], mixture): fd = self.filter_dict new_reactions = [] for s in species_list: use_mechanism = self.apply_filter(s) if use_mechanism: - new_reactions += self.update_reactions(s, parameters) + new_reactions += self.update_reactions(s, mixture) return new_reactions - def update_species(self, s, parameters): - """ - All global mechanisms must use update_species functions with these inputs - :param s: - :param parameters: + def get_parameter(self, species, param_name, mixture): + param = mixture.get_parameter(mechanism = self, part_id = repr(species), param_name = param_name) + if param is None: + raise ValueError("No parameters can be found that match the " + "(mechanism, part_id, " + f"param_name)=({repr(self)}, {repr(species)}, " + f"{param_name}).") + else: + return param + + def update_species(self, s: Species, mixture): + """All global mechanisms must use update_species functions with these inputs. + + :param s: Species instance :return: """ return [] - def update_reactions(self, s, parameters): - """ - All global mechanisms must use update_reactions functions with these inputs + def update_reactions(self, s, mixture): + """All global mechanisms must use update_reactions functions with these inputs. + :param s: - :param parameters: + :param mixture: :return: """ return [] - def get_parameter(self, s, parameters, param_name): - if (self.name, repr(s), param_name) in parameters: - return parameters[(self.name, repr(s), param_name)] - elif (self.mechanism_type, repr(s), param_name) in parameters: - return parameters[(self.mechanism_type, repr(s), param_name)] - elif (repr(s), param_name) in parameters: - return parameters[(repr(s), param_name)] - elif (self.name, param_name) in parameters: - return parameters[(self.name, param_name)] - elif (self.mechanism_type, param_name) in parameters: - return parameters[(self.mechanism_type, param_name)] - elif (param_name) in parameters: - return parameters[param_name] - else: - raise ValueError(f"No parameter found for GlobalMechanism name: {self.name} type: {self.mechanism_type} species: {repr(s)} param: {param_name}") - class Dilution(GlobalMechanism): + """A global mechanism to represent dilution.""" + def __init__(self, name = "global_degredation_via_dilution", - mechanism_type = "dilution", filter_dict = {}, - default_on = True): + mechanism_type = "dilution", filter_dict=None, + default_on = True, recursive_species_filtering = True): GlobalMechanism.__init__(self, name = name, mechanism_type = mechanism_type, default_on = default_on, - filter_dict = filter_dict) + filter_dict = filter_dict, + recursive_species_filtering = recursive_species_filtering) - def update_reactions(self, s: Species, parameters): - k_dil = self.get_parameter(s, parameters, "kdil") - rxn = Reaction([s], [], k_dil) + def update_reactions(self, s: Species, mixture): + k_dil = self.get_parameter(s, "kdil", mixture) + rxn = Reaction.from_massaction(inputs=[s], outputs=[], k_forward=k_dil) return [rxn] - - - class AnitDilutionConstiutiveCreation(GlobalMechanism): - """ - Global Mechanism to Constitutively Create Certain Species at the rate of dilution. + """Global Mechanism to Constitutively Create Certain Species at the rate of dilution. + Useful for keeping machinery species like ribosomes and polymerases at a constant concentration. """ def __init__(self, name = "anti_dilution_constiuitive_creation", - material_type = "dilution", filter_dict = {}, - default_on = True): + material_type="dilution", filter_dict=None, + default_on = True, recursive_species_filtering = True): GlobalMechanism.__init__(self, name = name, mechanism_type = material_type, default_on = default_on, - filter_dict = filter_dict) + filter_dict = filter_dict, + recursive_species_filtering = recursive_species_filtering) - def update_reactions(self, s, parameters): - k_dil = parameters["kdil"] - rxn = Reaction([], [s], k_dil) + def update_reactions(self, s, parameters, mixture): + k_dil = self.get_parameter(s, "kdil", mixture) + rxn = Reaction.from_massaction(inputs=[], outputs=[s], k_forward=k_dil) return [rxn] + + + +class Degredation_mRNA_MM(GlobalMechanism, MichaelisMenten): + """Michaelis Menten mRNA Degredation by Endonucleases + mRNA + Endo <--> mRNA:Endo --> Endo + All species of type "rna" are degraded by this mechanisms, including those inside of a ComplexSpecies. + ComplexSpecies are seperated by this process, including embedded ComplexSpecies. + OrderedPolymerSpecies are ignored. + """ + def __init__(self, nuclease, name="rna_degredation_mm", mechanism_type = "rna_degredation", **keywords): + if isinstance(nuclease, Species): + self.nuclease = nuclease + else: + raise ValueError("'nuclease' must be a Species.") + MichaelisMenten.__init__(self=self, name=name, mechanism_type = mechanism_type) + + GlobalMechanism.__init__(self, name = name, mechanism_type = mechanism_type, default_on = False, + filter_dict = {"rna":True, "notdegradable":False}, recursive_species_filtering = True) + + def update_species(self, s, mixture): + species = [] + + #Check if rna species are inside a ComplexSpecies. + #If so, break up the ComplexSpecies and degrade the RNA + if isinstance(s, ComplexSpecies) and s.material_type != "rna" and not isinstance(s, OrderedPolymerSpecies): + internal_species = s.get_species(recursive = True) + non_rna_species = [sp for sp in internal_species if sp.material_type != "rna" and sp != s] + if len(non_rna_species)>0: + prod = non_rna_species + else: + prod = None + species += MichaelisMenten.update_species(self, Enzyme = self.nuclease, Sub = s, Prod = prod) + + #If the material type is simply RNA, break it up. + elif s.material_type == "rna": + species += MichaelisMenten.update_species(self, Enzyme = self.nuclease, Sub = s, Prod = None) + else: + #This case includes OrderedPolymerSpecies with RNA inside them and species with RNA in their name (but not mateiral type) + species = [] + + return species + + def update_reactions(self, s, mixture): + reactions = [] + + #Check if rna species are inside a ComplexSpecies. + #If so, break up the ComplexSpecies and degrade the RNA + + + + if isinstance(s, ComplexSpecies) and s.material_type != "rna" and not isinstance(s, OrderedPolymerSpecies): + kdeg = self.get_parameter(s, "kdeg", mixture) + kb = self.get_parameter(s, "kb", mixture) + ku = self.get_parameter(s, "ku", mixture) + + internal_species = s.get_species(recursive = True) + non_rna_species = [sp for sp in internal_species if sp.material_type != "rna" and sp != s] + if len(non_rna_species)>0: + prod = non_rna_species + else: + prod = None + reactions += MichaelisMenten.update_reactions(self, Enzyme = self.nuclease, Sub = s, Prod = prod, kb=kb, ku=ku, kcat=kdeg) + + #If the material type is simply RNA, break it up. + elif s.material_type == "rna": + kdeg = self.get_parameter(s, "kdeg", mixture) + kb = self.get_parameter(s, "kb", mixture) + ku = self.get_parameter(s, "ku", mixture) + + reactions += MichaelisMenten.update_reactions(self, Enzyme = self.nuclease, Sub = s, Prod = None, kb=kb, ku=ku, kcat=kdeg) + else: + #This case includes OrderedPolymerSpecies with RNA inside them and species with RNA in their name (but not mateiral type) + reactions = [] + + return reactions + + +class Deg_Tagged_Degredation(GlobalMechanism, MichaelisMenten): + """Michaelis Menten Degredation of deg-tagged proteins by Proteases + Species_degtagged + protease <--> Species_degtagged:protease --> protease + All species with the attribute degtagged and material_type protein are degraded. The method is not recursive. + """ + def __init__(self, protease, deg_tag = "degtagged", name="deg_tagged_degredation", mechanism_type="degredation", **keywords): + if isinstance(protease, Species): + self.protease = protease + else: + raise ValueError("'protease' must be a Species.") + MichaelisMenten.__init__(self=self, name=name, mechanism_type=mechanism_type) + + GlobalMechanism.__init__(self, name = name, mechanism_type = mechanism_type, default_on = False, + filter_dict = {deg_tag:True}, recursive_species_filtering = False) + + def update_species(self, s, mixture): + species = [] + species += MichaelisMenten.update_species(self, Enzyme = self.protease, Sub = s, Prod = None) + return species + + def update_reactions(self, s, mixture): + + kdeg = self.get_parameter(s, "kdeg", mixture) + kb = self.get_parameter(s, "kb", mixture) + ku = self.get_parameter(s, "ku", mixture) + + rxns = [] + rxns += MichaelisMenten.update_reactions(self, Enzyme = self.protease, Sub = s, Prod = None, kb=kb, ku=ku, kcat=kdeg) + return rxns diff --git a/biocrnpyler/mechanism.py b/biocrnpyler/mechanism.py index ee59beee..2d4ada81 100644 --- a/biocrnpyler/mechanism.py +++ b/biocrnpyler/mechanism.py @@ -1,38 +1,13 @@ -# mechanism.py - mechanism class for implementing TX-TL mechanisms -# RMM, 16 Aug 2018 -# -# Mechanisms the means by which all reactions in a TX-TL reaction are -# established. Mechanisms can be overridden to allow specialized -# processing of core reactions (eg, adding additional detail, using -# simplified models, etc. -# -# Mechanisms are established in the following order (lower levels -# override higher levels): -# -# Default extract mechanisms -# Default mechanisms -# Mechanisms passed to Component() [eg DNA Assembly] -# Mechanisms based to Sub) [eg, DNA elements] -# -# This hierarchy allows reactions to be created without the user -# having to specify any alternative mechanisms (defaults will be -# used), but also allows the user to override all mechanisms used for -# every (e.g, by giving an alternative transcription -# mechanisms when setting up an extract) or individual mechanisms for -# a given (by passing an alternative mechanism just to that -# . -# -# Copyright (c) 2018, Build-A-Cell. All rights reserved. -# See LICENSE file in the project root directory for details. +# Copyright (c) 2020, Build-A-Cell. All rights reserved. +# See LICENSE file in the project root directory for details. +from typing import List from warnings import warn -from .chemical_reaction_network import Species, Reaction, ComplexSpecies, Multimer -from .component import Component -import itertools as it + class Mechanism(object): - """Mechanism class for core mechanisms + """Mechanism class for core mechanisms. Core mechanisms within a mixture (transcription, translation, etc) @@ -41,24 +16,29 @@ class Mechanism(object): derived from this class. """ - def __init__(self, name, mechanism_type=""): + def __init__(self, name: str, mechanism_type=""): + """Initializes a Mechanism instance. + + :param name: name of the Mechanism + :param mechanism_type: mechanism_type in string + """ self.name = name self.mechanism_type = mechanism_type if mechanism_type == "" or mechanism_type is None: warn(f"Mechanism {name} instantiated without a type. This could " "prevent the mechanism from being inherited properly.") - def update_species(self, component = None, part_id = None): - """ - the child class should implement this method + def update_species(self, component=None, part_id=None) -> List: + """the child class should implement this method. + :return: empty list """ warn(f"Default Update Species Called for Mechanism = {self.name}.") return [] - def update_reactions(self, component = None, part_id = None): - """ - the child class should implement this method + def update_reactions(self, component=None, part_id=None) -> List: + """ the child class should implement this method. + :return: empty list """ warn(f"Default Update Reactions Called for Mechanism = {self.name}.") @@ -69,11 +49,17 @@ def __repr__(self): class EmptyMechanism(Mechanism): + """For use when one needs a Mechanism to do nothing, such as translation in Expression Mixtures.""" def __init__(self, name, mechanism_type): + """Initializes an EmptyMechanism instance. + + :param name: name of the Mechanism + :param mechanism_type: mechanism_type in string + """ Mechanism.__init__(self, name=name, mechanism_type=mechanism_type) - def update_species(self, component = None, part_id = None, **keywords): + def update_species(self, component=None, part_id=None, **keywords): return [] - def update_reactions(self, component = None, part_id = None, **keywords): - return [] \ No newline at end of file + def update_reactions(self, component=None, part_id=None, **keywords): + return [] diff --git a/biocrnpyler/mechanisms_binding.py b/biocrnpyler/mechanisms_binding.py index 26f08862..db821688 100644 --- a/biocrnpyler/mechanisms_binding.py +++ b/biocrnpyler/mechanisms_binding.py @@ -1,32 +1,54 @@ -from .mechanism import * -from .chemical_reaction_network import Species, Reaction, ComplexSpecies, Multimer + +# Copyright (c) 2020, Build-A-Cell. All rights reserved. +# See LICENSE file in the project root directory for details. + +import itertools as it + +from .mechanism import Mechanism +from .reaction import Reaction +from .species import Complex, Multimer, Species, WeightedSpecies + class Reversible_Bimolecular_Binding(Mechanism): - def __init__(self, name="reversible_bimolecular_binding", - mechanism_type="bimolecular_binding"): + """A Mechanism to model s1 + s2 <--> s1:s2.""" + def __init__(self, name: str="reversible_bimolecular_binding", + mechanism_type: str="bimolecular_binding"): + """Initializes a Reversible_Bimolecular_Binding instance + + :param name: name of the Mechanism, default: reversible_bimolecular_binding + :param mechanism_type: type of the Mechanism, default: bimolecular_binding + """ Mechanism.__init__(self, name=name, mechanism_type=mechanism_type) - def update_species(self, s1, s2, **keywords): - complexS = ComplexSpecies([s1, s2]) + def update_species(self, s1: Species, s2: Species, **keywords): + """ + + :param s1: + :param s2: + :param keywords: + :return: + """ + # TODO ZAT: remove unused keyword argument! + complexS = Complex([s1, s2]) return [s1, s2, complexS] def update_reactions(self, s1, s2, component = None, kb = None, ku = None, \ part_id = None,complex=None, **keywords): - #Get Parameters + # Get Parameters if part_id is None: repr(s1)+"_"+repr(s2) - if kb is None and component != None: + if kb is None and component is not None: kb = component.get_parameter("kb", part_id = part_id, mechanism = self) - if ku is None and component != None: + if ku is None and component is not None: ku = component.get_parameter("ku", part_id = part_id, mechanism = self) if component is None and (kb is None or ku is None): raise ValueError("Must pass in a Component or values for kb, ku.") - if(complex==None): - complexS = ComplexSpecies([s1, s2]) + if complex is None : + complexS = Complex([s1, s2]) else: complexS = complex - rxns = [Reaction([s1, s2], [complexS], k=kb, k_rev=ku)] + rxns = [Reaction.from_massaction([s1, s2], [complexS], k_forward=kb, k_reverse=ku)] return rxns @@ -44,7 +66,7 @@ def update_species(self, binder, bindee, complex_species = None, cooperativity=N part_id = repr(binder)+"-"+repr(bindee) if cooperativity is None and component != None: - cooperativity = component.get_parameter("cooperativity", part_id = part_id, mechanism = self) + cooperativity = component.get_parameter("cooperativity", part_id = part_id, mechanism = self, return_numerical = True) elif component is None and cooperativity is None: raise ValueError("Must pass in a Component or values for cooperativity") @@ -52,9 +74,6 @@ def update_species(self, binder, bindee, complex_species = None, cooperativity=N if complex_species is None: complex_name = None material_type = None - elif isinstance(complex_species, str): - complex_name = complex_species - material_type = None elif isinstance(complex_species, Species): complexS = complex_species material_type = complex_species.material_type @@ -62,38 +81,48 @@ def update_species(self, binder, bindee, complex_species = None, cooperativity=N raise TypeError("complex_species keyword must be a str, Species, or None.") if complexS is None: - complexS = ComplexSpecies([binder]*int(cooperativity)+[bindee], name = complex_name, material_type = material_type) + complexS = Complex([binder]*int(cooperativity)+[bindee], name = complex_name, material_type = material_type) return [binder, bindee, complexS] def update_reactions(self, binder, bindee, complex_species = None, component = None, kb = None, ku = None, part_id = None, cooperativity=None, **kwords): - complexS = self.update_species(binder, bindee, cooperativity = cooperativity, part_id = part_id, component = component, **kwords)[-1] - - #Get Parameters + # Get Parameters if part_id is None: part_id = repr(binder)+"-"+repr(bindee) - if kb is None and component != None: + if kb is None and component is not None: kb = component.get_parameter("kb", part_id = part_id, mechanism = self) - if ku is None and component != None: + if ku is None and component is not None: ku = component.get_parameter("ku", part_id = part_id, mechanism = self) - if cooperativity is None and component != None: - cooperativity = component.get_parameter("cooperativity", part_id = part_id, mechanism = self) + if cooperativity is None and component is not None: + cooperativity = component.get_parameter("cooperativity", part_id = part_id, mechanism = self, return_numerical = True) if component is None and (kb is None or ku is None or cooperativity is None): raise ValueError("Must pass in a Component or values for kb, ku, and coopertivity.") + complexS = None + if complex_species is None: + complex_name = None + material_type = None + elif isinstance(complex_species, Species): + complexS = complex_species + material_type = complex_species.material_type + else: + raise TypeError("complex_species keyword must be a str, Species, or None.") + + if complexS is None: + complexS = Complex([binder]*int(cooperativity)+[bindee], name = complex_name, material_type = material_type) + + inputs = [WeightedSpecies(species=binder, stoichiometry=cooperativity), + WeightedSpecies(species=bindee, stoichiometry=1)] - rxns = [] - rxns += [ - Reaction(inputs=[binder, bindee], outputs=[complexS], - input_coefs=[cooperativity, 1], output_coefs=[1], k=kb, - k_rev=ku)] + rxns = [Reaction.from_massaction(inputs=inputs, outputs=[complexS], k_forward=kb, k_reverse=ku)] return rxns class Two_Step_Cooperative_Binding(Mechanism): - """A reaction where n binders (s1) bind to 1 bindee (s2) in two steps + """A reaction where n binders (s1) bind to 1 bindee (s2) in two steps. + n A <--> nx_A nx_A <--> nx_A:B """ @@ -107,7 +136,7 @@ def update_species(self, binder, bindee, component = None, complex_species = Non part_id = repr(binder)+"-"+repr(bindee) if cooperativity is None and component != None: - cooperativity = component.get_parameter("cooperativity", part_id = part_id, mechanism = self) + cooperativity = component.get_parameter("cooperativity", part_id = part_id, mechanism = self, return_numerical = True) elif component is None and cooperativity is None: raise ValueError("Must pass in a Component or values for cooperativity") @@ -139,10 +168,11 @@ def update_species(self, binder, bindee, component = None, complex_species = Non raise TypeError("complex_species keyword must be a str, Species, or None. Not "+str(complex_species)) if complexS is None: - complexS = ComplexSpecies([n_mer, bindee], name = complex_name) + complexS = Complex([n_mer, bindee], name = complex_name) return [binder, bindee, complexS, n_mer] - def update_reactions(self, binder, bindee, kb = None, ku = None, component = None, part_id = None, cooperativity=None, complex_species = None, n_mer_species = None, **keywords): + def update_reactions(self, binder, bindee, kb = None, ku = None, component = None, part_id = None, \ + cooperativity=None, complex_species = None, n_mer_species = None, **keywords): """ Returns reactions: cooperativity binder <--> n_mer, kf = kb1, kr = ku1 @@ -158,12 +188,12 @@ def update_reactions(self, binder, bindee, kb = None, ku = None, component = Non if part_id is None: repr(binder)+"-"+repr(bindee) - if (kb is None or ku is None or cooperativity is None) and Component != None: + if (kb is None or ku is None or cooperativity is None) and component != None: kb1 = component.get_parameter("kb1", part_id = part_id, mechanism = self) kb2 = component.get_parameter("kb2", part_id = part_id, mechanism = self) ku1 = component.get_parameter("ku1", part_id = part_id, mechanism = self) ku2 = component.get_parameter("ku2", part_id = part_id, mechanism = self) - cooperativity = component.get_parameter("cooperativity", part_id = part_id, mechanism = self) + cooperativity = component.get_parameter("cooperativity", part_id = part_id, mechanism = self, return_numerical = True) elif component is None and (kb is None or ku is None or cooperativity is None): raise ValueError("Must pass in a Component or values for kb, ku, and cooperativity") elif len(kb) != len(ku) != 2: @@ -172,17 +202,16 @@ def update_reactions(self, binder, bindee, kb = None, ku = None, component = Non else: kb1, kb2 = kb ku1, ku2 = ku - n_mer_name = f"{cooperativity}x_{binder.material_type}_{binder.name}" - n_mer = ComplexSpecies([binder], name = n_mer_name) - binder, bindee, complexS, n_mer = self.update_species(binder, bindee, component = component, complex_species = complex_species, n_mer_species = n_mer_species, cooperativity=cooperativity, part_id = part_id, **keywords) + binder, bindee, complexS, n_mer = self.update_species(binder, bindee, component = component, \ + complex_species = complex_species, n_mer_species = n_mer_species,\ + cooperativity=cooperativity, part_id = part_id, **keywords) + inputs_for_rxn1 = [WeightedSpecies(species=binder, stoichiometry=cooperativity)] rxns = [ - Reaction(inputs=[binder], outputs=[n_mer], - input_coefs=[cooperativity], output_coefs=[1], k=kb1, - k_rev=ku1), - Reaction(inputs=[n_mer, bindee], outputs=[complexS], k=kb2, - k_rev=ku2)] + Reaction.from_massaction(inputs=inputs_for_rxn1, outputs=[n_mer], k_forward=kb1, k_reverse=ku1), + Reaction.from_massaction(inputs=[n_mer, bindee], outputs=[complexS], k_forward=kb2, k_reverse=ku2) + ] return rxns @@ -190,11 +219,17 @@ class Combinatorial_Cooperative_Binding(Mechanism): """a reaction where some number of binders bind combinatorially to a bindee""" def __init__(self,name="Combinatorial_Cooperative_binding", mechanism_type="cooperative_binding"): + """Initializes a Combinatorial_Cooperative_Binding instance + + :param name: name of the Mechanism, default: Combinatorial_Cooperative_binding + :param mechanism_type: type of the Mechanism, default: cooperative_binding + """ Mechanism.__init__(self,name,mechanism_type) + def make_cooperative_complex(self,combo,bindee,cooperativity): """given a list of binders and their cooperativities, make a complex that contains the binders present N number of times where N is - each one's cooperativity""" + each one's cooperativity.""" complexed_species_list = [] for binder in combo: binder_cooperativity = int(cooperativity[binder.name]) @@ -207,25 +242,26 @@ def make_cooperative_complex(self,combo,bindee,cooperativity): if(len(complexed_species_list)==1): myspecies = complexed_species_list[0] else: - myspecies = ComplexSpecies(complexed_species_list) + myspecies = Complex(complexed_species_list) return myspecies def update_species(self,binders,bindee,cooperativity=None,\ component = None, part_id = None, **kwords): cooperativity_dict = {} + out_species = [] for binder in binders: binder_partid = part_id+"_"+binder.name if ((cooperativity is None) or (type(cooperativity)==dict and binder_partid not in cooperativity) \ and (component is not None)): #here we are extracting the relevant cooperativity value from the dictionary which should be passed #in as the cooperativity argument - coop_val = component.get_parameter("cooperativity", part_id = binder_partid, mechanism = self) + coop_val = component.get_parameter("cooperativity", part_id = binder_partid, mechanism = self, return_numerical = True) elif type(cooperativity)==dict and binder_partid in cooperativity: coop_val = cooperativity[binder_partid] if component is None and ( cooperativity is None): raise ValueError("Must pass in a Component or values for kb, ku, and coopertivity.") cooperativity_dict[binder.name]=coop_val - out_species = [] + for i in range(1, len(binders)+1): for combo in it.combinations(binders,i): #go through every possible combination of reactants and dna and make @@ -252,7 +288,7 @@ def update_reactions(self,binders,bindee,component=None,kbs=None,kus=None,\ raise ValueError("Must pass in a Component or values for kb, ku, and coopertivity.") if ((cooperativity is None) or (type(cooperativity)==dict and binder.name not in cooperativity) \ and component is not None): - coop_val = component.get_parameter("cooperativity", part_id = binder_partid, mechanism = self) + coop_val = component.get_parameter("cooperativity", part_id = binder_partid, mechanism = self, return_numerical = True) elif type(cooperativity)==dict and binder.name in cooperativity: coop_val = cooperativity[binder.name] if component is None and (kb is None or ku is None or cooperativity is None): @@ -281,19 +317,32 @@ def update_reactions(self,binders,bindee,component=None,kbs=None,kus=None,\ continue else: reactant_complex = self.make_cooperative_complex(reactant,bindee,coop_dict) - reaction = Reaction(inputs=[binder, reactant_complex], outputs=[product], - input_coefs=[binder_params[binder]["cooperativity"], 1], output_coefs=[1], \ - k=binder_params[binder]["kb"],k_rev=binder_params[binder]["ku"]) + + inputs = [WeightedSpecies(species=binder, stoichiometry=binder_params[binder]["cooperativity"]), + WeightedSpecies(species=reactant_complex, stoichiometry=1)] + + reaction = Reaction.from_massaction(inputs=inputs, outputs=[product], + k_forward=binder_params[binder]["kb"], + k_reverse=binder_params[binder]["ku"]) rxndict[rxn_prototype]=reaction return [rxndict[a] for a in rxndict] class One_Step_Binding(Mechanism): + """ + A mechanism to model the binding of a list of species, eg + S1 + S2 ... SN <--> S1:S2:...:SN + """ def __init__(self, name="one_step_binding", mechanism_type="binding"): Mechanism.__init__(self, name, mechanism_type) - def update_species(self, species, component = None, complex_species = None, part_id = None, **keywords): + def update_species(self, binder,bindee, component = None, complex_species = None, part_id = None, **keywords): + if(not isinstance(binder,list)): + binder = [binder] + if(not isinstance(bindee,list)): + bindee = [bindee] + species = binder+bindee if part_id is None: part_id = "" for s in species: @@ -301,30 +350,29 @@ def update_species(self, species, component = None, complex_species = None, part part_id = part_id[:-1] if complex_species is None: - complex_species = ComplexSpecies(species) + complex_species = Complex(species) return species + [complex_species] - - def update_reactions(self, species, component = None, complex_species = None, part_id = None, kb = None, ku = None, **keywords): + def update_reactions(self, binder,bindee, component = None, complex_species = None, part_id = None, kb = None, ku = None, **keywords): + if(not isinstance(binder,list)): + binder = [binder] + if(not isinstance(bindee,list)): + bindee = [bindee] + species = binder+bindee if part_id is None: part_id = "" for s in species: part_id += s.name+"_" part_id = part_id[:-1] - if (kb is None or ku is None) and Component != None: + if (kb is None or ku is None) and component != None: kb = component.get_parameter("kb", part_id = part_id, mechanism = self) ku = component.get_parameter("ku", part_id = part_id, mechanism = self) elif component is None and (kb is None or ku is None): raise ValueError("Must pass in a Component or values for kb and ku") if complex_species is None: - complex_species = ComplexSpecies(species) - - return [Reaction(inputs = species, outputs = [complex_species], k = kb, k_rev = ku)] - - - - + complex_species = Complex(species) + return [Reaction.from_massaction(inputs=species, outputs=[complex_species], k_forward=kb, k_reverse=ku)] diff --git a/biocrnpyler/mechanisms_enzyme.py b/biocrnpyler/mechanisms_enzyme.py index 13bad0db..7878d40d 100644 --- a/biocrnpyler/mechanisms_enzyme.py +++ b/biocrnpyler/mechanisms_enzyme.py @@ -1,13 +1,18 @@ -from warnings import warn -from .mechanism import * -from .chemical_reaction_network import Species, Reaction, ComplexSpecies, Multimer +from .mechanism import Mechanism +from .reaction import Reaction +from .species import Complex class BasicCatalysis(Mechanism): - """ - Mechanism for the schema S + C --> P + C - """ - def __init__(self, name = "basic_catalysis", mechanism_type = "catalysis", **keywords): + """Mechanism for the schema S + C --> P + C.""" + def __init__(self, name: str="basic_catalysis", mechanism_type: str="catalysis", **keywords): + """Initializes a BasicCatalysis instance. + + :param name: name of the Mechanism, default: basic_catalysis + :param mechanism_type: type of the Mechanism, default: catalysis + :param keywords: + """ + # TODO ZAT: remove unused keywords argument Mechanism.__init__(self, name, mechanism_type) def update_species(self, Enzyme, Sub, Prod = None, **keywords): @@ -25,13 +30,19 @@ def update_reactions(self, Enzyme, Sub, Prod, component = None, part_id = None, elif kcat is None: kcat = component.get_parameter("kcat", part_id = part_id, mechanism = self) - return [Reaction([Enzyme, Sub], [Enzyme, Prod], kcat)] + return [Reaction.from_massaction(inputs=[Enzyme, Sub], outputs=[Enzyme, Prod], k_forward=kcat)] + class BasicProduction(Mechanism): - """ - Mechanism for the schema C --> P + C - """ - def __init__(self, name = "basic_production", mechanism_type = "catalysis", **keywords): + """Mechanism for the schema C --> P + C.""" + def __init__(self, name="basic_production", mechanism_type="catalysis", **keywords): + """Initializes a BasicProduction instance. + + :param name: name of the Mechanism, default: basic_production + :param mechanism_type: type of the Mechanism, default: catalysis + :param keywords: + """ + # TODO ZAT: remove unused keywords argument Mechanism.__init__(self, name, mechanism_type) def update_species(self, Enzyme, Sub = None, Prod = None, **keywords): @@ -59,20 +70,29 @@ def update_reactions(self, Enzyme, Sub, Prod, component = None, part_id = None, if Sub is not None: inputs += [Sub] - return [Reaction(inputs, outputs, kcat)] + return [Reaction.from_massaction(inputs=inputs, outputs=outputs, k_forward=kcat)] + + +class MichaelisMenten(Mechanism): + """Mechanism to automatically generate Michaelis-Menten Type Reactions. -class MichalisMenten(Mechanism): - """Mechanism to automatically generate Michalis-Menten Type Reactions In the Copy RXN version, the Substrate is not Consumed Sub+Enz <--> Sub:Enz --> Enz+Prod """ - def __init__(self, name = "michalis_menten", mechanism_type = "catalysis", **keywords): + def __init__(self, name="michalis_menten", mechanism_type="catalysis", **keywords): + """Initializes a MichaelisMenten instance. + + :param name: name of the Mechanism, default: michalis_menten + :param mechanism_type: type of the Mechanism, default: catalysis + :param keywords: + """ + # TODO ZAT: remove unused keywords argument Mechanism.__init__(self, name, mechanism_type) def update_species(self, Enzyme, Sub, Prod = None, complex=None, **keywords): if complex is None: - complexS = ComplexSpecies([Sub, Enzyme]) + complexS = Complex([Sub, Enzyme]) else: complexS = complex if Prod is None: @@ -82,11 +102,11 @@ def update_species(self, Enzyme, Sub, Prod = None, complex=None, **keywords): def update_reactions(self, Enzyme, Sub, Prod, component = None, part_id = None, complex=None, kb=None, ku=None, kcat=None, **keywords): - #Get Parameters - if part_id == None and component != None: + # Get Parameters + if part_id is None and component is not None: part_id = component.name - if component == None and (kb == None or ku == None or kcat == None): + if component is None and (kb is None or ku is None or kcat is None): raise ValueError("Must pass in a Component or values for kb, ku, and kcat.") if kb is None: kb = component.get_parameter("kb", part_id = part_id, mechanism = self) @@ -94,43 +114,54 @@ def update_reactions(self, Enzyme, Sub, Prod, component = None, part_id = None, ku = component.get_parameter("ku", part_id = part_id, mechanism = self) if kcat is None: kcat = component.get_parameter("kcat", part_id = part_id, mechanism = self) - if complex is None: - complexS = ComplexSpecies([Sub, Enzyme]) + complexS = Complex([Sub, Enzyme]) else: complexS = complex # Sub + Enz <--> Sub:Enz - binding_rxn = Reaction(inputs=[Sub, Enzyme], outputs=[complexS], - k=kb, k_rev=ku) + binding_rxn = Reaction.from_massaction(inputs=[Sub, Enzyme], + outputs=[complexS], + k_forward=kb, + k_reverse=ku) if Prod is not None: # Sub:Enz --> Enz + Prod - cat_rxn = Reaction(inputs=[complexS], - outputs=[Prod, Enzyme], k=kcat) + cat_rxn = Reaction.from_massaction(inputs=[complexS], + outputs=[Prod, Enzyme], + k_forward=kcat) else: # Degradation Reaction # Sub:Enz --> Enz - cat_rxn = Reaction(inputs=[complexS], outputs=[Enzyme], - k=kcat) + cat_rxn = Reaction.from_massaction(inputs=[complexS], + outputs=[Enzyme], + k_forward=kcat) return [binding_rxn, cat_rxn] -class MichalisMentenReversible(Mechanism): - """Mechanism to automatically generate Michalis-Menten Type Reactions with products that can bind to enzymes +class MichaelisMentenReversible(Mechanism): + """Mechanism to automatically generate Michaelis-Menten Type Reactions with products that can bind to enzymes. + In the Copy RXN version, the Substrate is not Consumed - Sub+Enz <--> Sub:Enz --> Enz:Prod <--> Enz + Prod + Sub+Enz <--> Sub:Enz <--> Enz:Prod <--> Enz + Prod """ - def __init__(self, name = "michalis_menten_reverse_binding", mechanism_type = "catalysis", **keywords): + def __init__(self, name="michalis_menten_reverse_binding", mechanism_type="catalysis", **keywords): + """Initializes a MichaelisMentenReversible instance. + + :param name: name of the Mechanism, default: michalis_menten_reverse_binding + :param mechanism_type: type of the Mechanism, default: catalysis + :param keywords: + """ + # TODO ZAT: remove unused keywords argument Mechanism.__init__(self, name, mechanism_type) def update_species(self, Enzyme, Sub, Prod, complex=None, complex2 = None, **keywords): if complex is None: - complex1 = ComplexSpecies([Sub, Enzyme]) + complex1 = Complex([Sub, Enzyme]) else: complex1 = complex if complex2 is None: - complex2 = ComplexSpecies([Prod, Enzyme]) + complex2 = Complex([Prod, Enzyme]) else: complex2 = complex2 return [Enzyme, Sub, Prod, complex1, complex2] @@ -138,10 +169,10 @@ def update_species(self, Enzyme, Sub, Prod, complex=None, complex2 = None, **key def update_reactions(self, Enzyme, Sub, Prod, component = None, part_id = None, complex=None, complex2 = None, kb=None, ku=None, kcat=None, **keywords): #Get Parameters - if part_id == None and component != None: + if part_id is None and component is not None: part_id = component.name - if component == None and (kb == None or ku == None or kcat == None): + if component is None and (kb is None or ku is None or kcat is None): raise ValueError("Must pass in a Component or values for kb, ku, and kcat.") if kb is None: kb1 = component.get_parameter("kb1", part_id = part_id, mechanism = self) @@ -161,70 +192,88 @@ def update_reactions(self, Enzyme, Sub, Prod, component = None, part_id = None, if complex is None: - complex1 = ComplexSpecies([Sub, Enzyme]) + complex1 = Complex([Sub, Enzyme]) else: complex1 = complex if complex2 == None: - complex2 = ComplexSpecies([Prod, Enzyme]) + complex2 = Complex([Prod, Enzyme]) # Sub + Enz <--> Sub:Enz - binding_rxn1 = Reaction(inputs=[Sub, Enzyme], outputs=[complex1], - k=kb1, k_rev=ku1) + binding_rxn1 = Reaction.from_massaction(inputs=[Sub, Enzyme], + outputs=[complex1], + k_forward=kb1, + k_reverse=ku1) - binding_rxn2 = Reaction(inputs=[Prod, Enzyme], outputs=[complex2], - k=kb2, k_rev=ku2) + binding_rxn2 = Reaction.from_massaction(inputs=[Prod, Enzyme], + outputs=[complex2], + k_forward=kb2, + k_reverse=ku2) # Sub:Enz --> Enz:Prod - cat_rxn = Reaction(inputs=[complex1], outputs=[complex2], k=kcat, k_rev = kcat_rev) + cat_rxn = Reaction.from_massaction(inputs=[complex1], + outputs=[complex2], + k_forward=kcat, + k_reverse=kcat_rev) return [binding_rxn1, binding_rxn2, cat_rxn] -class MichalisMentenCopy(Mechanism): - """In the Copy RXN version, the Substrate is not Consumed +class MichaelisMentenCopy(Mechanism): + """In the Copy RXN version, the Substrate is not Consumed. + Sub+Enz <--> Sub:Enz --> Sub+Enz+Prod """ - def __init__(self, name = "michalis_menten_copy", mechanism_type = "copy", **keywords): + def __init__(self, name="michalis_menten_copy", mechanism_type="copy", **keywords): + """Initializes a MichaelisMentenCopy instance. + + :param name: name of the Mechanism, default: michalis_menten_copy + :param mechanism_type: type of the Mechanism, default: copy + :param keywords: + """ + # TODO ZAT: remove unused keywords argument Mechanism.__init__(self, name, mechanism_type) def update_species(self, Enzyme, Sub, complex=None, Prod = None, **keywords): if complex is None: - complexS = ComplexSpecies([Sub, Enzyme]) + complexS = Complex([Sub, Enzyme]) else: complexS = complex - + if Prod is None: return [Enzyme, Sub, complexS] + elif(type(Prod)==list): + return [Enzyme,Sub,complexS]+Prod else: return [Enzyme, Sub, Prod, complexS] def update_reactions(self, Enzyme, Sub, Prod, component = None, part_id = None, complex=None, kb=None, ku=None, kcat=None, **keywords): if complex is None: - complexS = ComplexSpecies([Sub, Enzyme]) + complexS = Complex([Sub, Enzyme]) else: complexS = complex - - #Get Parameters - if part_id == None and component != None: + # Get Parameters + if part_id is None and component is not None: part_id = component.name - if kb == None and component != None: + if kb is None and component is not None: kb = component.get_parameter("kb", part_id = part_id, mechanism = self) - if ku == None and component != None: + if ku is None and component is not None: ku = component.get_parameter("ku", part_id = part_id, mechanism = self) - if kcat == None and component != None: + if kcat is None and component is not None: kcat = component.get_parameter("kcat", part_id = part_id, mechanism = self) - if component == None and (kb == None or ku == None or kcat == None): + if component is None and (kb is None or ku is None or kcat is None): raise ValueError("Must pass in a Component or values for kb, ku, and kcat.") # Sub + Enz <--> Sub:Enz - binding_rxn = Reaction(inputs=[Sub, Enzyme], outputs=[complexS], - k=kb, k_rev=ku) + binding_rxn = Reaction.from_massaction(inputs=[Sub, Enzyme], + outputs=[complexS], + k_forward=kb, + k_reverse=ku) # Sub:Enz --> Enz + Prod + Sub - cat_rxn = Reaction(inputs=[complexS], outputs=[Sub, Prod, Enzyme], - k=kcat) + cat_rxn = Reaction.from_massaction(inputs=[complexS], + outputs=[Sub, Prod, Enzyme], + k_forward=kcat) return [binding_rxn, cat_rxn] - diff --git a/biocrnpyler/mechanisms_txtl.py b/biocrnpyler/mechanisms_txtl.py index 21214291..7caf7dea 100644 --- a/biocrnpyler/mechanisms_txtl.py +++ b/biocrnpyler/mechanisms_txtl.py @@ -1,300 +1,367 @@ -from .mechanism import * -from .chemical_reaction_network import Species, Reaction, ComplexSpecies, Multimer -from .mechanisms_enzyme import * +from .mechanism import Mechanism +from .mechanisms_enzyme import MichaelisMentenCopy +from .propensities import ProportionalHillNegative, ProportionalHillPositive +from .reaction import Reaction +from .species import Complex, Species -class Transcription_MM(MichalisMentenCopy): - """Michalis Menten Transcription - G + RNAP <--> G:RNAP --> G+RNAP+mRNA +class OneStepGeneExpression(Mechanism): + """A mechanism to model gene expression without transcription or translation. + + G --> G + P """ + def __init__(self, name="gene_expression", + mechanism_type="transcription"): + """Initializes a OneStepGeneExpression instance. - def __init__(self, name="transcription_mm", rnap="RNAP", **keywords): - if isinstance(rnap, Species): - self.rnap = rnap - elif isinstance(rnap, str): - self.rnap = Species(name=rnap, material_type="protein") - elif isinstance(rnap, Component) and rnap.get_species() != None: - self.rnap = rnap.get_species() - else: - raise ValueError( - "'rnap' parameter must be a string or a Component with defined " - "get_species(), or a chemical_reaction_network.Species object") + :param name: name of the Mechanism, default: gene_expression + :param mechanism_type: type of the Mechanism, default: transcription - MichalisMentenCopy.__init__(self=self, name=name, - mechanism_type="transcription") + """ + Mechanism.__init__(self, name=name, mechanism_type=mechanism_type) - def update_species(self, dna, transcript=None, return_rnap=True, - **keywords): + def update_species(self, dna, protein, transcript=None, **keywords): species = [dna] - if return_rnap: - species += [self.rnap] - - species += MichalisMentenCopy.update_species(self, self.rnap, dna) - if transcript is None: - transcript = Species(dna.name, material_type="rna") - - species += [transcript] + if protein is not None: + species += [protein] return species - def update_reactions(self, dna, component, part_id = None, complex=None, transcript=None, - **keywords): - - #Get Parameters - if part_id == None and component != None: - part_id = component.name - - ktx = component.get_parameter("ktx", part_id = part_id, mechanism = self) - kb = component.get_parameter("kb", part_id = part_id, mechanism = self) - ku = component.get_parameter("ku", part_id = part_id, mechanism = self) - - rxns = [] - if transcript is None: - transcript = Species(dna.name, material_type="rna") - rxns += MichalisMentenCopy.update_reactions(self, self.rnap, dna, transcript, - complex=complex, kb=kb, - ku=ku, kcat=ktx) - - return rxns - + def update_reactions(self, dna, component = None, kexpress = None, + protein=None, transcript = None, part_id = None, **keywords): -class Translation_MM(MichalisMentenCopy): - """ Michalis Menten Translation - mRNA + Rib <--> mRNA:Rib --> mRNA + Rib + Protein - """ + if kexpress is None and component is not None: + kexpress = component.get_parameter("kexpress", part_id = part_id, mechanism = self) + elif component is None and kexpress is None: + raise ValueError("Must pass in component or a value for kexpress") - def __init__(self, name="translation_mm", ribosome="Ribo", **keywords): - if isinstance(ribosome, Species): - self.ribosome = ribosome - elif isinstance(ribosome, str): - self.ribosome = Species(name=ribosome, material_type="ribosome") - elif isinstance(ribosome, Component) and ribosome.get_species() != None: - self.ribosome = ribosome.get_species() + if protein is not None: + return [Reaction.from_massaction(inputs=[dna], outputs=[dna, protein], k_forward=kexpress)] else: - raise ValueError( - "'ribosome' parameter must be a string, a Component with defined " - "get_species, or a chemical_reaction_network.species") - MichalisMentenCopy.__init__(self=self, name=name, - mechanism_type="translation") - - def update_species(self, transcript, protein=None, - return_ribosome=True, **keywords): - species = [transcript] - if return_ribosome: - species += [self.ribosome] - if protein is None: - protein = Species(transcript.name, material_type="protein") - species += [protein] - - species += MichalisMentenCopy.update_species(self, self.ribosome, transcript) + return [] - return species - - def update_reactions(self, transcript, component, part_id = None, complex=None, - protein=None, **keywords): - rxns = [] - - #Get Parameters - if part_id == None and component != None: - part_id = component.name - - ktl = component.get_parameter("ktl", part_id = part_id, mechanism = self) - kb = component.get_parameter("kb", part_id = part_id, mechanism = self) - ku = component.get_parameter("ku", part_id = part_id, mechanism = self) - - if protein is None: - protein = Species(transcript.name, material_type="protein") - rxns += MichalisMentenCopy.update_reactions(self, self.ribosome, transcript, - protein, complex=complex, - kb=kb, ku=ku, - kcat=ktl) - return rxns +class SimpleTranscription(Mechanism): + """A Mechanism to model simple catalytic transcription. -class Degredation_mRNA_MM(MichalisMenten): - """Michalis Menten mRNA Degredation by Endonucleases - mRNA + Endo <--> mRNA:Endo --> Endo + G --> G + T """ - def __init__(self, name="rna_degredation_mm", nuclease="RNAase", - **keywords): - if isinstance(nuclease, Species): - self.nuclease = nuclease - elif isinstance(nuclease, str): - self.nuclease = Species(name=nuclease, material_type="protein") - else: - raise ValueError("'nuclease' parameter requires a " - "chemical_reaction_network.species or a string") - MichalisMenten.__init__(self=self, name=name, - mechanism_type="rna_degredation") - - def update_species(self, rna, return_nuclease=True, **keywords): - species = [rna] - if return_nuclease: - species += [self.nuclease] - species += MichalisMenten.update_species(self, self.nuclease, rna) - return species + def __init__(self, name="simple_transcription", mechanism_type="transcription"): + """Initializes a SimpleTranscription instance. - def update_reactions(self, rna, component, part_id = None, complex=None, **keywords): + :param name: name of the Mechanism, default: simple_transcription + :param mechanism_type: type of the Mechanism, default: transcription - #Get Parameters - if part_id == None and component != None: - part_id = component.name - - kdeg = component.get_parameter("kdeg", part_id = part_id, mechanism = self) - kb = component.get_parameter("kb", part_id = part_id, mechanism = self) - ku = component.get_parameter("ku", part_id = part_id, mechanism = self) - - rxns = [] - rxns += MichalisMenten.update_reactions(self, self.nuclease, rna, Prod=None, complex=complex, kb=kb, ku=ku, kcat=kdeg) - return rxns - -class SimpleTranscription(Mechanism): - def __init__(self, name = "simple_transcription", mechanism_type = "transcription"): + """ Mechanism.__init__(self, name=name, mechanism_type=mechanism_type) - def update_species(self, dna, transcript = None, **keywords): - if transcript is None: - transcript = Species(dna.name, material_type="rna") + def update_species(self, dna, transcript = None, protein = None, **keywords): - return [dna, transcript] + species = [dna] + if transcript is not None: + species += [transcript] + if protein is not None: + species += [protein] + + return species - def update_reactions(self, dna, component = None, ktx = None, part_id = None, transcript = None, **keywords): + def update_reactions(self, dna, component = None, ktx = None, part_id = None, transcript = None, protein = None, **keywords): - if ktx == None and Component != None: + if ktx == None and component != None: ktx = component.get_parameter("ktx", part_id = part_id, mechanism = self) elif component == None and ktx == None: raise ValueError("Must pass in component or a value for ktx") - if transcript is None: - transcript = Species(dna.name, material_type="rna") + #First case only true in Mixtures without transcription (eg Expression Mixtures) + if transcript is None and protein is not None: + ktl = component.get_parameter("ktl", part_id = part_id, mechanism = self) + rxns = [Reaction.from_massaction(inputs = [dna], outputs = [dna, protein], k_forward=ktx * ktl)] + else: + rxns = [Reaction.from_massaction(inputs = [dna], outputs = [dna, transcript], k_forward=ktx)] - rxns = [Reaction(inputs = [dna], outputs = [dna, transcript], k = ktx)] return rxns + class SimpleTranslation(Mechanism): - def __init__(self, name = "simple_translation", mechanism_type = "translation"): + """A mechanism to model simple catalytic translation. + + T --> T + P + """ + def __init__(self, name="simple_translation", mechanism_type="translation"): + """Initializes a SimpleTranslation instance. + + :param name: name of the Mechanism, default: simple_translation + :param mechanism_type: type of the Mechanism, default: translation + + """ Mechanism.__init__(self, name=name, mechanism_type=mechanism_type) def update_species(self, transcript, protein = None, **keywords): if protein is None: protein = Species(transcript.name, material_type="protein") - - return [transcript, protein] + outlst = [transcript] + if(type(protein)==list): + outlst+=protein + else: + outlst+=[protein] + return outlst def update_reactions(self, transcript, component = None, ktl = None, part_id = None, protein = None, **keywords): - if ktl == None and Component != None: + if ktl is None and component is not None: ktl = component.get_parameter("ktl", part_id = part_id, mechanism = self) - elif component == None and ktl == None: + elif component is None and ktl is None: raise ValueError("Must pass in component or a value for ktl") - if protein is None: - protein = Species(transcript.name, material_type="protein") + # First case only true in Mixtures without transcription (eg Expression Mixtures) + if transcript is None and protein is not None: + rxns = [] + else: + rxns = [Reaction.from_massaction(inputs = [transcript], outputs = [transcript, protein], k_forward=ktl)] - rxns = [Reaction(inputs = [transcript], outputs = [transcript, protein], k = ktl)] return rxns -class OneStepGeneExpression(Mechanism): - def __init__(self, name="gene_expression", - mechanism_type="transcription"): - Mechanism.__init__(self, name=name, mechanism_type=mechanism_type) - - def update_species(self, dna, protein=None, transcript=None, **keywords): - species = [dna] - if protein == None: - protein = Species(dna.name, material_type="protein") - - species += [protein] - return species - def update_reactions(self, dna, component = None, kexpress = None, - protein=None, transcript = None, part_id = None, **keywords): - - if kexpress == None and Component != None: - kexpress = component.get_parameter("kexpress", part_id = part_id, mechanism = self) - elif component == None and kexpress == None: - raise ValueError("Must pass in component or a value for kexpress") +class PositiveHillTranscription(Mechanism): + """A mechanism to model transcription as a proprotional positive hill function: + G --> G + P + rate = k*G*(R^n)/(K+R^n) + where R is a regulator (activator). + Optionally includes a leak reaction + G --> G + P @ rate kleak. + """ - if protein is None: - protein = Species(dna.name, material_type="protein") - rxns = [Reaction(inputs=[dna], outputs=[dna, protein], k = kexpress)] - return rxns + def __init__(self, name="positivehill_transcription", mechanism_type="transcription"): + """Initializes a PositiveHillTranscription instance. + :param name: name of the Mechanism, default: positivehill_transcription + :param mechanism_type: type of the Mechanism, default: transcription -class PositiveHillTranscription(Mechanism): - #Set the name and mechanism_type - def __init__(self, name="positivehill_transcription", mechanism_type="transcription"): + """ Mechanism.__init__(self, name=name, mechanism_type=mechanism_type) - #Overwrite update_species - def update_species(self, dna, regulator, transcript = None, **keywords): - - if transcript is None: #Species names can be automatically created - transcript = Species(dna.name, material_type = "rna") + def update_species(self, dna, regulator, transcript = None, leak = False, protein = None, **keywords): - return [dna, transcript, regulator] #it is best to return all species that will be involved in the reactions + species = [dna, regulator] + if transcript is not None: + species += [transcript] + if protein is not None: + species += [protein] + return species # it is best to return all species that will be involved in the reactions - #Overwrite update_reactions - #This always requires the inputs component and part_id to find the relevant parameters - def update_reactions(self, dna, regulator, component, part_id, transcript = None, **keywords): + def update_reactions(self, dna, regulator, component, part_id, transcript = None, leak = False, protein = None, **keywords): + """This always requires the inputs component and part_id to find the relevant parameters - if transcript is None: #Species names should be automatically created the same here as above - transcript = Species(dna.name, material_type = "rna") + :param dna: + :param regulator: + :param component: + :param part_id: + :param transcript: + :param leak: + :param protein: + :param keywords: + :return: + """ ktx = component.get_parameter("k", part_id = part_id, mechanism = self) n = component.get_parameter("n", part_id = part_id, mechanism = self) K = component.get_parameter("K", part_id = part_id, mechanism = self) kleak = component.get_parameter("kleak", part_id = part_id, mechanism = self) - params = {"k":ktx, "n":n, "K":K, "s1":regulator, "d":dna} + prophill = ProportionalHillPositive(k=ktx, K=K, s1=regulator, n=n, d=dna) - reaction = Reaction(inputs = [dna], outputs = [dna, transcript], - propensity_type = "proportionalhillpositive", propensity_params = params) + reactions = [] - reaction_leak = Reaction(inputs = [dna], outputs = [dna, transcript], k = kleak) + #First case only true in Mixtures without transcription (eg Expression Mixtures) + if transcript is None and protein is not None: + tx_output = protein + else: + tx_output = transcript + + reactions.append(Reaction(inputs=[dna], outputs=[dna, tx_output], propensity_type=prophill)) + + if leak: + reactions.append(Reaction.from_massaction(inputs=[dna], outputs=[dna, tx_output], k_forward=kleak)) #In this case, we just return one reaction - return [reaction, reaction_leak] + return reactions + class NegativeHillTranscription(Mechanism): - #Set the name and mechanism_type + """A mechanism to model transcription as a proprotional negative hill function: + G --> G + P + rate = k*G*(1)/(K+R^n) + where R is a regulator (repressor). + Optionally includes a leak reaction + G --> G + P @ rate kleak. + """ + def __init__(self, name="negativehill_transcription", mechanism_type="transcription"): + """Initializes a NegativeHillTranscription instance. + + :param name: name of the Mechanism, default: negativehill_transcription + :param mechanism_type: type of the Mechanism, default: transcription + + """ Mechanism.__init__(self, name=name, mechanism_type=mechanism_type) - #Overwrite update_species - def update_species(self, dna, regulator, transcript = None, **keywords): + def update_species(self, dna, regulator, transcript = None, leak = False, protein = None, **keywords): - if transcript is None: #Species names can be automatically created - transcript = Species(dna.name, material_type = "rna") + species = [dna, regulator] + if transcript is not None: + species += [transcript] + if protein is not None: + species += [protein] - return [dna, transcript, regulator] #it is best to return all species that will be involved in the reactions + return species # it is best to return all species that will be involved in the reactions - #Overwrite update_reactions - #This always requires the inputs component and part_id to find the relevant parameters - def update_reactions(self, dna, regulator, component, part_id, transcript = None, **keywords): + def update_reactions(self, dna, regulator, component, part_id, transcript = None, leak = False, protein = None, **keywords): + """This always requires the inputs component and part_id to find the relevant parameters - if transcript is None: #Species names should be automatically created the same here as above - transcript = Species(dna.name, material_type = "rna") + :param dna: + :param regulator: + :param component: + :param part_id: + :param transcript: + :param leak: + :param protein: + :param keywords: + :return: + """ ktx = component.get_parameter("k", part_id = part_id, mechanism = self) n = component.get_parameter("n", part_id = part_id, mechanism = self) K = component.get_parameter("K", part_id = part_id, mechanism = self) kleak = component.get_parameter("kleak", part_id = part_id, mechanism = self) - params = {"k":ktx, "n":n, "K":K, "s1":regulator, "d":dna} + prop_hill = ProportionalHillNegative(k=ktx, K=K, n=n, s1=regulator, d=dna) - reaction = Reaction(inputs = [dna], outputs = [dna, transcript], - propensity_type = "proportionalhillnegative", propensity_params = params) + reactions = [] + + #First case only true in Mixtures without transcription (eg Expression Mixtures) + if transcript is None and protein is not None: + tx_output = protein + else: + tx_output = transcript - reaction_leak = Reaction(inputs = [dna], outputs = [dna, transcript], k = kleak) + reactions.append(Reaction(inputs=[dna], outputs=[dna, tx_output], propensity_type=prop_hill)) + + if leak: + reactions.append(Reaction.from_massaction(inputs = [dna], outputs = [dna, tx_output], k_forward=kleak)) #In this case, we just return one reaction - return [reaction, reaction_leak] + return reactions + + +class Transcription_MM(MichaelisMentenCopy): + """Michaelis Menten Transcription. + + G + RNAP <--> G:RNAP --> G+RNAP+mRNA + """ + + def __init__(self, rnap: Species, name="transcription_mm", **keywords): + """Initializes a Transcription_MM instance. + + :param rnap: Species instance that is representing an RNA polymerase + :param name: name of the Mechanism, default: transcription_mm + """ + if isinstance(rnap, Species): + self.rnap = rnap + else: + raise ValueError("'rnap' parameter must be a Species.") + + MichaelisMentenCopy.__init__(self=self, name=name, + mechanism_type="transcription") + + def update_species(self, dna, transcript=None, protein = None, **keywords): + species = [dna] + + if transcript is None and protein is not None: + tx_output = protein + else: + tx_output = transcript + + species += MichaelisMentenCopy.update_species(self, Enzyme = self.rnap, Sub = dna, Prod = tx_output) + + return species + + def update_reactions(self, dna, component, part_id = None, complex=None, transcript=None, protein = None, + **keywords): + + #Get Parameters + if part_id == None and component != None: + part_id = component.name + + ktx = component.get_parameter("ktx", part_id = part_id, mechanism = self) + kb = component.get_parameter("kb", part_id = part_id, mechanism = self) + ku = component.get_parameter("ku", part_id = part_id, mechanism = self) + + rxns = [] + + if transcript is None and protein is not None: + tx_output = protein + else: + tx_output = transcript + + rxns += MichaelisMentenCopy.update_reactions(self, Enzyme = self.rnap, Sub = dna, Prod = tx_output, complex=complex, kb=kb, ku=ku, kcat=ktx) + + return rxns + + +class Translation_MM(MichaelisMentenCopy): + """Michaelis Menten Translation. + + mRNA + Rib <--> mRNA:Rib --> mRNA + Rib + Protein + """ + + def __init__(self, ribosome: Species, name="translation_mm", **keywords): + """Initializes a Translation_MM instance. + + :param rnap: Species instance that is representing a ribosome + :param name: name of the Mechanism, default: translation_mm + """ + if isinstance(ribosome, Species): + self.ribosome = ribosome + else: + raise ValueError("ribosome must be a Species!") + MichaelisMentenCopy.__init__(self=self, name=name, + mechanism_type="translation") + + def update_species(self, transcript, protein, **keywords): + species = [] + + #This can only occur in expression mixtures + if transcript is None and protein is not None: + species += Species.flatten_list([protein]) + else: + species += MichaelisMentenCopy.update_species(self, Enzyme = self.ribosome, Sub = transcript, Prod = protein) + + return species + + def update_reactions(self, transcript, protein, component, part_id = None, complex=None, **keywords): + rxns = [] + + #Get Parameters + if part_id == None and component != None: + part_id = component.name + + ktl = component.get_parameter("ktl", part_id = part_id, mechanism = self) + kb = component.get_parameter("kb", part_id = part_id, mechanism = self) + ku = component.get_parameter("ku", part_id = part_id, mechanism = self) + + + #This can only occur in expression mixtures + if transcript is None and protein is not None: + pass + else: + rxns += MichaelisMentenCopy.update_reactions(self, Enzyme = self.ribosome, Sub = transcript, Prod = protein, complex=complex, kb=kb, ku=ku, kcat=ktl) + return rxns + class multi_tx(Mechanism): - ''' - Multi-RNAp Transcription w/ Isomerization: + """Multi-RNAp Transcription w/ Isomerization. + Detailed transcription mechanism accounting for each individual RNAp occupancy states of gene. @@ -309,109 +376,97 @@ class multi_tx(Mechanism): DNA:RNAp_n_c --> DNA with n open configuration RNAp and 1 closed configuration RNAp on it For more details, see examples/MultiTX_Demo.ipynb - ''' - - # initialize mechanism subclass - def __init__(self, pol, name='multi_tx', mechanism_type='transcription', **keywords): + """ - if isinstance(pol,str): - self.pol = Species(name=pol, material_type='protein') + def __init__(self, pol: Species, name: str='multi_tx', mechanism_type: str='transcription', **keywords): + """Initializes a multi_tx instance. - elif isinstance(pol,Species): + :param pol: reference to a species instance that represents a polymerase + :param name: name of the Mechanism, default: multi_tx + :param mechanism_type: type of the mechanism, default: transcription + :param keywords: + """ + if isinstance(pol, Species): self.pol = pol - else: - raise ValueError("'pol' must be a string or Species") + raise ValueError("'pol' must be a Species") - - Mechanism.__init__(self, name=name, mechanism_type=mechanism_type, **keywords) + Mechanism.__init__(self, name=name, mechanism_type=mechanism_type) # species update - def update_species(self, dna, transcript, component, part_id, **keywords): - max_occ = int(component.get_parameter("max_occ", part_id = part_id, mechanism = self)) + def update_species(self, dna, transcript, component, part_id, protein = None, **keywords): + max_occ = int(component.get_parameter("max_occ", part_id = part_id, mechanism = self, return_numerical = True)) cp_open = [] cp_closed = [] - for n in range(1,max_occ + 1): - name_open = self.pol.name + 'x' + dna.name + '_' + str(n) - cp_open.append(ComplexSpecies([dna]+[self.pol for i in range(n)],name=name_open)) - if n > 1: - name_closed = self.pol.name + 'x' + dna.name + '_closed' + '_' + str(n-1) - cp_closed.append(ComplexSpecies([dna]+[self.pol for i in range(n-1)],name=name_closed)) - else: - name_closed = self.pol.name + 'x' + dna.name + '_closed' + '_' + str(0) - cp_closed.append(ComplexSpecies([dna]+[self.pol for i in range(1)],name=name_closed)) + for n in range(0,max_occ): + cp_open.append(Complex([dna]+[self.pol for i in range(n+1)], attributes = ["open"])) + cp_closed.append(Complex([dna]+[self.pol for i in range(n+1)], attributes = ["closed"])) cp_misc = [self.pol,dna,transcript] - return cp_open + cp_closed + cp_misc - def update_reactions(self, dna, transcript, component, part_id, **keywords): + def update_reactions(self, dna, transcript, component, part_id, protein = None, **keywords): + """It sets up the following reactions. - ''' - DNA:RNAp_n + RNAp <--> DNA:RNAp_n_c --> DNA:RNAp_n+1 - kf1 = k1, kr1 = k2, kf2 = k_iso - DNA:RNAp_n --> DNA:RNAp_0 + n RNAp + n mRNA - kf = ktx_solo - DNA:RNAp_n_c --> DNA:RNAp_0_c + n RNAp + n mRNA - kf = ktx_solo + DNA:RNAp_n + RNAp <--> DNA:RNAp_n_c --> DNA:RNAp_n+1 + kf1 = k1, kr1 = k2, kf2 = k_iso + DNA:RNAp_n --> DNA:RNAp_0 + n RNAp + n mRNA + kf = ktx_solo + DNA:RNAp_n_c --> DNA:RNAp_0_c + n RNAp + n mRNA + kf = ktx_solo - max_occ = maximum occupancy of gene (physical limit) - ''' + max_occ = maximum occupancy of gene (physical limit) + """ # parameter loading - k1 = component.get_parameter("k1", part_id = part_id, mechanism = self) - k2 = component.get_parameter("k2", part_id = part_id, mechanism = self) + kb = component.get_parameter("kb", part_id = part_id, mechanism = self) + ku = component.get_parameter("ku", part_id = part_id, mechanism = self) k_iso = component.get_parameter("k_iso", part_id = part_id, mechanism = self) - ktx_solo = component.get_parameter("ktx_solo", part_id = part_id, mechanism = self) - max_occ = int(component.get_parameter("max_occ", part_id = part_id, mechanism = self)) + ktx = component.get_parameter("ktx", part_id = part_id, mechanism = self) + max_occ = int(component.get_parameter("max_occ", part_id = part_id, mechanism = self, return_numerical = True)) # complex species instantiation cp_open = [] cp_closed = [] - for n in range(1,max_occ + 1): - name_open = self.pol.name + 'x' + dna.name + '_' + str(n) - cp_open.append(ComplexSpecies([dna]+[self.pol for i in range(n)],name=name_open)) - if n > 1: - name_closed = self.pol.name + 'x' + dna.name + '_closed' + '_' + str(n-1) - cp_closed.append(ComplexSpecies([dna]+[self.pol for i in range(n-1)],name=name_closed)) - else: - name_closed = self.pol.name + 'x' + dna.name + '_closed' + '_' + str(0) - cp_closed.append(ComplexSpecies([dna]+[self.pol for i in range(1)],name=name_closed)) + for n in range(0,max_occ): + cp_open.append(Complex([dna]+[self.pol for i in range(n+1)], attributes = ["open"])) #has n polymerases all open + cp_closed.append(Complex([dna]+[self.pol for i in range(n+1)], attributes = ["closed"])) #has n-1 open polymerases and 1 closed polymerase # Reactions - # polymerase + complex(n) --> complex(n_closed) - rxn_open_pf = [Reaction(inputs=[self.pol, cp_open[n]], outputs=[cp_closed[n+1]], k=k1) for n in range(0,max_occ-1)] - rxn_open_pr = [Reaction(inputs=[cp_closed[n+1]], outputs=[self.pol, cp_open[n],], k=k2) for n in range(0,max_occ-1)] + # polymerase + complex(n) <--> complex(n+1)_closed + rxn_open_p = [Reaction.from_massaction(inputs=[self.pol, cp_open[n]], outputs=[cp_closed[n+1]], k_forward=kb, k_reverse = ku) for n in range(0, max_occ-1)] + #rxn_open_pr = [Reaction.from_massaction(inputs=[cp_closed[n + 1]], outputs=[self.pol, cp_open[n], ], k_forward=k2) for n in range(0, max_occ - 1)] # isomerization - rxn_iso = [Reaction(inputs=[cp_closed[n]], outputs=[cp_open[n]], k=k_iso) for n in range(0,max_occ)] + #complex(n)_closes --> complex(n) + rxn_iso = [Reaction.from_massaction(inputs=[cp_closed[n]], outputs=[cp_open[n]], k_forward=k_iso) for n in range(0, max_occ)] # release/transcription from open and closed states rxn_release_open = [] rxn_release_closed = [] for n in range(0,max_occ): - rxn_temp1 = Reaction(inputs= [cp_open[n]], outputs=[self.pol for i in range(n+1)] + - [transcript for i in range(n+1)] + [dna], k=ktx_solo) + rxn_temp1 = Reaction.from_massaction(inputs= [cp_open[n]], outputs=[self.pol for i in range(n+1)] + + [transcript for i in range(n+1)] + [dna], k_forward=ktx) rxn_release_open.append(rxn_temp1) for n in range(1,max_occ): - rxn_temp2 = Reaction(inputs= [cp_closed[n]], outputs=[self.pol for i in range(n)] + - [transcript for i in range(n)] + [cp_closed[0]], k=ktx_solo) + rxn_temp2 = Reaction.from_massaction(inputs= [cp_closed[n]], outputs=[self.pol for i in range(n)] + + [transcript for i in range(n)] + [cp_closed[0]], k_forward=ktx) rxn_release_closed.append(rxn_temp2) - # missing reactions (0 --> 0_closed and v.v. 0_closed --> 0) - rxn_m1 = Reaction(inputs=[dna,self.pol], outputs=[cp_closed[0]], k=k1) - rxn_m2 = Reaction(inputs=[cp_closed[0]], outputs=[dna,self.pol], k=k2) + # base case pol + dna <--> complex(n=1)_open + rxn_m1 = Reaction.from_massaction(inputs=[dna, self.pol], outputs=[cp_closed[0]], k_forward=kb, k_reverse = ku) - rxn_all = rxn_open_pf + rxn_open_pr + rxn_iso + rxn_release_open + rxn_release_closed + [rxn_m1, rxn_m2] + rxn_all = rxn_open_p + rxn_iso + rxn_release_open + rxn_release_closed + [rxn_m1] return rxn_all + class multi_tl(Mechanism): - ''' - Multi-RBZ Translation w/ Isomerization: + """Multi-RBZ Translation w/ Isomerization. + Detailed translation mechanism accounting for each individual RBZ occupancy states of mRNA. Still needs some work, so use with caution, read all warnings and consult the example notebook. @@ -427,104 +482,86 @@ class multi_tl(Mechanism): mRNA:RBZ_n_c --> mRNA with n open configuration RBZ and 1 closed configuration RBZ on it For more details, see examples/MultiTX_Demo.ipynb - ''' + """ - # initialize mechanism subclass - def __init__(self, ribosome, name='multi_tl', mechanism_type='translation', **keywords): + def __init__(self, ribosome: Species, name: str='multi_tl', mechanism_type: str='translation', **keywords): + """Initializes a multi_tl instance. - if isinstance(ribosome,str): - self.ribosome = Species(name=ribosome, material_type='protein') + :param ribosome: a Species instance that represents a ribosome + :param name: name of the Mechanism, default: multi_tl + :param mechanism_type: type of the Mechanism, default: translation - elif isinstance(ribosome,Species): + """ + if isinstance(ribosome, Species): self.ribosome = ribosome - else: - raise ValueError("'ribosome' must be a string or Species") - - warn('This mechanism still needs some extra validation, use at your own peril and read the warnings!') - warn("To properly use this mechanism, set dilution for mRNA-RBZ complexes!") - warn("I've set RBZ and mRNA-RBZ complexes as protein Species to apply dilution to them, edit if you want something else!") + raise ValueError("'ribosome' must be a Species.") - Mechanism.__init__(self, name=name, mechanism_type=mechanism_type, **keywords) + Mechanism.__init__(self, name=name, mechanism_type=mechanism_type) # species update def update_species(self, transcript, protein, component, part_id, **keywords): - max_occ = int(component.get_parameter("max_occ", part_id = part_id, mechanism = self)) + max_occ = int(component.get_parameter("max_occ", part_id = part_id, mechanism = self, return_numerical = True)) cp_open = [] cp_closed = [] - for n in range(1,max_occ + 1): - name_open = self.ribosome.name + 'x' + transcript.name + '_' + str(n) - cp_open.append(ComplexSpecies([transcript]+[self.ribosome for i in range(n)],name=name_open)) + for n in range(0, max_occ): + cp_open.append(Complex([transcript]+[self.ribosome for i in range(n+1)], attributes = ["open"])) + cp_closed.append(Complex([transcript]+[self.ribosome for i in range(n+1)], attributes = ["closed"])) - if n > 1: - name_closed = self.ribosome.name + 'x' + transcript.name + '_closed' + '_' + str(n-1) - cp_closed.append(ComplexSpecies([transcript]+[self.ribosome for i in range(n-1)],name=name_closed)) - else: - name_closed = self.ribosome.name + 'x' + transcript.name + '_closed' + '_' + str(0) - cp_closed.append(ComplexSpecies([transcript]+[self.ribosome for i in range(1)],name=name_closed)) - - - cp_misc = [self.ribosome,transcript,protein] + cp_misc = [self.ribosome, transcript, protein] return cp_open + cp_closed + cp_misc def update_reactions(self, transcript, protein, component, part_id, **keywords): - ''' - mRNA:RBZ_n + RBZ <--> mRNA:RBZ_n_c --> mRNA:RBZ_n+1 - kf1 = kbr, kr1 = kur, kf2 = k_iso_r - mRNA:RBZ_n --> mRNA:RBZ_0 + n RBZ + n Protein - kf = ktl_solo - mRNA:RBZ_n_c --> mRNA:RBZ_0_c + n RBZ + n Protein - kf = ktl_solo - ''' + """It sets up the following reactions. - # parameter loading - kbr = component.get_parameter("kbr", part_id = part_id, mechanism = self) - kur = component.get_parameter("kur", part_id = part_id, mechanism = self) - k_iso_r = component.get_parameter("k_iso_r", part_id = part_id, mechanism = self) - ktl_solo = component.get_parameter("ktl_solo", part_id = part_id, mechanism = self) - max_occ = int(component.get_parameter("max_occ", part_id = part_id, mechanism = self)) + mRNA:RBZ_n + RBZ <--> mRNA:RBZ_n_c --> mRNA:RBZ_n+1 + kf1 = kbr, kr1 = kur, kf2 = k_iso_r + mRNA:RBZ_n --> mRNA:RBZ_0 + n RBZ + n Protein + kf = ktl_solo + mRNA:RBZ_n_c --> mRNA:RBZ_0_c + n RBZ + n Protein + kf = ktl_solo + """ + # parameter loading + kb = component.get_parameter("kb", part_id = part_id, mechanism = self) + ku = component.get_parameter("ku", part_id = part_id, mechanism = self) + k_iso = component.get_parameter("k_iso", part_id = part_id, mechanism = self) + ktl = component.get_parameter("ktl", part_id = part_id, mechanism = self) + max_occ = int(component.get_parameter("max_occ", part_id = part_id, mechanism = self, return_numerical = True)) # complex species instantiation cp_open = [] cp_closed = [] - for n in range(1,max_occ + 1): - name_open = self.ribosome.name + 'x' + transcript.name + '_' + str(n) - cp_open.append(ComplexSpecies([transcript]+[self.ribosome for i in range(n)],name=name_open)) - - if n > 1: - name_closed = self.ribosome.name + 'x' + transcript.name + '_closed' + '_' + str(n-1) - cp_closed.append(ComplexSpecies([transcript]+[self.ribosome for i in range(n-1)],name=name_closed)) - else: - name_closed = self.ribosome.name + 'x' + transcript.name + '_closed' + '_' + str(0) - cp_closed.append(ComplexSpecies([transcript]+[self.ribosome for i in range(1)],name=name_closed)) + for n in range(0,max_occ): + cp_open.append(Complex([transcript]+[self.ribosome for i in range(n+1)], attributes = ["open"])) + cp_closed.append(Complex([transcript]+[self.ribosome for i in range(n+1)], attributes = ["closed"])) # Reactions - # ribosome + complex(n) --> complex(n_closed) - rxn_open_pf = [Reaction(inputs=[self.ribosome, cp_open[n]], outputs=[cp_closed[n+1]], k=kbr) for n in range(0,max_occ-1)] - rxn_open_pr = [Reaction(inputs=[cp_closed[n+1]], outputs=[self.ribosome, cp_open[n],], k=kur) for n in range(0,max_occ-1)] + # ribosome + complex(n) <--> complex(n+1)_closed + rxn_open_p = [Reaction.from_massaction(inputs=[self.ribosome, cp_open[n]], outputs=[cp_closed[n+1]], k_forward=kb, k_reverse = ku) for n in range(0, max_occ-1)] # isomerization - rxn_iso = [Reaction(inputs=[cp_closed[n]], outputs=[cp_open[n]], k=k_iso_r) for n in range(0,max_occ)] + # complex(n)_closed --> complex(n) + rxn_iso = [Reaction.from_massaction(inputs=[cp_closed[n]], outputs=[cp_open[n]], k_forward=k_iso) for n in range(0, max_occ)] # release/translation from open and closed states rxn_release_open = [] rxn_release_closed = [] for n in range(0,max_occ): - rxn_temp1 = Reaction(inputs= [cp_open[n]], outputs=[self.ribosome for i in range(n+1)] + - [protein for i in range(n+1)] + [transcript], k=ktl_solo) + rxn_temp1 = Reaction.from_massaction(inputs= [cp_open[n]], outputs=[self.ribosome for i in range(n+1)] + + [protein for i in range(n+1)] + [transcript], k_forward=ktl) rxn_release_open.append(rxn_temp1) for n in range(1,max_occ): - rxn_temp2 = Reaction(inputs= [cp_closed[n]], outputs=[self.ribosome for i in range(n)] + - [protein for i in range(n)] + [cp_closed[0]], k=ktl_solo) + rxn_temp2 = Reaction.from_massaction(inputs= [cp_closed[n]], outputs=[self.ribosome for i in range(n)] + + [protein for i in range(n)] + [cp_closed[0]], k_forward=ktl) rxn_release_closed.append(rxn_temp2) # missing reactions (0 --> 0_closed and v.v. 0_closed --> 0) - rxn_m1 = Reaction(inputs=[transcript,self.ribosome], outputs=[cp_closed[0]], k=kbr) - rxn_m2 = Reaction(inputs=[cp_closed[0]], outputs=[transcript,self.ribosome], k=kur) + rxn_m1 = Reaction.from_massaction(inputs=[transcript, self.ribosome], outputs=[cp_closed[0]], k_forward=kb, k_reverse = ku) + #rxn_m2 = Reaction.from_massaction(inputs=[cp_closed[0]], outputs=[transcript, self.ribosome], k_forward=kur) - rxn_all = rxn_open_pf + rxn_open_pr + rxn_iso + rxn_release_open + rxn_release_closed + [rxn_m1, rxn_m2] + rxn_all = [rxn_m1] + rxn_iso + rxn_open_p + rxn_release_open + rxn_release_closed return rxn_all diff --git a/biocrnpyler/mixture.py b/biocrnpyler/mixture.py index cb17ea06..8b9934e5 100644 --- a/biocrnpyler/mixture.py +++ b/biocrnpyler/mixture.py @@ -1,24 +1,24 @@ -# Copyright (c) 2019, Build-A-Cell. All rights reserved. +# Copyright (c) 2020, Build-A-Cell. All rights reserved. # See LICENSE file in the project root directory for details. -from warnings import warn -from warnings import resetwarnings +import copy +from typing import List, Union +from warnings import resetwarnings, warn +from .chemical_reaction_network import ChemicalReactionNetwork from .component import Component -from .chemical_reaction_network import ChemicalReactionNetwork, Species, Reaction -from .parameter import Parameter -from typing import List, Union +from .global_mechanism import GlobalMechanism +from .mechanism import Mechanism +from .parameter import ParameterDatabase +from .reaction import Reaction +from .species import Species class Mixture(object): - def __init__(self, name="", mechanisms={}, components = [], parameters=None, - parameter_file = None, default_mechanisms = {}, - global_mechanisms = {}, default_components = [], - species = [], custom_initial_condition = {}, - parameter_warnings = None, **kwargs): - """ - A Mixture object holds together all the components (DNA,Protein, etc), mechanisms (Transcription, Translation), + def __init__(self, name="", mechanisms=None, components=None, parameters=None, parameter_file=None, + global_mechanisms=None, species=None, initial_condition_dictionary=None, **kwargs): + """A Mixture object holds together all the components (DNA,Protein, etc), mechanisms (Transcription, Translation), and parameters related to the mixture itself (e.g. Transcription rate). Default components and mechanisms can be added as well as global mechanisms that impacts all species (e.g. cell growth). @@ -29,274 +29,471 @@ def __init__(self, name="", mechanisms={}, components = [], parameters=None, :param parameter_file: Parameters can be loaded from a parameter file :param default_mechanisms: :param global_mechanisms: dict of global mechanisms that impacts all species (e.g. cell growth) - :param default_components: - :param parameter_warnings: suppressing parameter related warnings """ - - init = kwargs.get('init') - parameter_warnings = kwargs.get('parameter_warnings') - if parameter_warnings: - warn('Parameter warnings have been set True. Verbose warnings regarding parameter files will be displayed.') - else: - parameter_warnings = False - kwargs['parameter_warnings'] = parameter_warnings - if not init and parameter_warnings: - warn('Initial concentrations for extract species will all be set to zero.') - - # Initialize instance variables self.name = name # Save the name of the mixture - self.parameters = Parameter.create_parameter_dictionary(parameters, - parameter_file) - # Toggles whether parameter warnings are raised. if None (default) this - # can be toggled component by component. - self.parameter_warnings = parameter_warnings - - # Override the default mechanisms with anything we were passed - # default parameters are used by mixture subclasses. - self.default_mechanisms = dict(default_mechanisms) - self.custom_mechanisms = dict(mechanisms) - - #Initial conditions are searched for by defauled in the parameter file - #see Mixture.set_initial_condition(self) - #These can be overloaded with custom_initial_condition dictionary: component.name --> initial amount - self.custom_initial_condition = dict(custom_initial_condition) - - # Mechanisms stores the mechanisms used for compilation where defaults - # are overwritten by custom mechanisms. - self.mechanisms = dict(self.default_mechanisms) - - if isinstance(self.custom_mechanisms, dict): - for mech_type in self.custom_mechanisms: - self.mechanisms[mech_type] = self.custom_mechanisms[mech_type] - elif isinstance(self.custom_mechanisms, list): - for mech in self.custom_mechanisms: - self.mechanisms[mech.type] = mech + # process the components + if components is None and not hasattr(self, "_components"): + self.components = [] + else: + self.add_components(components) + + # process mechanisms: + if mechanisms is None and not hasattr(self, "_mechanisms"): + self.mechanisms = {} else: - raise ValueError("Mechanisms must be passed as a list of " - "instantiated objects or a dictionary " - "{type:mechanism}") + self.add_mechanisms(mechanisms) + # process global_mechanisms: # Global mechanisms are applied just once ALL species generated from # components inside a mixture # Global mechanisms should be used rarely, and with care. An example # usecase is degradation via dilution. - self.global_mechanisms = dict(global_mechanisms) + if global_mechanisms is None and not hasattr(self, "_global_mechanisms"): + self.global_mechanisms = {} + else: + self.add_mechanisms(global_mechanisms) - self.components = [] # components contained in mixture - # if chemical_reaction_network.species objects are passed in as - # components they are stored here - self.added_species = [] # process the species self.add_species(species) - # TODO find out why do we need default_components! - # process the components - self.add_components(components+default_components) - # internal lists for the species and reactions - self.crn_species = None - self.crn_reactions = None + # Create a paraemter database + self.parameter_database = ParameterDatabase(parameter_file = parameter_file, parameter_dictionary = parameters, **kwargs) + + # Initial conditions are searched for by defauled in the parameter file + # see Mixture.set_initial_condition(self) + # These can be overloaded with custom_initial_condition dictionary: component.name --> initial amount + if initial_condition_dictionary is None: + self.initial_condition_dictionary = {} + else: + self.initial_condition_dictionary = dict(initial_condition_dictionary) + + # CRN is stored here during compilation + self.crn = None def add_species(self, species: Union[List[Species], Species]): - if not isinstance(species, list): - species_list = [species] - else: - species_list = species + if not hasattr(self, "added_species"): + self.added_species = [] - assert all(isinstance(x, Species) for x in species_list), 'only Species type is accepted!' + if species is not None: + if not isinstance(species, list): + species_list = [species] + else: + species_list = species - self.added_species += species_list + assert all(isinstance(x, Species) for x in species_list), 'only Species type is accepted!' + self.added_species += species_list - + def set_species(self, species: Union[Species, str], material_type=None, attributes=None): + """Used to set internal species from strings, Species or Components - #Used to set internal species froms strings, Species or Components - def set_species(self, species, material_type = None, attributes = None): + :param species: name of a species or a species instance + :param material_type: material type of a species as a string + :param attributes: Species attribute + :return: Species in the mixture + """ if isinstance(species, Species): - return species + return species elif isinstance(species, str): - return Species(name = species, material_type = material_type, attributes = attributes) + return Species(name=species, material_type=material_type, attributes=attributes) elif isinstance(species, Component) and species.get_species() is not None: return species.get_species() else: raise ValueError("Invalid Species: string, chemical_reaction_network.Species or Component with implemented .get_species() required as input.") + @property + def components(self): + return self._components - def add_components(self, components): - if not isinstance(components, list): - components = [components] - - for component in components: - assert isinstance(component, Component), \ - "the object: %s passed into mixture as component must be of the class Component" % str(component) - self.components.append(component) - component.update_mechanisms(mixture_mechanisms=self.mechanisms, overwrite_custom_mechanisms = False) - component.update_parameters(mixture_parameters=self.parameters) - if self.parameter_warnings is not None: - component.set_parameter_warnings(self.parameter_warnings) - - #Sets the initial condition for all components with internal species - #Does this for the species returned during compilation to prevent errors - # First checks if (mixture.name, repr(species) is in the self.custom_initial_condition_dict - # Then checks if (repr(species) is in the self.custom_initial_condition_dict - # First checks if (mixture.name, component.name) is in the self.custom_initial_condition_dictionary - # Then checks if (component.name) is in the self.custom_initial_condition_dictionary - - # First checks if (mixture.name, repr(species) is in the parameter dictionary - # Then checks if repr(species) is in the parameter dictionary - # Then checks if (mixture.name, component.name) is in the parameter dictionary - # Then checks if component.name is in the parameter dictionary - # Then defaults to 0 - def set_initial_condition(self, species): - return_species = [] - for s in species: - found = False - if not found and (self.name, repr(s)) in self.custom_initial_condition: - s.initial_concentration = self.custom_initial_condition[self.name, repr(s)] - found = True - elif not found and repr(s) in self.custom_initial_condition: - s.initial_concentration = self.custom_initial_condition[repr(s)] - found = True - elif not found: - for comp in self.components: - - s_comp = comp.get_species() - if repr(s_comp) == repr(s): - if not found and (self.name, comp.name) in self.custom_initial_condition: - s.initial_concentration = self.custom_initial_condition[(self.name, comp.name)] - s_comp.initial_concentration = self.custom_initial_condition[(self.name, comp.name)] - found = True - elif not found and comp.name in self.custom_initial_condition: - s.initial_concentration = self.custom_initial_condition[comp.name] - s_comp.initial_concentration = self.custom_initial_condition[comp.name] - found = True - - if not found and (self.name, repr(s)) in self.parameters: - s.initial_concentration = self.parameters[self.name, repr(s)] - s_comp.initial_concentration = self.parameters[self.name, repr(s)] - found = True - elif not found and repr(s) in self.parameters: - s.initial_concentration = self.parameters[repr(s)] - s_comp.initial_concentration = self.parameters[repr(s)] - found = True - elif not found: - for comp in self.components: - s_comp = comp.get_species() - if not found and repr(s_comp) == repr(s): - if not found and (self.name, comp.name) in self.parameters: - s.initial_concentration = self.parameters[(self.name, comp.name)] - s_comp.initial_concentration = self.parameters[(self.name, comp.name)] - found = True - elif not found and comp.name in self.parameters: - s.initial_concentration = self.parameters[comp.name] - s_comp.initial_concentration = self.parameters[comp.name] - found = True - return species + @components.setter + def components(self, components): + self._components = [] + self.add_components(components) - #Allows mechanisms to return nested lists of species. These lists are flattened. - def append_species(self, new_species, component): - for s in new_species: - if isinstance(s, Species): - self.crn_species.append(s) - elif isinstance(s, list) and all(isinstance(ss, Species) for ss in s): - self.crn_species+=s - elif s is not None: - raise ValueError(f"Invalid Species Returned in {component}.update_species(): {s}.") - #Old Version - #self.crn_species += [s for s in new_species if s not in self.crn_species] - + def add_component(self, component): + """this function adds a single component to the mixture.""" + if not hasattr(self, "_components"): + self.components = [] - def update_species(self) -> List[Species]: - """ it generates the list of species based on all the mechanisms and global mechanisms + if isinstance(component, list): + self.add_components(component) + else: + assert isinstance(component, Component), "the object: %s passed into mixture as component must be of the class Component" % str(component) + + # Check if component is already in self._components + for comp in self._components: + if type(comp) == type(component) and comp.name == component.name: + raise ValueError(f"{comp} of the same type and name already in Mixture!") + else: + # Components are copied before being added to Mixtures + component_copy = copy.deepcopy(component) + component_copy.set_mixture(self) + self.components.append(component_copy) + + def get_mechanism(self, mechanism_type): + """Searches the Mixture for a Mechanism of the correct type. + + If no Mechanism is found, None is returned. + """ + if not isinstance(mechanism_type, str): + raise TypeError(f"mechanism_type must be a string. Recievied {mechanism_type}.") - :return: list of species generated by all the mechanisms and global mechanisms + if mechanism_type in self.mechanisms: + return self.mechanisms[mechanism_type] + else: + return None + + @property + def global_mechanisms(self): """ - # TODO check if we can merge the two variables - self.crn_species = self.added_species - for component in self.components: - self.append_species(component.update_species(), component) + global_mechanisms stores global Mechanisms in the Mixture + """ + return self._global_mechanisms + + @global_mechanisms.setter + def global_mechanisms(self, mechanisms): + self._global_mechanisms = {} + if isinstance(mechanisms, dict): + for mech_type in mechanisms: + self.add_global_mechanism(mechanisms[mech_type], mech_type, overwrite = True) + elif isinstance(mechanisms, list): + for mech in mechanisms: + self.add_global_mechanism(mech, overwrite = True) + + def add_global_mechanism(self, mechanism: Mechanism, mech_type=None, overwrite=False): + """adds a mechanism of type mech_type to the Mixture global_mechanism dictonary. + + :param mechanism: a Mechanism instance + :param mech_type: the type of mechanism. defaults to mechanism.mech_type if None + :param overwrite: whether to overwrite existing mechanisms of the same type (default False) + :return: + """ + if not hasattr(self, "_global_mechanisms"): + self._global_mechanisms = {} - return self.crn_species + if not isinstance(mechanism, GlobalMechanism): + raise TypeError(f"mechanism must be a GlobalMechanism. Received {mechanism}.") - def update_reactions(self) -> List[Reaction]: - """ it generates the list of reactions based on all the mechanisms and global mechanisms - it **must be** called after update_species() was called! + if mech_type is None: + mech_type = mechanism.mechanism_type + if not isinstance(mech_type, str): + raise TypeError(f"mechanism keys must be strings. Received {mech_type}") - :raise: AttributeError if it was called before update_species() - :return: list of reactions generated by all the mechanisms and global mechanisms + if mech_type in self._mechanisms and not overwrite: + raise ValueError(f"mech_type {mech_type} already in Mixture {self}. To overwrite, use keyword overwrite = True.") + else: + self._global_mechanisms[mech_type] = copy.deepcopy(mechanism) + + def add_components(self, components: Union[List[Component], Component]): + """This function adds a list of components to the mixture. """ - if self.crn_species is None: - raise AttributeError("Mixture.crn_species not defined. " - "mixture.update_species() must be called " - "before mixture.update_reactions()") + if isinstance(components, Component): + self.add_component(components) + elif isinstance(components, List): + for component in components: + self.add_component(component) + else: + raise ValueError(f"add_components expected a list of Components. Received {components}") - self.crn_reactions = [] - for component in self.components: - if self.parameter_warnings is not None: - component.set_parameter_warnings(self.parameter_warnings) - self.crn_reactions += component.update_reactions() + def get_component(self, component=None, name=None, index=None): + """Function to get components from Mixture._components. - return self.crn_reactions + One of the 3 keywords must not be None. + :param component: an instance of a component. Searches Mixture._components for a Component with the same type and name. + :param name: str. Searches Mixture._components for a Component with the same name + :param index: int. returns Mixture._components[index] + :return: if nothing is found, returns None. + """ + if [component, name, index].count(None) != 2: + raise ValueError(f"get_component requires a single keyword. Received component={component}, name={name}, index={index}.") + if not (isinstance(component, Component) or component is None): + raise ValueError(f"component must be of type Component. Received {component}.") + if not (isinstance(name, str) or name is None): + raise ValueError(f"name must be of type str. Received {name}.") + if not (isinstance(index, int) or index is None): + raise ValueError(f"index must be of type int. Received {index}.") + + matches = [] + if index is not None: + matches.append(self.components[index]) + else: + for comp in self.components: + if component is not None: + if type(comp) == type(component) and comp.name == component.name: + matches.append(comp) + elif name is not None: + if comp.name == name: + matches.append(comp) + if len(matches) == 0: + return None + elif len(matches) == 1: + return matches[0] + else: + warn("get_component found multiple matching components. A list has been returned.") + return matches + + @property + def mechanisms(self): + """mechanisms stores Mixture Mechanisms.""" + return self._mechanisms + + @mechanisms.setter + def mechanisms(self, mechanisms): + self._mechanisms = {} + self.add_mechanisms(mechanisms, overwrite=True) + def add_mechanism(self, mechanism, mech_type=None, overwrite=False): + """adds a mechanism of type mech_type to the Mixture mechanism_dictionary. - def apply_global_mechanisms(self) -> (List[Species], List[Reaction]): - # update with global mechanisms + :param mechanism: a Mechanism instance + :param mech_type: the type of mechanism. defaults to mechanism.mech_type if None + :param overwrite: whether to overwrite existing mechanisms of the same type (default False) + :return: + """ + if not hasattr(self, "_mechanisms"): + self._mechanisms = {} + + if not isinstance(mechanism, Mechanism): + raise TypeError(f"mechanism must be a Mechanism. Received {mechanism}.") + + if mech_type is None: + mech_type = mechanism.mechanism_type + if not isinstance(mech_type, str): + raise TypeError(f"mechanism keys must be strings. Received {mech_type}") + + if isinstance(mechanism, GlobalMechanism): + self.add_global_mechanism(mechanism, mech_type, overwrite) + elif isinstance(mechanism, Mechanism): + if mech_type in self._mechanisms and not overwrite: + raise ValueError(f"mech_type {mech_type} already in Mixture {self}. To overwrite, use keyword overwrite = True.") + else: + self._mechanisms[mech_type] = copy.deepcopy(mechanism) + + def add_mechanisms(self, mechanisms, overwrite=False): + """This function adds a list or dictionary of mechanisms to the mixture. - if self.crn_species is None: - raise AttributeError("Mixture.crn_species not defined. " - "mixture.update_species() must be called " - "before mixture.apply_global_mechanisms()") + Can take both GlobalMechanisms and Mechanisms - global_mech_species = [] - global_mech_reactions = [] + :param mechanisms: a Mechanism instance + :param overwrite: whether to overwrite existing mechanisms of the same type (default False) + :return: + """ + if isinstance(mechanisms, Mechanism): + self.add_mechanism(mechanisms, overwrite = overwrite) + elif isinstance(mechanisms, dict): + for mech_type in mechanisms: + self.add_mechanism(mechanisms[mech_type], mech_type, overwrite = overwrite) + elif isinstance(mechanisms, list): + for mech in mechanisms: + self.add_mechanism(mech, overwrite = overwrite) + else: + raise ValueError(f"add_mechanisms expected a list of Mechanisms. Recieved {mechanisms}") + + def get_mechanism(self, mechanism_type): + """Searches the Mixture for a Mechanism of the correct type. + + If no Mechanism is found, None is returned. + """ + if not isinstance(mechanism_type, str): + raise TypeError(f"mechanism_type must be a string. Recievied {mechanism_type}.") + + if mechanism_type in self.mechanisms: + return self.mechanisms[mechanism_type] + else: + return None + + @property + def global_mechanisms(self): + """global_mechanisms stores global Mechanisms in the Mixture.""" + return self._global_mechanisms + + @global_mechanisms.setter + def global_mechanisms(self, mechanisms): + self._global_mechanisms = {} + if isinstance(mechanisms, dict): + for mech_type in mechanisms: + self.add_global_mechanism(mechanisms[mech_type], mech_type, overwrite = True) + elif isinstance(mechanisms, list): + for mech in mechanisms: + self.add_global_mechanism(mech, overwrite = True) + + def add_global_mechanism(self, mechanism, mech_type = None, overwrite = False): + """adds a mechanism of type mech_type to the Mixture global_mechanism dictonary. + + keywordS: + mechanism: a Mechanism instance + mech_type: the type of mechanism. defaults to mechanism.mech_type if None + overwrite: whether to overwrite existing mechanisms of the same type (default False) + """ + if not hasattr(self, "_global_mechanisms"): + self._global_mechanisms = {} - for mech in self.global_mechanisms: - # Update Global Mechanisms - global_mech_species += self.global_mechanisms[mech].update_species_global(self.crn_species, self.parameters) - global_mech_reactions += self.global_mechanisms[mech].update_reactions_global(self.crn_species, self.parameters) + if not isinstance(mechanism, GlobalMechanism): + raise TypeError(f"mechanism must be a GlobalMechanism. Recieved {mechanism}.") - return global_mech_species, global_mech_reactions + if mech_type is None: + mech_type = mechanism.mechanism_type + if not isinstance(mech_type, str): + raise TypeError(f"mechanism keys must be strings. Recieved {mech_type}") + if mech_type in self._mechanisms and not overwrite: + raise ValueError(f"mech_type {mech_type} already in Mixture {self}. To overwrite, use keyword overwrite = True.") + else: + self._global_mechanisms[mech_type] = copy.deepcopy(mechanism) + + def update_parameters(self, parameter_file = None, parameters = None, overwrite_parameters = True): + if parameter_file is not None: + self.parameter_database.load_parameters_from_file(parameter_file, overwrite_parameters = overwrite_parameters) + + if parameters is not None: + self.parameter_database.load_parameters_from_dictionary(parameters, overwrite_parameters = overwrite_parameters) + + def get_parameter(self, mechanism, part_id, param_name): + param = self.parameter_database.find_parameter(mechanism, part_id, param_name) + + return param + + def set_initial_condition(self, s: Species, component=None): + """ + Tries to find an initial condition of species s using the parameter hierarchy + 1. Tries to find the initial concentration in the Component initial_Concentration_dictionary and ParameterDatabase + 2. Tries to find self.name, repr(s) in self.initial_condition_dictionary + 3. Tries to find repr(s) in self.initial_condition_dictionary + 4. if s == component.get_species(), tries to find (None, self.name, component.name) in self.initial_condition_dictionary + 5. if s == component.get_species(), tries to find component.name in self.initial_condition_dictionary + 6. tries to find (None, self.name, repr(s)) in self.parameter_database + 7. tries to find repr(s) in self.parameter_database + 8. if s == component.get_species(), tries to find (None, self.name, component.name) in self.parameter_database + 9. if s == component.get_species(), tries to find component.name in self.parameter_database + 10-. defaults to 0 + + :param s: + :param component: + :return: + """ + + if not isinstance(s, Species): + raise ValueError(f"{s} is not a Species! Can only set initial concentration of a Species.") + + init_conc = None + #1 + if component is not None: + init_conc = component.get_initial_condition(s) + + if init_conc is None: + #2 + if (self.name, repr(s)) in self.initial_condition_dictionary: + init_conc = self.initial_condition_dictionary[(self.name, repr(s))] + #3 + elif repr(s) in self.initial_condition_dictionary: + init_conc = self.initial_condition_dictionary[repr(s)] + #4 + elif component is not None and component.get_species() == s and (self.name, component.name) in self.initial_condition_dictionary: + return self.initial_condition_dictionary[(self.name, component.name)] + #5 + elif component is not None and component.get_species() == s and component.name in self.initial_condition_dictionary: + return self.initial_condition_dictionary[component.name] + #6 + elif self.parameter_database.find_parameter(None, self.name, repr(s)) is not None: + init_conc = self.parameter_database.find_parameter(None, self.name, repr(s)).value + #7 + elif self.parameter_database.find_parameter(None, None, repr(s)) is not None: + init_conc = self.parameter_database.find_parameter(None, None, repr(s)).value + #8 + elif component is not None and component.get_species() == s and (None, self.name, component.name) in self.parameter_database: + return self.parameter_database.find_parameter(None, self.name, component.name).value + #9 + elif component is not None and component.get_species() == s and component.name in self.parameter_database: + return self.parameter_database.find_parameter(None, None, component.name).value + #10 + else: + init_conc = 0 + + s.initial_concentration = init_conc + + def add_species_to_crn(self, new_species, component): + + if self.crn is None: + self.crn = ChemicalReactionNetwork(species = [], reactions = []) + + if isinstance(new_species, Species): + new_species = [new_species] + + for s in new_species: + if isinstance(s, Species): + self.set_initial_condition(s, component) + self.crn.add_species(s) + elif isinstance(s, list) and(all(isinstance(ss, Species) for ss in s) or len(s) == 0): + for ss in s: + self.set_initial_condition(ss, component) + self.crn.add_species(s) + elif s is not None: + raise ValueError(f"Invalid Species Returned in {component}.update_species(): {s}.") + + def apply_global_mechanisms(self, species) -> (List[Species], List[Reaction]): + # update with global mechanisms + + global_mech_species = [] + global_mech_reactions = [] + if self.global_mechanisms: + for mech in self.global_mechanisms: + # Update Global Mechanisms + global_mech_species += self.global_mechanisms[mech].update_species_global(species, self) + global_mech_reactions += self.global_mechanisms[mech].update_reactions_global(species, self) + + self.add_species_to_crn(global_mech_species, component = None) + self.crn.add_reactions(global_mech_reactions) def compile_crn(self) -> ChemicalReactionNetwork: - """ Creates a chemical reaction network from the species and reactions associated with a mixture object + """Creates a chemical reaction network from the species and reactions associated with a mixture object. + :return: ChemicalReactionNetwork """ resetwarnings()#Reset warnings - better to toggle them off manually. - species = self.update_species() - reactions = self.update_reactions() + #reset the Components' mixture to self - in case they have been added to other Mixtures + for c in self.components: + c.set_mixture(self) + + #Create a CRN to filter out duplicate species + self.crn = ChemicalReactionNetwork([], []) - #global mechanisms are applied last and only to all the species - global_mech_species, global_mech_reactions = self.apply_global_mechanisms() + #add the extra species to the CRN + self.add_species_to_crn(self.added_species, component = None) - species += global_mech_species - reactions += global_mech_reactions + #Append Species from each Component + for component in self.components: + self.add_species_to_crn(component.update_species(), component) + + #Append Reactions from each Component + for component in self.components: + self.crn.add_reactions(component.update_reactions()) - species = self.set_initial_condition(species) + #global mechanisms are applied last and only to all the species + #the reactions and species are added to the CRN + self.apply_global_mechanisms(self.crn.species) - CRN = ChemicalReactionNetwork(species, reactions) - return CRN + return self.crn def __str__(self): return type(self).__name__ + ': ' + self.name def __repr__(self): txt = str(self)+"\n" - txt += "Components = [" - for comp in self.components: - txt+="\n\t"+str(comp) - txt+=" ]\nMechanisms = {" - for mech in self.mechanisms: - txt+="\n\t"+mech+":"+self.mechanisms[mech].name - txt+=" }\nGlobal Mechanisms = {" - for mech in self.global_mechanisms: - txt+="\n\t"+mech+":"+self.global_mechanisms[mech].name + if self.components: + txt += "Components = [" + for comp in self.components: + txt+="\n\t"+str(comp) + if self.mechanisms: + txt+=" ]\nMechanisms = {" + for mech in self.mechanisms: + txt+="\n\t"+mech+":"+self.mechanisms[mech].name + if self.global_mechanisms: + txt+=" }\nGlobal Mechanisms = {" + for mech in self.global_mechanisms: + txt+="\n\t"+mech+":"+self.global_mechanisms[mech].name txt+=" }" return txt - - - - diff --git a/biocrnpyler/mixtures_cell.py b/biocrnpyler/mixtures_cell.py index fd83c2a1..9b0c132e 100644 --- a/biocrnpyler/mixtures_cell.py +++ b/biocrnpyler/mixtures_cell.py @@ -1,24 +1,36 @@ -from warnings import warn -from warnings import resetwarnings -from .components_basic import DNA, RNA, Protein, ChemicalComplex + +# Copyright (c) 2020, Build-A-Cell. All rights reserved. +# See LICENSE file in the project root directory for details. + +from .chemical_reaction_network import ChemicalReactionNetwork +from .components_basic import Protein +from .dna_assembly import DNAassembly +from .global_mechanism import Degredation_mRNA_MM, Dilution from .mechanism import EmptyMechanism -from .mechanisms_enzyme import BasicCatalysis, MichalisMenten from .mechanisms_binding import One_Step_Binding -from .mechanisms_txtl import Transcription_MM, Translation_MM, Degredation_mRNA_MM, OneStepGeneExpression, SimpleTranscription, SimpleTranslation +from .mechanisms_enzyme import BasicCatalysis, MichaelisMenten +from .mechanisms_txtl import (OneStepGeneExpression, SimpleTranscription, + SimpleTranslation, Transcription_MM, + Translation_MM) from .mixture import Mixture -from .chemical_reaction_network import Species, ChemicalReactionNetwork -from .global_mechanism import Dilution -from .dna_assembly import DNAassembly - -#A Model for in-vivo Gene Expression without any Machinery (eg Ribosomes, Polymerases, etc.) -# Here transcription and Translation are lumped into one reaction: expression. -#A global mechanism is used to dilute all non-dna species class ExpressionDilutionMixture(Mixture): - def __init__(self, name="", mechanisms={}, components=[], **kwargs): + """A Model for in-vivo Gene Expression without any Machinery (eg Ribosomes, Polymerases, etc.). - dummy_translation = EmptyMechanism(name = "dummy_translation", mechanism_type = "translation") + Here transcription and Translation are lumped into one reaction: expression. + A global mechanism is used to dilute all non-dna species + """ + def __init__(self, name="", **kwargs): + """Initializes an ExpressionDilutionMixture instance. + + :param name: name of the mixture + :param kwargs: keywords passed into the parent Class (Mixture) + """ + Mixture.__init__(self, name=name, **kwargs) + + # Create default mechanisms for Gene Expression + dummy_translation = EmptyMechanism(name="dummy_translation", mechanism_type="translation") mech_expression = OneStepGeneExpression() mech_cat = BasicCatalysis() mech_bind = One_Step_Binding() @@ -26,57 +38,53 @@ def __init__(self, name="", mechanisms={}, components=[], **kwargs): default_mechanisms = { mech_expression.mechanism_type: mech_expression, dummy_translation.mechanism_type: dummy_translation, - mech_cat.mechanism_type:mech_cat, - mech_bind.mechanism_type:mech_bind + mech_cat.mechanism_type: mech_cat, + mech_bind.mechanism_type: mech_bind } + self.add_mechanisms(default_mechanisms) - dilution_mechanism= Dilution(name = "dilution", filter_dict = {"dna":False}, default_on = True) - global_mechanisms = {"dilution":dilution_mechanism} + # Create global mechanism for dilution + dilution_mechanism = Dilution(name="dilution", filter_dict={"dna": False}, default_on=True) + global_mechanisms = {"dilution": dilution_mechanism} + self.add_mechanisms(global_mechanisms) - default_components = [] + def compile_crn(self) -> ChemicalReactionNetwork: + """Overwriting compile_crn to replace transcripts with proteins for all DNA_assemblies. - Mixture.__init__(self, name=name, default_mechanisms=default_mechanisms, mechanisms=mechanisms, - components=components+default_components, global_mechanisms = global_mechanisms, **kwargs) + Overwriting compile_crn to turn off transcription in all DNAassemblies - #Overwriting compile_crn to replace transcripts with proteins for all DNA_assemblies - def compile_crn(self) -> ChemicalReactionNetwork: - """ Creates a chemical reaction network from the species and reactions associated with a mixture object - :return: ChemicalReactionNetwork + :return: compiled CRN instance """ - resetwarnings()#Reset warnings - better to toggle them off manually. - - species = self.update_species() - reactions = self.update_reactions() + for component in self.components: + if isinstance(component, DNAassembly): + # Only turn off transcription for an Assembly that makes a Protein. + # Some assemblies might only make RNA! + if component.protein is not None: + # This will turn off transcription and set Promoter.transcript = False + # Mechanisms that recieve no transcript but a protein will use the protein instead. + component.update_transcript(False) + # Call the superclass function + return Mixture.compile_crn(self) - for comp in self.components: - if isinstance(comp, DNAassembly): - if comp.transcript is not None and comp.protein is not None: - for i, s in enumerate(species): - species[i] = s.replace_species(comp.transcript, comp.protein) - for i, r in enumerate(reactions): - reactions[i] = r.replace_species(comp.transcript, comp.protein) - self.crn_species = list(set(species)) - self.crn_reactions = reactions - #global mechanisms are applied last and only to all the species - global_mech_species, global_mech_reactions = self.apply_global_mechanisms() +class SimpleTxTlDilutionMixture(Mixture): + """Mixture with continuous dilution for non-DNA species. - species += global_mech_species - reactions += global_mech_reactions + Transcription and Translation are both modeled as catalytic with no cellular machinery. + mRNA is also degraded via a separate reaction to represent endonucleases + """ + def __init__(self, name="", **keywords): + """Initializes a SimpleTxTlDilutionMixture instance. - species = self.set_initial_condition(species) - species.sort(key = lambda s:repr(s)) - reactions.sort(key = lambda r:repr(r)) - CRN = ChemicalReactionNetwork(species, reactions) - return CRN + :param name: name of the mixture + :param kwargs: keywords passed into the parent Class (Mixture) + """ + # Always call the superclass __init__ with **keywords + Mixture.__init__(self, name=name, **keywords) -#A Mixture with continious dilution for non-DNA species -#mRNA is also degraded via a seperate reaction to represent endonucleases -class SimpleTxTlDilutionMixture(Mixture): - def __init__(self, name="", **keywords): - - simple_transcription = SimpleTranscription() #Transcription will not involve machinery + # Create TxTl Mechanisms + simple_transcription = SimpleTranscription() # Transcription will not involve machinery simple_translation = SimpleTranslation() mech_cat = BasicCatalysis() mech_bind = One_Step_Binding() @@ -84,31 +92,42 @@ def __init__(self, name="", **keywords): default_mechanisms = { simple_transcription.mechanism_type: simple_transcription, simple_translation.mechanism_type: simple_translation, - mech_cat.mechanism_type:mech_cat, - mech_bind.mechanism_type:mech_bind + mech_cat.mechanism_type: mech_cat, + mech_bind.mechanism_type: mech_bind } - - #By Default Species are diluted S-->0 Unless: + self.add_mechanisms(default_mechanisms) + + # Global Dilution Mechanisms + # By Default Species are diluted S-->0 Unless: # They are of type 'dna' # They have the attribute 'machinery' - dilution_mechanism = Dilution(filter_dict = {"dna":False}, default_on = True) - deg_mrna = Dilution(name = "rna_degredation", filter_dict = {"rna":True}, default_on = False) + dilution_mechanism = Dilution(filter_dict={"dna": False}, default_on=True) + deg_mrna = Dilution(name="rna_degredation", filter_dict={"rna": True}, default_on=False) - global_mechanisms = {"dilution":dilution_mechanism, "rna_degredation":deg_mrna} - - #Always call the superclass __init__ with **keywords - Mixture.__init__(self, name=name, default_mechanisms=default_mechanisms, global_mechanisms = global_mechanisms, **keywords) + global_mechanisms = {"dilution": dilution_mechanism, "rna_degredation": deg_mrna} + self.add_mechanisms(global_mechanisms) -#A Model for Transcription and Translation with Ribosomes, Polymerases, and Endonucleases labelled as Machinery. -#Unlike TxTlExtract, has global dilution for non-DNA and non-Machinery -#This model does not include any energy -#TODO: -#Include some "internal" gene which provides background loading of all machinery class TxTlDilutionMixture(Mixture): - def __init__(self, name="", mechanisms={}, components=[], - rnap = "RNAP", ribosome = "Ribo", rnaase = "RNAase", **kwargs): - + """A Model for Transcription and Translation with Ribosomes, Polymerases, and Endonucleases labelled as Machinery. + + This model includes a background load "cellular processes" which represents innate loading effects in the cell. + Effects of loading on cell growth are not modelled. + Unlike TxTlExtract, has global dilution for non-DNA and non-Machinery + This model does not include any energy + """ + def __init__(self, name="", rnap="RNAP", ribosome="Ribo", rnaase="RNAase", **kwargs): + """Initializes a TxTlDilutionMixture instance. + + :param name: name of the mixture + :param rnap: name of the RNA polymerase, default: RNAP + :param ribosome: name of the ribosome, default: Ribo + :param rnaase: name of the Ribonuclease, default: RNAase + :param kwargs: keywords passed into the parent Class (Mixture) + """ + Mixture.__init__(self, name=name, **kwargs) + + # Create Components for TxTl machinery self.rnap = Protein(rnap) self.ribosome = Protein(ribosome) self.rnaase = Protein(rnaase) @@ -119,36 +138,39 @@ def __init__(self, name="", mechanisms={}, components=[], init = kwargs.get('init') if init: - self.rnap.get_species().initial_concentration = init[rep(rnap)] + self.rnap.get_species().initial_concentration = init[repr(rnap)] self.rnaase.get_species().initial_concentration = init[repr(rnaase)] self.ribosome.get_species().initial_concentration = init[repr(ribosome)] + # DNAassmbly represents background processes / loading in a cell + background_parameters = {("transcription", None, "ku"): 50, ("transcription", None, "kb"): 500, ("transcription", None, "ktx"): 0.1, + ("translation", None, "ku"): 5, ("translation", None, "kb"): 500, ("translation",None, "ktl"): .1, + ("rna_degredation", None, "ku"): 50, ("rna_degredation", None, "kb"): 500, ("rna_degredation", None, "kdeg"): 0.1} + BackgroundProcesses = DNAassembly(name="cellular_processes", promoter="average_promoter", rbs="average_rbs", parameters=background_parameters) + + default_components = [ + self.rnap, self.ribosome, self.rnaase, BackgroundProcesses + ] + self.add_components(default_components) + + #Create TxTl Mechansisms mech_tx = Transcription_MM(rnap = self.rnap.get_species()) mech_tl = Translation_MM(ribosome = self.ribosome.get_species()) - mech_rna_deg = Degredation_mRNA_MM(nuclease = self.rnaase.get_species()) - mech_cat = MichalisMenten() + mech_cat = MichaelisMenten() mech_bind = One_Step_Binding() + #Create Global Dilution Mechanisms + dilution_mechanism = Dilution(filter_dict = {"dna":False, "machinery":False}, default_on = True) + mech_rna_deg = Degredation_mRNA_MM(nuclease = self.rnaase.get_species()) + default_mechanisms = { mech_tx.mechanism_type: mech_tx, mech_tl.mechanism_type: mech_tl, - mech_rna_deg.mechanism_type: mech_rna_deg, mech_cat.mechanism_type: mech_cat, - mech_bind.mechanism_type:mech_bind + mech_bind.mechanism_type:mech_bind, + mech_rna_deg.mechanism_type:mech_rna_deg, + "dilution":dilution_mechanism, } - dilution_mechanism = Dilution(filter_dict = {"dna":False, "machinery":False}, default_on = True) - global_mechanisms = {"dilution":dilution_mechanism} - - background_parameters = {("transcription", "ku"):50, ("transcription", "kb"):500, ("transcription", "ktx"):0.1, - ("translation","ku"):5, ("translation","kb"):500, ("translation", "ktl"):.1, - ("rna_degredation","ku"):50, ("rna_degredation","kb"):500, ("rna_degredation", "kdeg"):0.1} - - BackgroundProcesses = DNAassembly(name = "cellular_processes", promoter = "average_promoter", rbs = "average_rbs", parameters = background_parameters) - - default_components = [ - self.rnap, self.ribosome, self.rnaase, BackgroundProcesses - ] + self.add_mechanisms(default_mechanisms) - Mixture.__init__(self, name=name, default_mechanisms=default_mechanisms, mechanisms=mechanisms, - components=components+default_components, global_mechanisms = global_mechanisms, **kwargs) \ No newline at end of file diff --git a/biocrnpyler/mixtures_extract.py b/biocrnpyler/mixtures_extract.py index 36156f31..5cb34fc9 100644 --- a/biocrnpyler/mixtures_extract.py +++ b/biocrnpyler/mixtures_extract.py @@ -1,24 +1,36 @@ -# Copyright (c) 2018, Build-A-Cell. All rights reserved. + +# Copyright (c) 2020, Build-A-Cell. All rights reserved. # See LICENSE file in the project root directory for details. -from warnings import warn -from warnings import resetwarnings -from .components_basic import DNA, RNA, Protein, ChemicalComplex +from .chemical_reaction_network import ChemicalReactionNetwork +from .components_basic import Protein +from .dna_assembly import DNAassembly +from .global_mechanism import Degredation_mRNA_MM, Dilution from .mechanism import EmptyMechanism -from .mechanisms_enzyme import BasicCatalysis, MichalisMenten from .mechanisms_binding import One_Step_Binding -from .mechanisms_txtl import Transcription_MM, Translation_MM, Degredation_mRNA_MM, OneStepGeneExpression, SimpleTranscription, SimpleTranslation -from .global_mechanism import Dilution +from .mechanisms_enzyme import BasicCatalysis, MichaelisMenten +from .mechanisms_txtl import (OneStepGeneExpression, SimpleTranscription, + SimpleTranslation, Transcription_MM, + Translation_MM) from .mixture import Mixture -from .chemical_reaction_network import Species, ChemicalReactionNetwork -from .dna_assembly import DNAassembly - -#A Model for Gene Expression without any Machinery (eg Ribosomes, Polymerases, etc.) -# Here transcription and Translation are lumped into one reaction: expression. + + class ExpressionExtract(Mixture): - def __init__(self, name="", mechanisms={}, components=[], **kwargs): + """A Model for Gene Expression without any Machinery (eg Ribosomes, Polymerases, etc.). + + Here transcription and Translation are lumped into one reaction: expression. + """ + def __init__(self, name="", **kwargs): + """Initializes an ExpressionExtract instance. - dummy_translation = EmptyMechanism(name = "dummy_translation", mechanism_type = "translation") + :param name: name of the mixture + :param kwargs: keywords passed into the parent Class (Mixture) + """ + # always call the superlcass Mixture.__init__(...) + Mixture.__init__(self, name=name, **kwargs) + + # Create default Expression Mechanisms + dummy_translation = EmptyMechanism(name="dummy_translation", mechanism_type="translation") mech_expression = OneStepGeneExpression() mech_cat = BasicCatalysis() mech_bind = One_Step_Binding() @@ -30,46 +42,42 @@ def __init__(self, name="", mechanisms={}, components=[], **kwargs): mech_bind.mechanism_type: mech_bind } - default_components = [] - Mixture.__init__(self, name=name, default_mechanisms=default_mechanisms, mechanisms=mechanisms, - components=components+default_components, **kwargs) + self.add_mechanisms(default_mechanisms) - #Overwriting compile_crn to replace transcripts with proteins for all DNA_assemblies def compile_crn(self) -> ChemicalReactionNetwork: - """ Creates a chemical reaction network from the species and reactions associated with a mixture object - :return: ChemicalReactionNetwork + """Overwriting compile_crn to turn off transcription in all DNAassemblies + + :return: compiled CRN instance """ - resetwarnings()#Reset warnings - better to toggle them off manually. - species = self.update_species() - reactions = self.update_reactions() - - for comp in self.components: - if isinstance(comp, DNAassembly): - if comp.transcript is not None and comp.protein is not None: - for i, s in enumerate(species): - species[i] = s.replace_species(comp.transcript, comp.protein) - for i, r in enumerate(reactions): - reactions[i] = r.replace_species(comp.transcript, comp.protein) - - self.crn_species = list(set(species)) - self.crn_reactions = reactions - #global mechanisms are applied last and only to all the species - global_mech_species, global_mech_reactions = self.apply_global_mechanisms() - - species += global_mech_species - reactions += global_mech_reactions - - species = self.set_initial_condition(species) - species.sort(key = lambda s:repr(s)) - reactions.sort(key = lambda r:repr(r)) - CRN = ChemicalReactionNetwork(species, reactions) - return CRN - -#A Model for Transcription and Translation in an extract any Machinery (eg Ribosomes, Polymerases, etc.) -#RNA is degraded via a global mechanism + for component in self.components: + if isinstance(component, DNAassembly): + # Only turn off transcription for an Assembly that makes a Protein. + # Some assemblies might only make RNA! + if component.protein is not None: + # This will turn off transcription and set Promoter.transcript = False + # Mechanisms that recieve no transcript but a protein will use the protein instead. + component.update_transcript(False) + + # Call the superclass function + return Mixture.compile_crn(self) + + class SimpleTxTlExtract(Mixture): - def __init__(self, name="", mechanisms={}, components=[], **kwargs): + """ + A Model for Transcription and Translation in an extract any Machinery (eg Ribosomes, Polymerases, etc.) + RNA is degraded via a global mechanism. + """ + + def __init__(self, name="", **kwargs): + """Initializes a SimpleTxTlExtract instance. + :param name: name of the mixture + :param kwargs: keywords passed into the parent Class (Mixture) + """ + # Always call the superlcass Mixture.__init__(...) + Mixture.__init__(self, name=name, **kwargs) + + # TxTl Mechanisms mech_tx = SimpleTranscription() mech_tl = SimpleTranslation() mech_cat = BasicCatalysis() @@ -81,36 +89,51 @@ def __init__(self, name="", mechanisms={}, components=[], **kwargs): mech_cat.mechanism_type: mech_cat, mech_bind.mechanism_type: mech_bind } + self.add_mechanisms(default_mechanisms) - mech_rna_deg_global = Dilution(name = "rna_degredation", filter_dict = {"rna":True}, default_on = False) - global_mechanisms = {"rna_degredation":mech_rna_deg_global} + # global mechanisms for dilution and rna degredation + mech_rna_deg_global = Dilution(name="rna_degredation", filter_dict={"rna": True}, default_on=False) + global_mechanisms = {"rna_degredation": mech_rna_deg_global} + self.add_mechanisms(global_mechanisms) - default_components = [] - Mixture.__init__(self, name=name, default_mechanisms=default_mechanisms, mechanisms=mechanisms, - components=components+default_components, global_mechanisms= global_mechanisms, **kwargs) -#A Model for Transcription and Translation in Cell Extract with Ribosomes, Polymerases, and Endonucleases. -#This model does not include any energy class TxTlExtract(Mixture): - def __init__(self, name="", mechanisms={}, components=[], - rnap = "RNAP", ribosome = "Ribo", rnaase = "RNAase", **kwargs): + """A Model for Transcription and Translation in Cell Extract with Ribosomes, Polymerases, and Endonucleases. + + This model does not include any energy + """ + def __init__(self, name="", rnap="RNAP", ribosome="Ribo", rnaase="RNAase", **kwargs): + """Initializes a TxTlExtract instance. + + :param name: name of the mixture + :param rnap: name of the RNA polymerase, default: RNAP + :param ribosome: name of the ribosome, default: Ribo + :param rnaase: name of the Ribonuclease, default: RNAase + :param kwargs: keywords passed into the parent Class (Mixture) + """ + # Always call the superlcass Mixture.__init__(...) + Mixture.__init__(self, name=name, **kwargs) + # create default Components to represent cellular machinery self.rnap = Protein(rnap) self.ribosome = Protein(ribosome) self.rnaase = Protein(rnaase) init = kwargs.get('init') if init: - self.rnap.get_species().initial_concentration = init[rep(rnap)] + self.rnap.get_species().initial_concentration = init[repr(rnap)] self.rnaase.get_species().initial_concentration = init[repr(rnaase)] self.ribosome.get_species().initial_concentration = init[repr(ribosome)] - mech_tx = Transcription_MM(rnap = self.rnap.get_species()) - mech_tl = Translation_MM(ribosome = self.ribosome.get_species()) - mech_rna_deg = Degredation_mRNA_MM(nuclease = self.rnaase.get_species()) - mech_cat = MichalisMenten() - mech_bind = One_Step_Binding() + default_components = [self.rnap, self.ribosome, self.rnaase] + self.add_components(default_components) + # Create default TxTl Mechanisms + mech_tx = Transcription_MM(rnap=self.rnap.get_species()) + mech_tl = Translation_MM(ribosome=self.ribosome.get_species()) + mech_rna_deg = Degredation_mRNA_MM(nuclease=self.rnaase.get_species()) + mech_cat = MichaelisMenten() + mech_bind = One_Step_Binding() default_mechanisms = { mech_tx.mechanism_type: mech_tx, @@ -119,7 +142,4 @@ def __init__(self, name="", mechanisms={}, components=[], mech_cat.mechanism_type: mech_cat, mech_bind.mechanism_type: mech_bind } - - default_components = [self.rnap, self.ribosome, self.rnaase] - Mixture.__init__(self, name=name, default_mechanisms=default_mechanisms, mechanisms=mechanisms, - components=components+default_components, **kwargs) + self.add_mechanisms(default_mechanisms) diff --git a/biocrnpyler/parameter.py b/biocrnpyler/parameter.py index 2292a202..2cb5b12f 100644 --- a/biocrnpyler/parameter.py +++ b/biocrnpyler/parameter.py @@ -5,30 +5,11 @@ # parameters, as well as utility functions for manipulating # parameters. # -# Copyright (c) 2018, Build-A-Cell. All rights reserved. +# Copyright (c) 2020, Build-A-Cell. All rights reserved. # See LICENSE file in the project root directory for details. -""" -Parameter processing --------------------- - -Parameters are used to set the rate constants for reactions, as well -as the initial concentrations of extract and buffer. - -Please see the Parameter ipynb in examples for details on mechanism parameters. - -#### Parameter File Overview: -Parameter files can be TSVs or CSVs. The first line of the file should contain column headings. -The following headings are required (in any order): mechanism_id, part_id, param_name, param_val - (spaces can be substituted for underscores and headings are not case sensitive). - -mechanism_id is the name of the Mechanism or the kind of mechanism that will use this parameter, - for example "transcription" or "transcription_mm" for Mechalis-Menten transcription would go in this column. -part_id refers to the name of the Component that will use this mechanism, - for example "ptet" for a tet repressed promoter. -param_name refers to the name of the model parameter, - for example "ktx", "kb", or "ku". The value of these columns is case sensitive and underscores are different from spaces. +""" #### Parameter Value Defaulting: Not all parameters need to have the required headings. The only two required columns are "param_val" and "param_name". @@ -42,7 +23,7 @@ the software will default to the following keys: (mechanism_type, part_id, param_name) >> (part_id, param_name) >> (mechanism_name, param_name) >> (mechanism_type, param_name) >> - (param_name) and give a warning. + (param_name) and give a warning. As a note, mechanism_name refers to the .name variable of a Mechanism. mechanism_type refers to the .type variable of a Mechanism. Either of these can be used as a mechanism_id. This allows for models to be constructed easily using default parameter values and for parameters to be shared between different Mechanisms and/or Components. @@ -64,103 +45,345 @@ # Then checks if (mixture.name, component.name) is in the parameter dictionary # Then checks if component.name is in the parameter dictionary # Then defaults to 0 - -#### Multiple Parameter Files: -Components and Mixtures can both have one more multiple parameter files by passing in a list of filenames - instead of a single filename to the parameter_file keyword. - Components use parameters loaded from their file(s) before defaulting to the file(s) supplied to a Mixture. - The last file in any list will take precedent and overwrite parameter files which were written earlier. - -#### Suppressing warnings -To suppress parameter warnings, use the keyword parameter_warnings = False inside a Mixture or Component constructor. - -Below is an example csv with all the parameters for a tetR promoter undergoing Michalis Menten transcription and translation. - """ import csv +import numbers +import re +from collections import namedtuple # Used for the parameter keys +from typing import Dict, List, Union from warnings import warn -from typing import List, Dict, Union + +ParameterKey = namedtuple('ParameterKey', 'mechanism part_id name') # This could later be extended class Parameter(object): - """Parameter value (reaction rates)""" - - def __init__(self, name, param_type, value, comment="", debug=False): - if not isinstance(param_type, str): - raise ValueError('parameter_type must be a string') - - self.name = name.strip() - self.param_type = param_type.strip() - self.comment = comment.strip() - - # Set the value of the parameter - if debug: - print("%s [%s] = %s" % (self.name, self.param_type, value)) - if param_type.strip() == 'Numeric': - self.value = float(value) # store as float - elif param_type.strip() == 'Expression': - self.value = value # store as string + def __init__(self, parameter_name: str, parameter_value: Union[str, numbers.Real]): + """A class for representing parameters in general. Only the below subclasses are ever used. + + :param parameter_name: is the name of the parameter + :param parameter_value: is the value of the parameter + """ + self.parameter_name = parameter_name + self.value = parameter_value + + @property + def parameter_name(self) -> str: + return self._parameter_name + + @parameter_name.setter + def parameter_name(self, new_parameter_name: str): + if not isinstance(new_parameter_name, str): + raise ValueError(f"parameter_name must be a string: received {type(new_parameter_name)}.") + if not re.search('^[a-z]+', new_parameter_name, re.IGNORECASE): + raise ValueError(f'parameter_name should be at least one character and cannot start with a number!') + + self._parameter_name = new_parameter_name + + @property + def value(self) -> numbers.Real: + return self._value + + @value.setter + def value(self, new_parameter_value: Union[str, numbers.Real]): + if not (isinstance(new_parameter_value, numbers.Real) or isinstance(new_parameter_value, str)): + raise ValueError(f"parameter_value must be a float or int: received {type(new_parameter_value)}.") + if isinstance(new_parameter_value, str): + if re.search('[a-d-f-z]', new_parameter_value, re.I) \ + or re.search('(^[1-9]+/[1-9]+)|(^[1-9]+e-?[0-9]+)|(^.?[0-9])', new_parameter_value, re.I) is None: + raise ValueError(f'No valid parameter value! Accepted formats: 1.00 or 1e4 or 2/5, we got {new_parameter_value} ') + + self._value = Parameter._convert_rational(new_parameter_value) else: - raise ValueError("can't parse value of parameter %s" % name) + self._value = new_parameter_value @staticmethod - def _get_field_names(field_names: List[str], accepted_field_names: Dict[str, List[str]]) -> Dict[str, str]: - """ Searches through valid field names and finds the currently used one. It builds a dictionary of currently - used field names - :param field_names: list of field names (columns) found in the csv file - :param accepted_field_names: dictionary of possible field names and their valid aliases - :return: dictionary of currently used field names (aliases) + def _convert_rational(p_value: str) -> numbers.Real: + if '/' in p_value: + nom, denom = p_value.split('/') + return float(nom)/float(denom) + else: + return float(p_value) + + def __str__(self): + return f"Parameter {self.parameter_name} = {self.value}" + + +class ParameterEntry(Parameter): + """A class for representing parameters in a parameter stored the ParameterDatabase. + + parameter_keys is a dictionary {key:value} or named_tuple (type ParameterKey) of keys for looking up the parameter + parameter_info is a dictionary {key:value} of additional information about the parameter. + For example: additional columns in the parameter file or the parameter file name. + """ + def __init__(self, parameter_name: str, parameter_value: Union[str,numbers.Real], parameter_key=None, parameter_info=None): + Parameter.__init__(self, parameter_name, parameter_value) + + self.parameter_key = parameter_key + self.parameter_info = parameter_info + + # Helper function to create ParameterKeys + @staticmethod + def create_parameter_key(new_key: Union[Dict, ParameterKey, str], parameter_name=None) -> ParameterKey: + # New Key can be a named_tuple + if isinstance(new_key, dict): + new_key = dict(new_key) + if parameter_name is not None: + new_key["name"] = parameter_name + for k in ParameterKey._fields: + if k not in new_key: + new_key[k] = None + return ParameterKey(**new_key) #automatically unpack the keywords + elif isinstance(new_key, ParameterKey): + return new_key + elif isinstance(new_key, tuple) and len(list(new_key)) == len(ParameterKey._fields): + # make a dictionary assuming correct ordering + keywords = {ParameterKey._fields[i]:new_key[i] for i in range(len(ParameterKey._fields))} + return ParameterKey(**keywords) #automatically unpack the keywords + elif isinstance(new_key, str): + return ParameterKey(mechanism = None, part_id = None, name = new_key) + elif new_key is None and parameter_name is not None: + return ParameterKey(mechanism = None, part_id = None, name = parameter_name) + else: + raise ValueError(f"parameter_key must be None, a dictionary, a ParameterKey, a {len(ParameterKey._fields)}-tuple, or a string (parameter name): received {new_key}.") + + @property + def parameter_key(self) -> ParameterKey: + return self._parameter_key + + @parameter_key.setter + def parameter_key(self, parameter_key: Union[Dict, ParameterKey, str]): + self._parameter_key = self.create_parameter_key(parameter_key, self.parameter_name) + + @property + def parameter_info(self) -> Dict: + return self._parameter_info + + @parameter_info.setter + def parameter_info(self, parameter_info: Dict): + if parameter_info is None: + self._parameter_info = {} + elif isinstance(parameter_info, dict): + self._parameter_info = dict(parameter_info) + else: + raise ValueError(f"parameter_info must be None or a dictionary: received {parameter_info}.") + + def get_sbml_id(self): + sbml_id = self.parameter_key.name+"_" + if self.parameter_key.part_id is not None: + sbml_id += self.parameter_key.part_id + sbml_id += "_" + if self.parameter_key.mechanism is not None: + sbml_id += self.parameter_key.mechanism + return sbml_id + + def __str__(self): + return f"ParameterEntry({self.parameter_key}) = {self.value}" + + +class ModelParameter(ParameterEntry): + """A class for representing parameters used in the Model. + + search_key is a tuple searched for to find the parameter, eg (mech_id, part_id, param_name), : + found_key is the tuple used after defaulting to find the parameter eg (param_name) + """ + def __init__(self, parameter_name: str, parameter_value: Union[str, numbers.Real], search_key, found_key, parameter_key=None, parameter_info=None): + + ParameterEntry.__init__(self, parameter_name, parameter_value, parameter_key=parameter_key, parameter_info=parameter_info) + self.search_key = search_key + self.found_key = found_key + + @property + def search_key(self): + return self._search_key + + @search_key.setter + def search_key(self, search_key): + self._search_key = self.create_parameter_key(search_key, self.parameter_name) + + @property + def found_key(self): + return self._found_key + + @found_key.setter + def found_key(self, found_key): + self._found_key = self.create_parameter_key(found_key, self.parameter_name) + + def __str__(self): + return f"ModelParameter({self.parameter_key}) = {self.value}\tsearch_key={self.search_key}" + + +class ParameterDatabase(object): + def __init__(self, parameter_dictionary=None, parameter_file=None, overwrite_parameters=False): + """A class for storing parameters in Components and Mixtures. + + :param parameter_dictionary: + :param parameter_file: + :param overwrite_parameters: whether to overwrite existing entries in the parameter database """ - if not isinstance(field_names, list): - raise ValueError('field_names must be a list of strings') - if isinstance(field_names, list) and len(field_names) == 0: - raise ValueError('field_names cannot be empty list!') - if not isinstance(accepted_field_names, dict): - raise ValueError('accepted_field_names must be a dictionary') - if isinstance(accepted_field_names, dict) and len(accepted_field_names) == 0: - raise ValueError('accepted_field_names cannot be empty dictionary') - return_field_names = dict.fromkeys(accepted_field_names.keys()) - for accepted_name in accepted_field_names: - # try to find an possible accepted names in the field_names using a generator + self.parameters = {} #create an emtpy dictionary to get parameters. + + if isinstance(parameter_file, str): + self.load_parameters_from_file(parameter_file, overwrite_parameters = overwrite_parameters) + elif isinstance(parameter_file, list): + for p in parameter_file: + if isinstance(p, str): + self.load_parameters_from_file(p, overwrite_parameters = overwrite_parameters) + else: + raise ValueError("parameter_file must be a string or list of strings representing file names and paths.") + elif parameter_file is not None: + raise ValueError("parameter_file must be a string representing a file name and path.") + + if isinstance(parameter_dictionary, dict): + self.load_parameters_from_dictionary(parameter_dictionary, overwrite_parameters = overwrite_parameters) + elif parameter_dictionary is not None: + raise ValueError("parameter_dictionary must be None or a dictionary!") + + # To check if a key or ParameterEntry is in a the ParameterDatabase + def __contains__(self, val): + if isinstance(val, ParameterEntry): + key = val.parameter_key + if key in self.parameters and self.parameters[key] == val: + return True + else: + return False + else: try: - loc_gen = (idx for idx, name in enumerate(accepted_field_names[accepted_name]) if name in field_names) - loc_idx = next(loc_gen) - except StopIteration: - # we have reached the end of the possible names - return_field_names[accepted_name] = None - warn(f"parameter file contains no {accepted_name} column! Please add a " - f"column named {accepted_field_names[accepted_name]}.") + key = ParameterEntry.create_parameter_key(val) + return key in self.parameters + except ValueError: + return False + + # Ability to loop through parameters eg + # for entry in ParameterDatabase: ... + def __iter__(self): + self.keys = list(self.parameters.keys()) + self.current_key_ind = 0 + return self + + def __next__(self): + if self.current_key_ind < len(self.keys): + key = self.keys[self.current_key_ind] + entry = self.parameters[key] + self.current_key_ind += 1 + return entry + else: + raise StopIteration + + # Length method + def __len__(self): + return len(self.parameters) + + # Gets a parameter from the database + # Only returns exact matches. + def __getitem__(self, key): + param_key = ParameterEntry.create_parameter_key(key) + return self.parameters[param_key] + + # Sets a parameter in the databases - useful for quickly changing parameters, but add_parameter is recommended. + def __setitem__(self, parameter_key, value): + + key = ParameterEntry.create_parameter_key(parameter_key) + + if isinstance(value, ParameterEntry): + if key != value.parameter_key: + raise ValueError(f"Parameter Key does not match: ParameterDatabase key {key} is not the same as ParameterEntry Key {value.parameter_key}.") + self.parameters[key] = value + else: + self.add_parameter(key.name, value, parameter_key = key, parameter_origin = "Set Manually", overwrite_parameters = True) + + def __str__(self): + txt = "ParameterDatabase:" + param_txt = "\n".join([repr(p) for p in self.parameters]) + return txt+param_txt + + def add_parameter(self, parameter_name: str, parameter_value: Union[str,numbers.Real], parameter_origin = None, parameter_key = None, parameter_info = None, overwrite_parameters = False): + """Adds a parameter to the database with appropriate metadata + + :param parameter_name: the name of the parameter + :param parameter_value: the value of the parameter + :param parameter_origin: + :param parameter_key: + :param parameter_info: + :param overwrite_parameters: whether to overwrite existing entries in the parameter database + :return: + """ + + # Put parameter origin into parameter_info + if parameter_info is None: + parameter_info = {} + if "parameter origin" not in parameter_info: + parameter_info["parameter origin"] = parameter_origin + + # Create ParameterEntry + param = ParameterEntry(parameter_name, parameter_value, parameter_key = parameter_key, parameter_info = parameter_info) + key = param.parameter_key + + # Update parameter dictionary + if key in self.parameters and not overwrite_parameters: + raise ValueError(f"Duplicate parameter detected. Parameter with key = {key} is already in the ParameterDatabase. To Overwrite existing parameters, use overwrite_parameters = True.") + else: + self.parameters[key] = param + + def load_parameters_from_dictionary(self, parameter_dictionary: Dict[ParameterKey, Union[str,numbers.Real]], overwrite_parameters=False) -> None: + """Loads Parameters from a parameter dictionary. + + :param parameter_dictionary: Dictionary with keys ParameterKey types and values with real numbers + :param overwrite_parameters: whether to overwrite existing entries in the parameter database + """ + for k in parameter_dictionary: + key = ParameterEntry.create_parameter_key(k) + self.add_parameter(key.name, parameter_dictionary[k], parameter_key = {"part_id":key.part_id, "mechanism":key.mechanism}, parameter_origin = "parameter_dictionary", overwrite_parameters = overwrite_parameters) + + def load_parameters_from_database(self, parameter_database, overwrite_parameters=False) -> None: + """Loads parameters from another ParameterDatabase. + + :param parameter_database: instance of another ParameterDatabase + :param overwrite_parameters: whether to overwrite existing entries in the parameter database + """ + + if not isinstance(parameter_database, ParameterDatabase): + raise TypeError(f"paramater_database must be a ParamaterDatabase: recievied {parameter_database}.") + + for k in parameter_database: + if k not in self.parameters or overwrite_parameters: + self.parameters[k.parameter_key] = parameter_database[k.parameter_key] else: - return_field_names[accepted_name] = accepted_field_names[accepted_name][loc_idx] + raise ValueError(f"Duplicate parameter detected. Parameter with key = {k} is already in the ParameterDatabase. To Overwrite existing parameters, use overwrite_parameters = True.") - return return_field_names + def load_parameters_from_file(self, filename: str, overwrite_parameters=False) -> None: + """Loads parameters from a file to the ParameterDatabase. - @staticmethod - def load_parameter_file(filename: str) -> Dict: - """load the parameter configuration file into a dictionary - :param filename: valid parameter file name - :return: a dictionary of the parameters + Parameter files must be tab-separated (.tsv or .txt) or comma-separated (.csv) files! + :param filename: name of the file (with valid file path) + :param overwrite_parameters: whether to overwrite existing entries in the parameter database """ - assert isinstance(filename, str) and len(filename) > 0 - param_dict = {} - # TODO implement search through possible parameter config file locations - # Open up the CSV file for reaching + + # Figure out the format of the parameter file from the file extension with open(filename) as f: - csvreader = csv.DictReader(f, delimiter='\t') + file_type = filename.split(".")[-1] + if file_type in ["tsv", "txt"]: + delimiter = '\t' + elif file_type in ["csv"]: + delimiter = "," + else: + raise ValueError("Parameter files must be tab-seperated (.tsv or .txt) or comma-seperated (.csv) files.") - accepted_field_names = {'mechanism': ['mechanism', 'mechanism_id'], - 'param_name': ["parameter_name", "parameter", "param", "param_name"], - 'part_id': ['part_id', 'part'], - 'param_val': ["val", "value", "param_val", "parameter_value"] - } + csvreader = csv.DictReader(f, delimiter=delimiter) + # Used for flexible column headings + accepted_field_names = { + 'mechanism': ['mechanism', 'mechanism_id'], + 'param_name': ["parameter_name", "parameter", "param", "param_name"], + 'part_id': ['part_id', 'part'], + 'param_val': ["val", "value", "param_val", "parameter_value"] + } - field_names = Parameter._get_field_names(csvreader.fieldnames, accepted_field_names) + field_names = self._get_field_names(csvreader.fieldnames, accepted_field_names) + # Determine which columns are in the CSV if field_names['param_name'] is None: - warn('No param name column was found, could not load parameter') - return param_dict + warn('No param_name column was found, could not load parameter!') if field_names['mechanism'] is None: no_mechism_column = True else: @@ -171,79 +394,149 @@ def load_parameter_file(filename: str) -> Dict: else: no_part_id_column = False + #Load all parameters for row in csvreader: - # TODO what about integers? float might cause numerical drift in simulations, e.g. cooperativity=2.001 - param_value = float(row[field_names['param_val']]) + param_value = row[field_names['param_val']] + field_columns = [field_names['param_name'], field_names['part_id'], field_names['mechanism'], field_names['param_val']] + parameter_info = {k:row[k] for k in row if k not in field_columns} # TODO test all these cases! + + # Case 1: No Param Name so skip the row if row[field_names['param_name']] is None or len(row[field_names['param_name']]) == 0: pass + + # Case 2: Just a Param Name elif no_mechism_column and no_part_id_column: param_name = row[field_names['param_name']] - param_dict[param_name] = param_value + self.add_parameter(param_name, param_value, parameter_origin = filename, + parameter_info = parameter_info, overwrite_parameters = overwrite_parameters) + + # Case 3: Part_id and Param Name elif no_mechism_column and no_part_id_column is False: - if row[field_names['part_id']] is not None and len(row[field_names['part_id']]) > 0: - part_id = row[field_names['part_id']] - param_name = row[field_names['param_name']] - param_dict[(part_id, param_name)] = param_value + param_name = row[field_names['param_name']] + part_id = row[field_names['part_id']] + + if part_id is not None and len(part_id) > 0: + self.add_parameter(param_name, param_value, parameter_key = {"part_id":part_id}, parameter_origin = filename, + parameter_info = parameter_info, overwrite_parameters = overwrite_parameters) else: - param_name = row[field_names['param_name']] - param_dict[param_name] = param_value + self.add_parameter(param_name, param_value, parameter_origin = filename, + parameter_info = parameter_info , overwrite_parameters = overwrite_parameters) + + # Case 4: mechanism and param name elif no_part_id_column and no_mechism_column is False: - if row[field_names['mechanism']] is not None and len(row[field_names['mechanism']]) > 0: - mech_name = row[field_names['mechanism']] - param_name = row[field_names['param_name']] - param_dict[(mech_name, param_name)] = param_value + mech_name = row[field_names['mechanism']] + param_name = row[field_names['param_name']] + if mech_name is not None and len(mech_name) > 0: + self.add_parameter(param_name, param_value, parameter_key = {"mechanism":mech_name}, parameter_origin = filename, + parameter_info = parameter_info, overwrite_parameters = overwrite_parameters) else: - param_name = row[field_names['param_name']] - param_dict[param_name] = param_value + self.add_parameter(param_name, param_value, parameter_origin = filename, + parameter_info = parameter_info, overwrite_parameters = overwrite_parameters) + + # Case 5: mechanism, part_id, and param name else: - if row[field_names['part_id']] is not None and len(row[field_names['part_id']]) > 0: - if row[field_names['mechanism']] is not None and len(row[field_names['mechanism']]) > 0: - part_id = row[field_names['part_id']] - mech_name = row[field_names['mechanism']] - param_name = row[field_names['param_name']] - param_dict[(mech_name, part_id, param_name)] = param_value - else: - part_id = row[field_names['part_id']] - param_name = row[field_names['param_name']] - param_dict[(part_id, param_name)] = param_value + part_id = row[field_names['part_id']] + mech_name = row[field_names['mechanism']] + param_name = row[field_names['param_name']] + if part_id is not None and len(part_id) > 0 and mech_name is not None and len(mech_name) >0: + self.add_parameter(param_name, param_value, parameter_key = {"part_id":part_id, "mechanism":mech_name}, parameter_origin = filename, + parameter_info = parameter_info, overwrite_parameters = overwrite_parameters) + + elif part_id is not None and len(part_id) > 0: + self.add_parameter(param_name, param_value, parameter_key = {"part_id":part_id}, parameter_origin = filename, + parameter_info = parameter_info, overwrite_parameters = overwrite_parameters) + + elif mech_name is not None and len(mech_name) >0: + self.add_parameter(param_name, param_value, parameter_key = {"mechanism":mech_name}, parameter_origin = filename, + parameter_info = parameter_info, overwrite_parameters = overwrite_parameters) else: - if row[field_names['mechanism']] is not None and len(row[field_names['mechanism']]) > 0: - mech_name = row[field_names['mechanism']] - param_name = row[field_names['param_name']] - param_dict[(mech_name, param_name)] = param_value - else: - param_name = row[field_names['param_name']] - param_dict[param_name] = param_value - return param_dict + self.add_parameter(param_name, param_value, parameter_origin = filename, + parameter_info = parameter_info, overwrite_parameters = overwrite_parameters) @staticmethod - def create_parameter_dictionary(parameters: Union[None, Dict], - parameter_file: Union[None, str, List[str]]) -> Union[None, Dict]: - """ - Loads parameter config file(s) and merges the parameters with the existing parameters dictionary - :param parameters: existing parameters dictionary or None - :param parameter_file: valid parameter file(s) - :return: updated parameters dictionary (empty dict if no parameter file was given) + def _get_field_names(field_names: List[str], accepted_field_names: Dict[str, List[str]]) -> Dict[str, str]: + """Searches through valid field names and finds the currently used one. It builds a dictionary of currently + used field names. + + :param field_names: list of field names (columns) found in the csv file + :param accepted_field_names: dictionary of possible field names and their valid aliases + :return: dictionary of currently used field names (aliases) """ + if not isinstance(field_names, list): + raise ValueError('field_names must be a list of strings') + if isinstance(field_names, list) and len(field_names) == 0: + raise ValueError('field_names cannot be empty list!') + if not isinstance(accepted_field_names, dict): + raise ValueError('accepted_field_names must be a dictionary') + if isinstance(accepted_field_names, dict) and len(accepted_field_names) == 0: + raise ValueError('accepted_field_names cannot be empty dictionary') - # no parameter dictionary was given creating one - if not isinstance(parameters, dict): - parameters = {} + return_field_names = dict.fromkeys(accepted_field_names.keys()) + for accepted_name in accepted_field_names: + # try to find an possible accepted names in the field_names using a generator + try: + loc_gen = (idx for idx, name in enumerate(accepted_field_names[accepted_name]) if name in field_names) + loc_idx = next(loc_gen) + except StopIteration: + # we have reached the end of the possible names + return_field_names[accepted_name] = None + warn(f"parameter file contains no {accepted_name} column! Please add a " + f"column named {accepted_field_names[accepted_name]}.") + else: + return_field_names[accepted_name] = accepted_field_names[accepted_name][loc_idx] - # empty parameter_file no new parameters are loaded - if parameter_file is None: - return parameters + return return_field_names - assert isinstance(parameter_file, str) or isinstance(parameter_file, list) + def find_parameter(self, mechanism, part_id, param_name): + """Searches the database for the best matching parameter. + + Parameter defaulting hierarchy: + (mechanism_name, part_id, param_name) --> param_val. If that particular parameter key cannot be found, + the software will default to the following keys: + (mechanism_type, part_id, param_name) >> (part_id, param_name) >> + (mechanism_name, param_name) >> (mechanism_type, param_name) >> + (param_name) and give a warning. + As a note, mechanism_name refers to the .name variable of a Mechanism. mechanism_type refers to the .type variable of a Mechanism. + Either of these can be used as a mechanism_id. This allows for models to be constructed easily using default parameter values and + for parameters to be shared between different Mechanisms and/or Components. + """ - if isinstance(parameter_file, list): - file_list = parameter_file - else: - file_list = [parameter_file] + #this is imported here because otherwise there are import loops + from .mechanism import Mechanism - for file_name in file_list: - new_parameters = Parameter.load_parameter_file(file_name) - parameters.update(new_parameters) + found_entry = None - return parameters + if isinstance(mechanism, str): + mech_name = mechanism + mech_type = mechanism + elif isinstance(mechanism, Mechanism): + mech_name = mechanism.name + mech_type = mechanism.mechanism_type + elif mechanism is not None: + raise ValueError(f"mechanism keyword must be or string or have name and mechanism_type attributes: recievied {mechanism}.") + else: + mech_name = None + mech_type = None + + parameter_key_list = [ + ParameterKey(mechanism = mech_name, part_id = part_id, name = param_name), + ParameterKey(mechanism = mech_type, part_id = part_id, name = param_name), + ParameterKey(mechanism = None, part_id = part_id, name = param_name), + ParameterKey(mechanism = mech_name, part_id = None, name = param_name), + ParameterKey(mechanism = mech_type, part_id = None, name = param_name), + ParameterKey(mechanism = None, part_id = None, name = param_name), + ] + + for key in parameter_key_list: + if key in self.parameters and found_entry is None: + found_entry = self.parameters[key] + found_key = key + break + + if found_entry is None: + return None + else: + return_param = ModelParameter(found_entry.parameter_name,found_entry.value, (mech_name, part_id, param_name), found_key, + parameter_key = found_entry.parameter_key, parameter_info = found_entry.parameter_info) + return return_param diff --git a/biocrnpyler/pathutil.py b/biocrnpyler/pathutil.py index f68f73d2..79289b27 100644 --- a/biocrnpyler/pathutil.py +++ b/biocrnpyler/pathutil.py @@ -4,15 +4,15 @@ # This file contains some utility functions for manipulating and using # paths for finding models and configuration files. # -# Copyright (c) 2018, Build-A-Cell. All rights reserved. +# Copyright (c) 2020, Build-A-Cell. All rights reserved. # See LICENSE file in the project root directory for details. from importlib import import_module def load_model(prefix, name, length): - """ - Load a model from a file + """Load a model from a file. + Look to see if we have a model for this component """ #! Expand this to look in other locations diff --git a/biocrnpyler/plotting.py b/biocrnpyler/plotting.py index 3d088680..2c4725a7 100644 --- a/biocrnpyler/plotting.py +++ b/biocrnpyler/plotting.py @@ -1,4 +1,4 @@ -# pathutil.py - path utilities +# plotting.py - plotting utilities # ASS, 21 Apr 2020 # # This file contains some utility functions for plotting CRNs @@ -6,17 +6,51 @@ # Copyright (c) 2018, Build-A-Cell. All rights reserved. # See LICENSE file in the project root directory for details. +import math import random -import networkx as nx import statistics -from bokeh.models import (BoxSelectTool, Circle,Square, EdgesAndLinkedNodes, HoverTool, - MultiLine, NodesAndLinkedEdges, Plot, Range1d, TapTool,PanTool,WheelZoomTool) -from bokeh.palettes import Spectral4 -from bokeh.models.graphs import from_networkx -from fa2 import ForceAtlas2 -import numpy as np -from matplotlib import cm -import matplotlib.pyplot as plt +from warnings import warn + +from .components_basic import Protein +from .dna_part_cds import CDS +from .dna_part_misc import AttachmentSite +from .dna_part_promoter import Promoter +from .dna_part_rbs import RBS +from .dna_part_terminator import Terminator +from .propensities import MassAction + +HAVE_MATPLOTLIB = False +try: + import matplotlib.pyplot as plt + from matplotlib import cm + + HAVE_MATPLOTLIB = True +except ModuleNotFoundError: + pass +PLOT_DNA = False +try: + import dnaplotlib as dpl + PLOT_DNA = True +except ModuleNotFoundError: + pass + +if(PLOT_DNA and not HAVE_MATPLOTLIB): + PLOT_DNA = False + +PLOT_NETWORK = False +try: + import networkx as nx + from bokeh.models import (BoxSelectTool, Circle, EdgesAndLinkedNodes, + HoverTool, MultiLine, NodesAndLinkedEdges, + PanTool, Plot, Range1d, Square, TapTool, + WheelZoomTool) + from bokeh.models.graphs import from_networkx + from bokeh.palettes import Spectral4 + from fa2 import ForceAtlas2 + PLOT_NETWORK = True +except ModuleNotFoundError: + pass + def updateLimits(limits,xvalues): for value in xvalues: @@ -26,7 +60,7 @@ def updateLimits(limits,xvalues): limits[1] = value return limits -def makeArrows2(graph_renderer,graph,positions,headsize=3,headangle=np.pi/6): +def makeArrows2(graph_renderer,graph,positions,headsize=3,headangle=math.pi/6): """this function draws an arrow shape at the end of graph lines""" xs,ys = [],[] xbounds = [0,0] @@ -48,22 +82,22 @@ def makeArrows2(graph_renderer,graph,positions,headsize=3,headangle=np.pi/6): xdif = from_x-to_x #next we calculate the angle from the destination node #to the source node - angl = np.arctan2(ydif,xdif) + angl = math.atan2(ydif,xdif) #the arrow consists of three added points, one on either side #of the line and one in the middle - p1x = to_x+headsize*np.cos(angl+headangle) #left side of the arrow - p1y = to_y+headsize*np.sin(angl+headangle) #left side of the arrow - p2x = to_x+headsize*np.cos(angl-headangle) #right side of the arrow - p2y = to_y+headsize*np.sin(angl-headangle) #right side of the arrow - p3x = to_x+headsize*.7*np.cos(angl) #middle of the arrow - p3y = to_y+headsize*.7*np.sin(angl) #middle of the arrow + p1x = to_x+headsize*math.cos(angl+headangle) #left side of the arrow + p1y = to_y+headsize*math.sin(angl+headangle) #left side of the arrow + p2x = to_x+headsize*math.cos(angl-headangle) #right side of the arrow + p2y = to_y+headsize*math.sin(angl-headangle) #right side of the arrow + p3x = to_x+headsize*.7*math.cos(angl) #middle of the arrow + p3y = to_y+headsize*.7*math.sin(angl) #middle of the arrow xs.append([from_x,p3x,p1x,to_x,p2x,p3x]) #'xs' is a list of lists which represent each line from node to node ys.append([from_y,p3y,p1y,to_y,p2y,p3y]) #'ys' is the same thing except the y positions graph_renderer.edge_renderer.data_source.data['xs'] = xs #this part replaces the lines with the ones made by this function graph_renderer.edge_renderer.data_source.data['ys'] = ys return xbounds,ybounds -def graphPlot(DG,DGspecies,DGreactions,plot,layout="force",positions=None,posscale = 1.0,layoutfunc=None): +def graphPlot(DG,DGspecies,DGreactions,plot,layout="force",positions=None,posscale = 1.0,layoutfunc=None,iterations=2000,rseed=30): """given a directed graph, plot it! Inputs: DG: a directed graph of type DiGraph @@ -78,6 +112,10 @@ def graphPlot(DG,DGspecies,DGreactions,plot,layout="force",positions=None,possca positions: a dictionary of node names and x,y positions. this gets passed into the layout function posscale: multiply the scaling of the plot. This only affects the arrows because the arrows are a hack :(""" + random.seed(rseed) + if(not PLOT_NETWORK): + warn("network plotting disabled because some libraries are not found") + return if(layout=="force"): #below are parameters for the force directed graph visualization forceatlas2 = ForceAtlas2( @@ -101,7 +139,7 @@ def graphPlot(DG,DGspecies,DGreactions,plot,layout="force",positions=None,possca # Log verbose=False) - positions = forceatlas2.forceatlas2_networkx_layout(DG, pos=positions, iterations=2000) + positions = forceatlas2.forceatlas2_networkx_layout(DG, pos=positions, iterations=iterations) elif(layout == "circle"): positions = nx.circular_layout(DGspecies,scale=50*posscale) positions.update(nx.circular_layout(DGreactions,scale=35*posscale)) @@ -113,9 +151,9 @@ def graphPlot(DG,DGspecies,DGreactions,plot,layout="force",positions=None,possca #edges edges_renderer.node_renderer.glyph = Circle(size=12,line_alpha=0,fill_alpha=0, fill_color="color") - edges_renderer.edge_renderer.glyph = MultiLine( line_alpha=0.2, line_width=4) - edges_renderer.edge_renderer.selection_glyph = MultiLine(line_color=Spectral4[2], line_width=5) - edges_renderer.edge_renderer.hover_glyph = MultiLine(line_color=Spectral4[1], line_width=5) + edges_renderer.edge_renderer.glyph = MultiLine( line_alpha=0.2, line_width=4,line_join="round") + edges_renderer.edge_renderer.selection_glyph = MultiLine(line_color=Spectral4[2], line_width=5,line_join="round") + edges_renderer.edge_renderer.hover_glyph = MultiLine(line_color=Spectral4[1], line_width=5,line_join="round") xbounds,ybounds = makeArrows2(edges_renderer,DG,positions,headsize=5) #make the arrows! #we want to find the middle of the graph and plot a square that is 1:1 aspect ratio @@ -163,9 +201,7 @@ def graphPlot(DG,DGspecies,DGreactions,plot,layout="force",positions=None,possca def generate_networkx_graph(CRN,useweights=False,use_pretty_print=False,pp_show_material=True, pp_show_rates=True,pp_show_attributes=True, - colordict={"complex":"cyan","protein":"green", - "dna":"grey","rna":"orange", - "ligand":"pink","phosphate":"yellow","nothing":"purple"}): + colordict=None): """generates a networkx DiGraph object that represents the CRN. input: ========================== @@ -200,6 +236,13 @@ def generate_networkx_graph(CRN,useweights=False,use_pretty_print=False,pp_show_ CRNspeciesonly: a DiGraph object with only species CRNreactionsonly: a DiGraph object with only reactions """ + if(not PLOT_NETWORK): + warn("network plotting disabled because some libraries are not found") + return None,None,None + if not colordict: + colordict = {"complex":"cyan","protein":"green", + "dna":"grey","rna":"orange", + "ligand":"pink","phosphate":"yellow","nothing":"purple"} CRNgraph = nx.DiGraph() allnodenum = 1 #every node has an index #this starts at 1 because "nothing" is node 0 @@ -247,35 +290,49 @@ def generate_networkx_graph(CRN,useweights=False,use_pretty_print=False,pp_show_ #reactions follow, allnodenum is not reset between these two loops for rxn in CRN.reactions: CRNgraph.add_node(allnodenum) - CRNgraph.nodes[allnodenum]["type"]=rxn.propensity_type - CRNgraph.nodes[allnodenum]["k"] = rxn.k - CRNgraph.nodes[allnodenum]["k_r"] = rxn.k_r + CRNgraph.nodes[allnodenum]["type"] = str(rxn.propensity_type) + if isinstance(rxn.propensity_type, MassAction): + CRNgraph.nodes[allnodenum]["k"] = str(rxn.propensity_type.k_forward) + CRNgraph.nodes[allnodenum]["k_r"] = str(rxn.propensity_type.k_reverse) + else: + CRNgraph.nodes[allnodenum]["k"] = str(rxn.propensity_type.k) + CRNgraph.nodes[allnodenum]["k_r"] = '' + default_color = "blue" #CRNgraph.nodes[allnodenum] - kval = rxn.k + if isinstance(rxn.propensity_type, MassAction): + kval = rxn.propensity_type.k_forward + CRNgraph.nodes[allnodenum]["k"] = str(kval) + else: + kval = rxn.k + CRNgraph.nodes[allnodenum]["k"] = str(rxn.propensity_type.k) + if(not useweights): kval = 1 - krev_val = rxn.k_r - if((krev_val > 0) and (not useweights)): + if isinstance(rxn.propensity_type, MassAction): + krev_val = rxn.propensity_type.k_reverse + else: + krev_val = None + if((krev_val is not None) and (not useweights)): krev_val = 1 for reactant in rxn.inputs: - CRNgraph.add_edge(nodedict[reactant],allnodenum,weight=kval) - if(krev_val>0): + CRNgraph.add_edge(nodedict[reactant.species],allnodenum,weight=kval) + if(krev_val is not None): #if the k is 0 then the node does not exist, right? - CRNgraph.add_edge(allnodenum,nodedict[reactant],weight=krev_val) + CRNgraph.add_edge(allnodenum,nodedict[reactant.species],weight=krev_val) for product in rxn.outputs: - CRNgraph.add_edge(allnodenum,nodedict[product],weight=kval) - if(krev_val>0): - CRNgraph.add_edge(nodedict[product],allnodenum,weight=krev_val) + CRNgraph.add_edge(allnodenum,nodedict[product.species],weight=kval) + if(krev_val is not None): + CRNgraph.add_edge(nodedict[product.species],allnodenum,weight=krev_val) if(len(rxn.outputs)==0): #this adds an edge to the "nothing" node we made in the beginning CRNgraph.add_edge(allnodenum,0,weight=kval) - if(krev_val>0): + if(krev_val is not None): CRNgraph.add_edge(0,allnodenum,weight=krev_val) elif(len(rxn.inputs)==0): #this adds an edge from the "nothing" node we made in the beginning CRNgraph.add_edge(0,allnodenum,weight=kval) - if(krev_val>0): + if(krev_val is not None): CRNgraph.add_edge(allnodenum,0,weight=krev_val) CRNgraph.nodes[allnodenum]["color"]=default_color if(not use_pretty_print): @@ -290,4 +347,148 @@ def generate_networkx_graph(CRN,useweights=False,use_pretty_print=False,pp_show_ CRNspeciesonly.remove_nodes_from(rxnlist) CRNreactionsonly = CRNgraph.copy() CRNreactionsonly.remove_nodes_from(range(rxnlist[0])) - return CRNgraph,CRNspeciesonly,CRNreactionsonly \ No newline at end of file + return CRNgraph,CRNspeciesonly,CRNreactionsonly + +def make_dpl_from_construct(construct,showlabels=None): + """ This function creats a dictionary suitable for + input into dnaplotlib for plotting constructs. + Inputs: + construct: a DNA_construct object + showlabels: list of part types to show labels for. For example, [AttachmentSite,Terminator]""" + #TODO make showlabels more general + if(showlabels is None): + showlabels = [] + outdesign = [] + if(HAVE_MATPLOTLIB): + cmap = cm.Set1(range(len(construct.parts_list)*2)) + pind = 0 + for part in construct.parts_list: + pcolor = part.color + pcolor2 = part.color2 + if(HAVE_MATPLOTLIB): + if(type(pcolor)==int): + c1 = cmap[pcolor][:-1] + else: + c1 = cmap[pind][:-1] + if(type(pcolor2)==int): + c2 = cmap[pcolor2][:-1] + else: + c2 = cmap[random.choice(list(range(len(construct.parts_list))))][:-1] + showlabel = False + if(type(part) in showlabels): + showlabel = True + outdesign+=make_dpl_from_part(part,direction = part.direction=="forward",\ + color=c1,color2 =c2 ,showlabel=showlabel) + pind+=1 + return outdesign +def make_dpl_from_part(part,direction=None,color=None,color2=None,showlabel=False): + """ This function creats a dictionary suitable for + input into dnaplotlib for plotting constructs. + Inputs: + part: a DNA_part object + direction: True for forward, False for reverse. If you leave it as None, it will take from the DNA_part object + color: this is the color of the part. Tuple with relative rgb values. if the DNA_part has a defined color it will take that first before + looking at this variable + color2: this is the secondary color of the part. Only relevant for RecombinaseSite2 components. Basically the + same idea as color, above + showlabel: if True, the label of this part will be shown.""" + regs = [] + if(direction is None and part.direction is not None): + direction = part.direction=="forward" + elif(direction is None): + direction = True + if(type(part.color) is not int): + color = part.color + elif(color is not None): + part.color = color + if(type(part.color2) is not int): + color2 = part.color2 + elif(color2 is not None): + part.color2 = color2 + dpl_type = "UserDefined" #this is the default part type + if(hasattr(part,"dpl_type")): + part_dpl = part.dpl_type + else: + part_dpl = None + + if(isinstance(part,Promoter)): + dpl_type = "Promoter" + if(hasattr(part,"regulators")): + regs = part.regulators + elif(isinstance(part,RBS)): + dpl_type = "RBS" + elif(isinstance(part,CDS)): + dpl_type = "CDS" + elif(isinstance(part,Protein)): + dpl_type = "CDS" + elif(isinstance(part,Terminator)): + dpl_type = "Terminator" + elif(isinstance(part,AttachmentSite)): + if(part.site_type == "attP" or part.site_type == "attB"): + dpl_type = "RecombinaseSite" + elif(part.site_type == "attL" or part.site_type == "attR"): + dpl_type = "RecombinaseSite2" + if(part_dpl is not None): + #parts can have their own pre-set dnaplotlib types + dpl_type = part_dpl + outdesign = [{'type':dpl_type,"name":part.name,"fwd":direction,'opts':{'color':color,'color2':color2}}] + for reg in regs: + #promoters with regulators have a number of "operator" symbols on them + outdesign += [{"type":"Operator","name":str(reg),"fwd":direction,'opts':{'color':color,'color2':color2}}] + if(showlabel): + outdesign[0]["opts"].update({'label':str(part.name),'label_size':13,'label_y_offset':-8,}) + if(not direction): + outdesign = outdesign[::-1] + return outdesign + +def plotDesign(design,renderer = None,part_renderers=None,\ + circular=False,title=None): + """helper function for doing dnaplotlib plots. You need to set the size and min max of the + plot, and that's what this function does""" + if(PLOT_DNA): + if(renderer is None): + renderer = dpl.DNARenderer(scale = 5,linewidth=3) + if(part_renderers is None): + part_renderers = renderer.SBOL_part_renderers() + fig = plt.figure(figsize=(len(design)*.75,1.1)) + ax = fig.add_axes([0,0,1,1]) + start,end = renderer.renderDNA(ax,design,part_renderers,circular=circular) + ax.axis('off') + if title is not None: + ax.set_title(title) + addedsize=1 + ax.set_xlim([start-addedsize,end+addedsize]) + ax.set_ylim([-15,15]) + plt.show() + else: + warn("plotting DNA has been disabled because you don't have DNAplotlib") + +def plotConstruct(DNA_construct_obj,dna_renderer=None,\ + rna_renderer=None,\ + plot_rnas=False,debug=False,showlabels = None,plot_dna_test=True): + """helper function for making dnaplotlib plots of a DNA_construct object. Plots the + DNAs and the RNAs that come from that DNA, using DNA_construct.explore_txtl""" + #TODO: make the label showing more general + if(showlabels is None): + showlabels = [] + if(PLOT_DNA and plot_dna_test): + if(dna_renderer is None): + dna_renderer=dpl.DNARenderer(scale = 5,linewidth=3) + if(rna_renderer is None): + rna_renderer=dpl.DNARenderer(scale = 5,linewidth=3,linecolor=(1,0,0)) + + design = make_dpl_from_construct(DNA_construct_obj,showlabels=showlabels) + circular=DNA_construct_obj.circular + if(PLOT_DNA and plot_dna_test): + plotDesign(design,circular=circular,title=DNA_construct_obj.get_species()) + if(plot_rnas): + rnas,proteins = DNA_construct_obj.explore_txtl() + for promoter in rnas: + rnadesign = make_dpl_from_construct(rnas[promoter],showlabels=showlabels) + rnacolor = rna_renderer.linecolor + for part in rnadesign: + if("edgecolor" not in part['opts']): + part['opts'].update({'edgecolor':rnacolor}) + plotDesign(rnadesign,renderer=rna_renderer,title=rnas[promoter].get_species()) + else: + print(DNA_construct_obj.show()) diff --git a/biocrnpyler/polymer.py b/biocrnpyler/polymer.py new file mode 100644 index 00000000..6dde41d3 --- /dev/null +++ b/biocrnpyler/polymer.py @@ -0,0 +1,214 @@ +"""The classes OrderedPolymer and OrderedMonomer are datastructures used to represent Polymers and their associatd components. + +These classes are used by Chemical Reaction Network Species as well as certain Components such as DNA_construct. +""" +import copy + + +class OrderedPolymer: + + """a polymer made up of OrderedMonomers that has a specific order""" + def __init__(self,parts): + """parts can be a list of lists containing + [[OrderedMonomer,direction],[OrderedMonomer,direction],...] + alternatively, you can have a regular list, and the direcitons + will end up being None""" + polymer = [] + assert(type(parts)==list or type(parts)==tuple), "OrderedPolymer must be instantiated with a list" + for item in parts: + if(isinstance(item,list)): + part = item[0] + if(len(item)>1): + partdir = item[1] + else: + partdir = None + elif(isinstance(item,OrderedMonomer)): + part = item + partdir = item.direction + else: + raise ValueError("{} is not an OrderedMonomer or a list of the form [OrderedMonomer,direction]".format(str(part))) + + part_copy = copy.copy(part) #OrderedMonomers are always copied when inserted into an OrderedPolymer + polymer += [part_copy] + position = len(polymer)-1 + direction = partdir + part_copy.monomer_insert(self,position,direction) + + self._polymer = tuple(polymer) + + def __hash__(self): + return hash(self._polymer) + def changed(self): + #runs whenever anything changed + pass + def insert(self,position,part,direction=None): + part_copy = copy.copy(part) #OrderedMonomers are always copied when inserted into an OrderedPolymer + + part_copy.monomer_insert(self,position,direction) + for subsequent_part in self._polymer[position:]: + subsequent_part.position += 1 + self._polymer = self._polymer[:position]+(part_copy,)+self._polymer[position:] + self.changed() + + def replace(self,position,part,direction=None): + part_copy = copy.copy(part) #OrderedMonomers are always copied when inserted into an OrderedPolymer + + if(direction is None): + direction = part.direction + self._polymer[position].remove() + part_copy.monomer_insert(self,position,direction) + self._polymer = self._polymer[:position]+(part_copy,)+self._polymer[position+1:] + self.changed() + + + def append(self,part,direction=None): + part_copy = copy.copy(part) #OrderedMonomers are always copied when inserted into an OrderedPolymer + + if(direction is None): + if(hasattr(part,"direction")): + direction = part_copy.direction + else: + direction = None + pos = len(self._polymer) + self.insert(pos,part_copy,direction) + + def __repr__(self): + outstr = "polymer(" + for part in self._polymer: + outstr += str(part)+", direction = "+str(part.direction)+"," + if(outstr[:-1]==","): + outstr = outstr[:-1] + outstr += ")" + return outstr + + def direction_invert(self,dirname): + if(dirname == "forward"): + return "reverse" + elif(dirname == "reverse"): + return "forward" + elif(dirname == 0): + return 1 + elif(dirname == 1): + return 0 + elif(dirname is None): + return None + else: + warn("didn't know how to invert {}".format(str(dirname))) + return dirname + + def __len__(self): + return len(self._polymer) + + def __getitem__(self,ii): + return self._polymer[ii] + + def __setitem__(self,ii,val): + self.replace(ii,val,val.direction) + + def __eq__(self,other): + if(isinstance(other,OrderedPolymer)): + for item1,item2 in zip(self._polymer,other._polymer): + if(item1.direction==item2.direction and item1.position==item2.position and type(item1)==type(item2)): + pass + else: + return False + if(len(self._polymer)==len(other._polymer)): + return True + return False + + def __contains__(self,item): + if(item in self._polymer): + return True + else: + return False + + def delpart(self,position): + part = self._polymer[position] + part.remove() + for subsequent_part in self._polymer[position+1:]: + subsequent_part.position -= 1 + self._polymer = self._polymer[:position] + self._polymer[position+1:] + self.changed() + if(hasattr(self,"name") and hasattr(self,"make_name")): + self.name = self.make_name() + + def reverse(self): + self._polymer = self._polymer[::-1] + for ind,part in enumerate(self._polymer): + part.position = ind + part.direction = self.direction_invert(part.direction) + self.changed() + + +class OrderedMonomer: + """a unit that belongs to an OrderedPolymer. Each unit has a direction, a location, and a link back to its parent""" + def __init__(self,direction=None,position=None,parent=None): + """the default is that the monomer is not part of a polymer""" + + self.parent = None; self.direction = None; self.position = None #Prevents weird testing errors of not having attributes + + #Set properties correctly + self.parent = parent + self.direction = direction + self.position = position + + @property + def parent(self): + return self._parent + @parent.setter + def parent(self, parent): + if parent is None or isinstance(parent, OrderedPolymer): + self._parent = parent + else: + raise ValueError(f"parent must be an OrderedPolymer. Recieved {parent}") + + @property + def direction(self): + return self._direction + @direction.setter + def direction(self, direction): + self._direction = direction + + @property + def position(self): + return self._position + @position.setter + def position(self, position): + if self.parent is None and position is not None: + raise ValueError("{} cannot have a position if it has no parent".format(self)) + elif self.parent is not None and position is None: + raise ValueError("{} is part of a polymer with no position!".format(self)) + else: + self._position = position + + def monomer_insert(self,parent:OrderedPolymer,position:int,direction=None): + if(position is None): + raise ValueError("{} has no position to be inserted at!".format(self)) + if(direction is None): + if(self.direction is not None): + direction = self.direction + if(parent is None): + raise ValueError("{} is trying to be inserted into nothing!".format(self)) + self.parent = parent + self.position = position + self.direction = direction + + def set_dir(self,direction): + self.direction = direction + return(self) + + def remove(self): + self.parent = None + self.direction = None + self.position = None + return(self) + + def __repr__(self): + txt = "OrderedMonomer(direction="+str(self.direction)+",position="+\ + str(self.position)+")" + return txt + def __eq__(self,other): + if(isinstance(other,OrderedMonomer)): + if(self.direction == other.direction and self.position == other.position and self.parent == other.parent): + return True + return False diff --git a/biocrnpyler/propensities.py b/biocrnpyler/propensities.py new file mode 100644 index 00000000..96a43366 --- /dev/null +++ b/biocrnpyler/propensities.py @@ -0,0 +1,576 @@ +# Copyright (c) 2020, Build-A-Cell. All rights reserved. +# See LICENSE file in the project root directory for details. + +import copy +import numbers +from collections import defaultdict +from typing import List, Set, Union + +import libsbml + +from .parameter import ModelParameter, Parameter, ParameterEntry +from .sbmlutil import (_create_global_parameter, _create_local_parameter, + getSpeciesByName) +from .species import Species + + +class Propensity(object): + def __init__(self): + self.propensity_dict = {'species': {}, 'parameters': {}} + self.name = None + + @staticmethod + def is_valid_propensity(propensity_type) -> bool: + """checks whether the given propensity_type is valid propensity. + + It recursively checks all subclasses of Propensity until it finds the + propensity type. Otherwise raise a Type error + + :param propensity_type: Propensity + :returns bool + """ + for propensity in Propensity.get_available_propensities(): + if isinstance(propensity_type, propensity): + return True + return False + + @staticmethod + def _all_subclasses(cls): + """Returns a set of all subclasses of cls (recursively calculated). + + Source: + https://stackoverflow.com/questions/3862310/how-to-find-all-the-subclasses-of-a-class-given-its-name + :param cls: A class in the codebase, for example Propensity + :return: set of all subclasses from cls + """ + return set(cls.__subclasses__()).union( + [s for c in cls.__subclasses__() for s in Propensity._all_subclasses(c)]) + + @staticmethod + def get_available_propensities() -> Set: + return Propensity._all_subclasses(Propensity) + + def _create_sbml_parameter(self, parameter_name, sbml_model, ratelaw, rename_dict = None): + """Creates an sbml parameter for a parameter of the given name. + + if self.propensity_dict["parameter"]["parameter_name"] is a Parameter, + creates a global parameter "Parameter.name_Parameter.part_id_Parameter.mechanism" + where part_id and mechanism can be empty (but _ will always be incldued for uniqueness). + if self.propensity_dict["parameter"]["parameter_name"] is a Number, + creates a local parameter "parameter_name". + rname_dict allows for param.name to be changed to rename_dict[param.name] + """ + p = self.propensity_dict["parameters"][parameter_name] + if isinstance(p, ParameterEntry): + v = p.value + + m = p.parameter_key.mechanism + if m is None: + m = "" + pid = p.parameter_key.part_id + if pid is None: + pid = "" + + if rename_dict is None or p.parameter_name not in rename_dict: + sbml_name = p.parameter_name+"_"+pid+"_"+m + else: + sbml_name = rename_dict[p.parameter_name]+"_"+pid+"_"+m + + return _create_global_parameter(sbml_model, sbml_name, v) + + elif isinstance(p, int) or isinstance(p, float): + v = p + if rename_dict is None or parameter_name not in rename_dict: + sbml_name = parameter_name + else: + sbml_name = rename_dict[parameter_name] + + return _create_local_parameter(ratelaw, sbml_name, v) + + else: + raise TypeError(f"Invalid item in propensity_diction['parameter']: {p}. Only numbers of ParameterEntries accepted.") + + def _check_parameter(self, parameter, allow_None = False, positive = True): + """A helper function used in setters to set parameters and do type checking.""" + if isinstance(parameter, Parameter) and (parameter.value > 0 or not positive): + return parameter + elif isinstance(parameter, numbers.Real) and (parameter > 0 or not positive): + return parameter + elif parameter is None and allow_None: + return parameter + else: + if positive: + raise ValueError(f"Propensity parameters must be Parameters or floats with positive values. Recieved {type(parameter)}.") + else: + raise ValueError(f"Propensity parameters must be Parameters or floats. Recieved {type(parameter)}.") + + def _check_species(self, species, allow_None=False): + """A helper function used in setters to set species and do type checking.""" + if isinstance(species, Species): + return species + elif species is None and allow_None: + return species + else: + raise TypeError(f"Propensity expected a Species: received {type(species)}.") + + def pretty_print(self, show_parameters=True, **kwargs): + txt = self.pretty_print_rate(**kwargs) + if show_parameters: + txt += "\n"+self.pretty_print_parameters(**kwargs) + return txt + + def pretty_print_rate(self, **kwargs): + raise NotImplementedError("class Propensity is meant to be subclassed!") + + def pretty_print_parameters(self, show_keys = True, **kwargs): + txt = "" + for k in self.propensity_dict["parameters"]: + p = self.propensity_dict["parameters"][k] + if isinstance(p, Parameter): + txt += f" {k}={p.value}"#p.pretty_print(**kwargs)+"\n" + if isinstance(p, ModelParameter) and show_keys: + txt+=f"\n found_key=(mech={p.found_key.mechanism}, partid={p.found_key.part_id}, name={p.found_key.name}).\n search_key=(mech={p.search_key.mechanism}, partid={p.search_key.part_id}, name={p.search_key.name})." + txt+="\n" + elif p is not None: + txt += f" {k}={p}\n" + return txt + + @property + def is_reversible(self): + """By default, Propensities are assumed to NOT be reversible.""" + return False + + @property + def k_forward(self): + raise NotImplementedError + + @property + def k_reverse(self): + raise NotImplementedError + + def __eq__(self, other): + if other.__class__ == self.__class__: + return other.propensity_dict == self.propensity_dict + + @property + def species(self) -> List: + """returns the instance variables that are species type.""" + return list(self.propensity_dict['species'].values()) + + def create_kinetic_law(self, reaction, reverse_reaction, stochastic, **kwargs): + raise NotImplementedError("class Propensity is meant to be subclassed!") + + @classmethod + def from_dict(cls, propensity_dict): + merged = propensity_dict['parameters'] + merged.update(propensity_dict['species']) + return cls(**merged) + + def _create_annotation(self, model, propensity_dict_in_sbml, **kwargs): + """Create simulator specific annotations to write to Kinetic laws or any other + part of the SBML model object. + + Annotations are used to take advantage of a simulator specific need/feature. + """ + annotation_string = '' + # Add your own simulator specific annotations here + + # For the bioscrape simulator: + # Check if `for_bioscrape` keyword argument has been passed in **kwargs + if 'for_bioscrape' in kwargs: + for_bioscrape = kwargs.get('for_bioscrape') + else: + for_bioscrape = False + + if for_bioscrape: + annotation_string = self._create_bioscrape_annotation(propensity_dict_in_sbml) + + return annotation_string + + def _create_bioscrape_annotation(self, propensity_dict_in_sbml): + """Propensity Annotations are Used to take advantage of Bioscrape Propensity types + for faster simulation.""" + annotation_dict = defaultdict() + for param_name, param_value in propensity_dict_in_sbml['parameters'].items(): + annotation_dict[param_name] = param_value + + for species_name, species in propensity_dict_in_sbml['species'].items(): + annotation_dict[species_name] = species + + annotation_dict["type"] = self.name + + annotation_string = "" + for k in annotation_dict: + annotation_string += " "+ str(k) + "=" + str(annotation_dict[k]) + annotation_string += "" + + # replace strings to match with bioscrape naming convention + annotation_string = annotation_string.replace('k_forward', 'k', 1) + # Bioscrape doesn't have the concept of a reversible reaction - so for both the reverse and forward cases + # we just make the annotation parameter be called 'k' + annotation_string = annotation_string.replace('k_reverse', 'k', 1) + return annotation_string + + def _translate_propensity_dict_to_sbml(self, model, ratelaw): + # get copy of the propensity_dict and fill with sbml names + propensity_dict_in_sbml = copy.deepcopy(self.propensity_dict) + for param_name in propensity_dict_in_sbml['parameters'].keys(): + parameter_in_sbml =self._create_sbml_parameter(param_name, model, ratelaw) + propensity_dict_in_sbml['parameters'][param_name] = parameter_in_sbml.getId() + + for species_name, species in propensity_dict_in_sbml['species'].items(): + propensity_dict_in_sbml['species'][species_name] = getSpeciesByName(model, str(species)).getId() + + return propensity_dict_in_sbml + + +class GeneralPropensity(Propensity): + def __init__(self, propensity_function: str, propensity_species: List[Species], propensity_parameters: List[ParameterEntry]): + """A class to define a general propensity. + + :param propensity_function: valid propensity formula defined as a string + :param propensity_species: list of species that are part of the propensity_function + :param propensity_parameters: list of parameters that are part of the propensity_function + """ + super(GeneralPropensity, self).__init__() + self.propensity_function = propensity_function + + if len(propensity_species) > 0 and not all(isinstance(s, Species) for s in propensity_species): + raise TypeError('propensity_species must be a list of Species!') + + if len(propensity_parameters) > 0 and not all(isinstance(s, ParameterEntry) for s in propensity_parameters): + raise TypeError('propensity_parameter must be a list of ParameterEntry!') + + for species in propensity_species: + if str(species) not in self.propensity_function: + raise ValueError(f'species: {species} must be part of the formula: {self.propensity_function}') + + self.propensity_dict['species'].update({str(species): species}) + + for parameter in propensity_parameters: + if parameter.parameter_name not in self.propensity_function: + raise ValueError(f'species: {parameter.parameter_name} must be part of the formula: {self.propensity_function}') + + self.propensity_dict['parameters'].update({parameter.parameter_name: parameter.value}) + + self.name = 'general' + + def create_kinetic_law(self, model, sbml_reaction, **kwargs): + """Creates KineticLaw object for SBML using the propensity_function string.""" + ratelaw = sbml_reaction.createKineticLaw() + + propensity_dict_in_sbml = self._translate_propensity_dict_to_sbml(model=model, ratelaw=ratelaw) + + # replacing the species defined in CRN with valid SBML names + for species_in_crn, species_in_sbml in propensity_dict_in_sbml['species'].items(): + self.propensity_function.replace(species_in_crn, species_in_sbml) + + # replacing the parameters defined in CRN with valid SBML names + for parameter_in_crn, parameter_in_sbml in propensity_dict_in_sbml['parameters'].items(): + self.propensity_function.replace(parameter_in_crn, parameter_in_sbml) + + math_ast = libsbml.parseL3Formula(self.propensity_function) + ratelaw.setMath(math_ast) + return ratelaw + + +class MassAction(Propensity): + def __init__(self, k_forward: Union[float, ParameterEntry], k_reverse: Union[float, ParameterEntry] = None): + super(MassAction, self).__init__() + self.k_forward = k_forward + self.k_reverse = k_reverse + self.name = 'massaction' + + @property + def k_forward(self): + if isinstance(self._k_forward, Parameter): + return self._k_forward.value + else: + return self._k_forward + + @k_forward.setter + def k_forward(self, new_k_forward): + self._k_forward = self._check_parameter(new_k_forward) + self.propensity_dict['parameters']['k_forward'] = self._k_forward + + @property + def k_reverse(self): + if isinstance(self._k_reverse, Parameter): + return self._k_reverse.value + else: + return self._k_reverse + + @k_reverse.setter + def k_reverse(self, new_k_reverse): + self._k_reverse = self._check_parameter(new_k_reverse, allow_None=True) + if self._k_reverse is not None: + self.propensity_dict['parameters']['k_reverse'] = self._k_reverse + + @property + def is_reversible(self): + if self.k_reverse is None: + return False + else: + return True + + def pretty_print_rate(self, **kwargs): + crn_reaction = kwargs["reaction"] + reactant_species = {} + for w_species in crn_reaction.inputs: + reactant_species[str(w_species.species)] = w_species + txt = " Kf="+self._get_rate_formula("k_forward", kwargs["stochastic"], reactant_species) + if self.is_reversible: + reactant_species = {} + for w_species in crn_reaction.outputs: + reactant_species[str(w_species.species)] = w_species + txt += "\n Kr="+self._get_rate_formula("k_reverse", kwargs["stochastic"], reactant_species) + return txt + + def create_kinetic_law(self, model, sbml_reaction, stochastic, reverse_reaction=False, **kwargs): + + if 'crn_reaction' in kwargs: + crn_reaction = kwargs['crn_reaction'] + else: + raise ValueError('crn_reaction reference is needed for Massaction kinetics!') + + # create a kinetic law for the sbml_reaction + ratelaw = sbml_reaction.createKineticLaw() + + # translate the internal representation of a propensity to SBML format + propensity_dict_in_sbml = self._translate_propensity_dict_to_sbml(model=model, ratelaw=ratelaw) + + # set up the forward sbml_reaction + if not reverse_reaction: + reactant_species = {} + for w_species in crn_reaction.inputs: + species_id = getSpeciesByName(model, str(w_species.species)).getId() + reactant_species[species_id] = w_species + + param = propensity_dict_in_sbml['parameters']['k_forward'] + # set up a reverse reaction + elif reverse_reaction: + reactant_species = {} + for w_species in crn_reaction.outputs: + species_id = getSpeciesByName(model, str(w_species.species)).getId() + reactant_species[species_id] = w_species + param = propensity_dict_in_sbml['parameters']['k_reverse'] + + rate_formula = self._get_rate_formula(param, stochastic, reactant_species) + # Set the ratelaw to the rateformula + math_ast = libsbml.parseL3Formula(rate_formula) + ratelaw.setMath(math_ast) + annotation_string = self._create_annotation(model, propensity_dict_in_sbml=propensity_dict_in_sbml, **kwargs) + sbml_reaction.appendAnnotation(annotation_string) + return ratelaw + + def _get_rate_formula(self, rate_coeff_name, stochastic, reactant_species) -> str: + + # Create Rate-strings for massaction propensities + ratestring = rate_coeff_name + + for species_id, weighted_species in reactant_species.items(): + if stochastic: + ratestring += '*' + ratestring += f"{species_id}" + ratestring += '*' + ratestring += '*'.join(f" ( {species_id} - {i} )" for i in range(1, weighted_species.stoichiometry)) + else: + if weighted_species.stoichiometry > 1: + ratestring += f" * {species_id}^{weighted_species.stoichiometry}" + else: + ratestring += f" * {species_id}" + return ratestring + +class Hill(Propensity): + def __init__(self, k: float, s1: Species, K: float, n: float, d: Species): + Propensity.__init__(self) + self.k = k + self.s1 = s1 + self.K = K + self.n = n + if d is not None: + self.d = d + + @property + def k(self): + if isinstance(self._k, Parameter): + return self._k.value + else: + return self._k + + @k.setter + def k(self, new_k): + self._k = self._check_parameter(new_k) + self.propensity_dict['parameters']['k'] = self.k + + @property + def K(self): + if isinstance(self._K, Parameter): + return self._K.value + else: + return self._K + + @K.setter + def K(self, new_K): + self._K = self._check_parameter(new_K) + self.propensity_dict['parameters']['K'] = self.K + + @property + def n(self): + if isinstance(self._n, Parameter): + return self._n.value + else: + return self._n + @n.setter + def n(self, new_n): + self._n = self._check_parameter(new_n) + self.propensity_dict['parameters']['n'] = self.n + + @property + def s1(self): + return self._s1 + + @s1.setter + def s1(self, new_s1): + self._s1 = self._check_species(new_s1) + self.propensity_dict['species']['s1'] = self.s1 + + @property + def d(self): + return self._d + + @d.setter + def d(self, new_d): + self._d = self._check_species(new_d, allow_None=True) + self.propensity_dict['species']['d'] = self.d + + def pretty_print_rate(self, show_parameters = True, **kwargs): + raise NotImplementedError("Propensity class Hill is meant to be subclassed: try HillPositive, HillNegative, ProportionalHillPositive, or ProportionalHillNegative.") + + def create_kinetic_law(self, model, sbml_reaction, stochastic, **kwargs): + """This code is reused in all Hill Propensity subclasses.""" + if 'reverse_reaction' in kwargs and kwargs['reverse_reaction'] is True: + raise ValueError('reverse reactions cannot exist for Hill type Propensities!') + + ratelaw = sbml_reaction.createKineticLaw() + + # translate the internal representation of a propensity to SBML format + propensity_dict_in_sbml = self._translate_propensity_dict_to_sbml(model=model, ratelaw=ratelaw) + + rate_formula = self._get_rate_formula(propensity_dict=propensity_dict_in_sbml) + # attach simulator specific annotations to the SBML model, if needed + annotation_string = self._create_annotation(model, propensity_dict_in_sbml, **kwargs) + sbml_reaction.appendAnnotation(annotation_string) + # Set the ratelaw to the rateformula + math_ast = libsbml.parseL3Formula(rate_formula) + ratelaw.setMath(math_ast) + + return ratelaw + + def _get_rate_formula(self, propensity_dict): + raise NotImplementedError('Hill does not have a rate formula! Check out the subclasses.') + + +class HillPositive(Hill): + def __init__(self, k: float, s1: Species, K: float, n: float): + """ Hill positive propensity is a nonlinear propensity with the following formula. + + p(s1; k, K, n) = k*s1^n/(s1^n + K) + + :param k: rate constant (float) + :param s1: species (chemical_reaction_network.species) + :param K: dissociation constant (float) + """ + Hill.__init__(self=self, k=k, s1=s1, K=K, n=n, d=None) + self.name = 'hillpositive' + + def pretty_print_rate(self, show_parameters = True, **kwargs): + return f' Kf = k {self.s1.pretty_print(**kwargs)}^n / ({self.s1.pretty_print(**kwargs)}^n + K)' + + def _get_rate_formula(self, propensity_dict): + k = propensity_dict['parameters']['k'] + n = propensity_dict['parameters']['n'] + K = propensity_dict['parameters']['K'] + s1 = propensity_dict['species']['s1'] + rate_formula = f"{k}*{s1}^{n}/({s1}^{n}+{K})" + return rate_formula + + +class HillNegative(Hill): + def __init__(self, k: float, s1: Species, K: float, n: float): + """ Hill negative propensity is a nonlinear propensity with the following formula. + + p(s1; k, K, n) = k*1/(s1^n + K) + + :param k: rate constant (float) + :param s1: species (chemical_reaction_network.species) + :param K: dissociation constant (float) + :param n: cooperativity (float) + """ + Hill.__init__(self = self, k=k, s1=s1, K=K, n=n, d=None) + self.name = 'hillnegative' + + def pretty_print_rate(self, show_parameters = True, **kwargs): + return f' Kf = k / ({self.s1.pretty_print(**kwargs)}^n + K)' + + def _get_rate_formula(self, propensity_dict): + k = propensity_dict['parameters']['k'] + n = propensity_dict['parameters']['n'] + K = propensity_dict['parameters']['K'] + s1 = propensity_dict['species']['s1'] + rate_formula = f"{k}/({s1}^{n}+{K})" + return rate_formula + + +class ProportionalHillPositive(HillPositive): + def __init__(self, k: float, s1:Species, K: float, n: float, d:Species): + """ proportional Hill positive propensity with the following formula. + + p(s1, d; k, K, n) = k*d*s1^n/(s1^n + K) + + :param k: rate constant (float) + :param s1: species (chemical_reaction_network.species) + :param K: dissociation constant (float) + :param n: cooperativity (float) + :param d: species (chemical_reaction_network.species) + """ + Hill.__init__(self=self, k=k, s1=s1, K=K, n=n, d=d) + self.name = 'proportionalhillpositive' + + def pretty_print_rate(self, show_parameters = True, **kwargs): + return f' Kf = k {self.d.pretty_print(**kwargs)} {self.s1.pretty_print(**kwargs)}^n/({self.s1.pretty_print(**kwargs)}^n + K)' + + def _get_rate_formula(self, propensity_dict): + k = propensity_dict['parameters']['k'] + n = propensity_dict['parameters']['n'] + K = propensity_dict['parameters']['K'] + s1 = propensity_dict['species']['s1'] + d = propensity_dict['species']['d'] + return f"{k}*{d}*{s1}^{n}/({s1}^{n}+{K})" + + +class ProportionalHillNegative(HillNegative): + def __init__(self, k: float, s1: Species, K: float, n: float, d: Species): + """ proportional Hill negative propensity with the following formula. + + p(s1, d; k, K, n) = k*d/(s1^n + K) + + :param k: rate constant (float) + :param s1: species (chemical_reaction_network.species) + :param K: dissociation constant (float) + :param n: cooperativity (float) + :param d: species (chemical_reaction_network.species) + """ + Hill.__init__(self=self, k=k, s1=s1, K=K, n=n, d=d) + self.name = 'proportionalhillnegative' + + def pretty_print_rate(self, show_parameters=True, **kwargs): + return f' Kf = k {self.d.pretty_print(**kwargs)} /({self.s1.pretty_print(**kwargs)}^{self.n} + K)' + + def _get_rate_formula(self, propensity_dict): + k = propensity_dict['parameters']['k'] + n = propensity_dict['parameters']['n'] + K = propensity_dict['parameters']['K'] + s1 = propensity_dict['species']['s1'] + d = propensity_dict['species']['d'] + return f"{k}*{d}/({s1}^{n}+{K})" diff --git a/biocrnpyler/reaction.py b/biocrnpyler/reaction.py new file mode 100644 index 00000000..0d2fbd10 --- /dev/null +++ b/biocrnpyler/reaction.py @@ -0,0 +1,265 @@ +# Copyright (c) 2020, Build-A-Cell. All rights reserved. +# See LICENSE file in the project root directory for details. + + +from .propensities import (HillNegative, HillPositive, MassAction, Propensity, + ProportionalHillNegative, ProportionalHillPositive) + +from.species import * +import copy +import itertools +from typing import List, Union +from warnings import warn + +from .utils import remove_bindloc + + +class Reaction(object): + """An abstract representation of a chemical reaction in a CRN. + + A reaction has the form: + .. math:: + \sum_i n_i I_i --> \sum_i m_i O_i @ rate = k + where n_i is the count of the ith input, I_i, and m_i is the count of the + ith output, O_i. + If the reaction is reversible, the reverse reaction is also included: + .. math:: + \sum_i m_i O_i --> \sum_i n_i I_i @ rate = k_rev + """ + def __init__(self, *args, **kwargs): + # This is to have backward compatibility for now, should be removed! + if args: + kwargs['inputs'] = args[0] + kwargs['outputs'] = args[1] + if 'k' in kwargs or 'propensity_params' in kwargs: + self.old_interface(**kwargs) + else: + self.new_interface(**kwargs) + + def old_interface(self,inputs, outputs, k = 0, input_coefs = None, + output_coefs = None, k_rev = 0, propensity_type = "massaction", + rate_formula = None, propensity_params = None): + warnings.warn('This way to initialize a reaction object is deprecated, please refactor your code!', DeprecationWarning) + + if propensity_type == 'hillpositive': + propensity_type = HillPositive(**propensity_params) + elif propensity_type == 'hillnegative': + propensity_type = HillNegative(**propensity_params) + elif propensity_type == 'proportionalhillpositive': + propensity_type = ProportionalHillPositive(**propensity_params) + elif propensity_type == 'proportionalhillnegative': + propensity_type = ProportionalHillNegative(**propensity_params) + elif k_rev: + propensity_type = MassAction(k_forward=k, k_reverse=k_rev) + else: + propensity_type = MassAction(k_forward=k) + + if rate_formula is not None: + NotImplementedError('General propensity is not supported this way!') + + if input_coefs: + reactants = [WeightedSpecies(species=s, stoichiometry=v) for s,v in zip(inputs, input_coefs, strict=True)] + else: + reactants = [WeightedSpecies(species=s) for s in inputs] + + if output_coefs: + products = [WeightedSpecies(species=s, stoichiometry=v) for s,v in zip(outputs, output_coefs, strict=True)] + else: + products = [WeightedSpecies(species=s) for s in outputs] + + self.new_interface(inputs=reactants, outputs=products, propensity_type=propensity_type) + + def new_interface(self, inputs: Union[List[Species], List[WeightedSpecies]], + outputs: Union[List[Species], List[WeightedSpecies]], + propensity_type: Propensity): + + if len(inputs) == 0 and len(outputs) == 0: + warn("Reaction Inputs and Outputs both contain 0 Species.") + + self.inputs = remove_bindloc(Species.flatten_list(inputs)) + self.outputs = remove_bindloc(Species.flatten_list(outputs)) + self.propensity_type = propensity_type + + @property + def propensity_type(self) -> Propensity: + return self._propensity_type + + @propensity_type.setter + def propensity_type(self, new_propensity_type: Propensity): + """Replace the propensity type associated with the reaction object. + + :param new_propensity_type: Valid propensity type + """ + if not Propensity.is_valid_propensity(new_propensity_type): + raise ValueError(f'unknown propensity type: {new_propensity_type} ' + f'({type(new_propensity_type)})!') + + self._propensity_type = new_propensity_type + + @classmethod + def from_massaction(cls, inputs: Union[List[Species], List[WeightedSpecies]], + outputs: Union[List[Species], List[WeightedSpecies]], + k_forward: float, k_reverse: float = None): + """Initialize a Reaction object with mass action kinetics. + + :param inputs: + :param outputs: + :param k_forward: + :param k_reverse: + :return: Reaction object + """ + mak = MassAction(k_forward=k_forward, k_reverse=k_reverse) + + return cls(inputs=inputs, outputs=outputs, propensity_type=mak) + + @property + def is_reversible(self) -> bool: + return self.propensity_type.is_reversible + + @property + def inputs(self) -> List[WeightedSpecies]: + return self._input_complexes + + @inputs.setter + def inputs(self, new_input_complexes: List[WeightedSpecies]): + self._input_complexes = Reaction._check_and_convert_complex_list(complexes=new_input_complexes) + + @property + def outputs(self) -> List[WeightedSpecies]: + return self._output_complexes + + @outputs.setter + def outputs(self, new_output_complexes: List[WeightedSpecies]): + self._output_complexes = Reaction._check_and_convert_complex_list(complexes=new_output_complexes) + + @staticmethod + def _check_and_convert_complex_list(complexes: Union[List[Species], List[WeightedSpecies]]) -> List[WeightedSpecies]: + if all([isinstance(one_complex, Species) for one_complex in complexes]): + # we wrap each Species object to WeightedSpecies + complexes = [WeightedSpecies(species=species) for species in complexes] + else: + if not all([isinstance(one_complex, WeightedSpecies) for one_complex in complexes]): + raise TypeError(f'inputs must be list of Species or list of ChemicalComplexes! Recieved {complexes}') + + # filter out duplicates and adjust stoichiometry + out_list = [] + # Create a dictionary of unique species and their stoichiometry count + stoichiometry_count = WeightedSpecies._count_weighted_species(complexes) + for one_complex, stoichiometry in stoichiometry_count.items(): + new_complex = WeightedSpecies(species=one_complex.species, stoichiometry=stoichiometry) + out_list.append(new_complex) + + return out_list + + #@property + #def k_forward(self): + # return self.propensity_type.k_forward + + #@property + #def k_reverse(self): + # return self.propensity_type.k_reverse + + def replace_species(self, species: Species, new_species: Species): + """Replaces species with new_species in the reaction. + + :param species: species to be replaced + :param new_species: the new species the old species is replaced with + :return: a new Reaction instance + """ + if not isinstance(species, Species) or not isinstance(new_species, Species): + raise ValueError('both species and new_species argument must be an instance of Species!') + + new_inputs = [] + for s in self.inputs: + new_s = s.replace_species(species, new_species) + new_inputs.append(new_s) + + new_outputs = [] + for s in self.outputs: + new_s = s.replace_species(species, new_species) + new_outputs.append(new_s) + + # get a shallow copy of the parameters and species, so we can replace some of them + propensity_type_dict = copy.copy(self.propensity_type.propensity_dict) + for key, prop_species in propensity_type_dict['species'].items(): + propensity_type_dict['species'][key] = prop_species.replace_species(species, new_species) + + new_propensity_type = self.propensity_type.from_dict(propensity_type_dict) + print(new_propensity_type.propensity_dict) + + new_r = Reaction(inputs=new_inputs, outputs=new_outputs, propensity_type=new_propensity_type) + return new_r + + def __repr__(self): + """Helper function to print the text of a rate function""" + return self.pretty_print(show_rates=False, show_material=True, show_attributes=True, show_parameters = False) + + def pretty_print(self, show_rates=True, show_material=True, show_attributes=True, show_parameters = True, **kwargs): + + kwargs['show_rates'] = show_rates + kwargs['show_material'] = show_material + kwargs['show_attributes'] = show_attributes + + txt = '+'.join([s.pretty_print(**kwargs) for s in self.inputs]) + + if self.is_reversible: + txt += " <--> " + else: + txt += " --> " + + txt += '+'.join([s.pretty_print(**kwargs) for s in self.outputs]) + if show_rates: + + #These kwargs are essential for massaction propensities + kwargs["reaction"] = self + if "stochastic" not in kwargs: + kwargs["stochastic"] = False + + txt += "\n"+f'{self.propensity_type.pretty_print(**kwargs)}' + + return txt + + def __eq__(self, other): + """Two reactions are equivalent if they have the same inputs, outputs, + and propensity.""" + if not isinstance(other, Reaction): + raise TypeError(f'Only reactions can be compared with reaction! We got {type(other)}.') + + if len(self.inputs) != len(other.inputs) or len(self.outputs) != len(other.outputs): + return False + + return (set(self.inputs), set(self.outputs), self.propensity_type) == (set(other.inputs), set(other.outputs), other.propensity_type) + + def __contains__(self, item: Species): + """It checks whether a species is part of a reaction. + + it checks the input and output lists as well as the propensity type for the species + + :param item: a Species instance + :return: bool + :exception NotImplementedError for non-Species objects + """ + if isinstance(item, Species): + if item in self.inputs \ + or item in self.outputs \ + or item in self.propensity_type.species: + return True + else: + raise NotImplementedError + return False + + @property + def species(self) -> List[Species]: + """returns a list of species in the reactions collected from the inputs + and outputs and the propensity (e.g. Hill kinetics has species in it). + + :return: list of species in the reactions + """ + in_part = [] + for s in self.inputs: + in_part.extend(Species.flatten_list(s.species)) + out_part = [] + for s in self.outputs: + out_part.extend(Species.flatten_list(s.species)) + + return list(itertools.chain(in_part, out_part, self.propensity_type.species)) diff --git a/biocrnpyler/sbmlutil.py b/biocrnpyler/sbmlutil.py index 6d7ad42e..d5992956 100644 --- a/biocrnpyler/sbmlutil.py +++ b/biocrnpyler/sbmlutil.py @@ -4,26 +4,40 @@ # Copyright (c) 2018, Build-A-Cell. All rights reserved. # See LICENSE file in the project root directory for details. -import libsbml -import numpy as np +import logging +from random import randint +from typing import List from warnings import warn +import libsbml + # Reaction ID number (global) reaction_id = 0 +logger = logging.getLogger(__name__) + -# Create an SBML model def create_sbml_model(compartment_id="default", time_units='second', extent_units='mole', substance_units='mole', - length_units='metre', area_units='square_metre', volume_units='litre', volume = 1e-6, model_id = None): - ''' - Creates an SBML Level 3 Version 2 model with some fixed standard settings. - Returns the SBMLDocument and the Model object as a tuple. + length_units='metre', area_units='square_metre', volume_units='litre', volume=1e-6, model_id=None, **kwargs): + """Creates an SBML Level 3 Version 2 model with some fixed standard settings. + Refer to python-libsbml for more information on SBML API. - ''' + + :param compartment_id: + :param time_units: + :param extent_units: + :param substance_units: + :param length_units: + :param area_units: + :param volume_units: + :param volume: + :param model_id: + :return: the SBMLDocument and the Model object as a tuple + """ document = libsbml.SBMLDocument(3, 2) model = document.createModel() if model_id is None: - model_id = 'biocrnpyler_'+str(np.random.randint(1e6)) + model_id = 'biocrnpyler_'+str(randint(1,1e6)) model.setId(model_id) model.setName(model_id) # Define units for area (not used, but keeps COPASI from complaining) @@ -50,8 +64,6 @@ def create_sbml_model(compartment_id="default", time_units='second', extent_unit compartment.setConstant(True) # keep compartment size constant compartment.setSpatialDimensions(3) # 3 dimensional compartment compartment.setVolume(volume) # 1 microliter - - # Returning document is enough. document.getModel() gives the model, and model.getCompartment(0) gives the compartment. return document, model @@ -66,9 +78,33 @@ def species_sbml_id(species, document=None): return species_id -# Helper function to add a species to the model -# species must be chemical_reaction_network.species objects -def add_species(model, compartment, species, debug=False, initial_concentration=None): +def add_all_species(model, species: List, compartment=None, **kwargs): + """adds a list of Species to the SBML model. + + :param model: valid SBML model + :param species: list of species to be added to the SBML model + :param compartment: compartment id, if empty species go to the first compartment + :return: None + """ + + if compartment is None: + compartment = model.getCompartment(0) + + for s in species: + add_species(model=model, compartment=compartment, + species=s, initial_concentration=s.initial_concentration) + + +def add_species(model, compartment, species, initial_concentration=None, **kwargs): + """Helper function to add a species to the sbml model. + + :param model: + :param compartment: a compartment in the SBML model + :param species: must be chemical_reaction_network.species objects + :param initial_concentration: initial concentration of the species in the SBML model + :return: None + """ + model = model # Get the model where we will store results # Construct the species name @@ -77,7 +113,7 @@ def add_species(model, compartment, species, debug=False, initial_concentration= # Construct the species ID species_id = species_sbml_id(species, model.getSBMLDocument()) - if debug: print("Adding species", species_name, species_id) + logger.debug(f'Adding species: {species_name}, id: {species_id}') sbml_species = model.createSpecies() sbml_species.setName(species_name) sbml_species.setId(species_id) @@ -121,199 +157,115 @@ def find_parameter(mixture, id): return model.getParameter(id) # ! TODO: add error checking -# Helper function to add a reaction to a model -# reaction must be a chemical_reaction_network.reaction object -#propensity params is a dictionary of the parameters for non-massaction propensities. -def add_reaction(model, inputs, input_coefs, outputs, output_coefs, - reaction_id, k = None, kname = None, - stochastic = False, propensity_type = "massaction", - propensity_params = None, propensity_annotation = True): - - # Create the reaction - reaction = model.createReaction() - reaction.setReversible(False) - # reaction.setFast(False) # Deprecated in SBML - all_ids = getAllIds(model.getSBMLDocument().getListOfAllElements()) - trans = SetIdFromNames(all_ids) - reaction.setId(trans.getValidIdForName(reaction_id)) - reaction.setName(reaction.getId()) - ratestring = "" #Stores the string representing the rate function - annotation_dict = {"type":propensity_type} - # Create a kinetic law for the reaction - ratelaw = reaction.createKineticLaw() - #Create Local Propensity Parameters - if propensity_type=="massaction": - if kname is None: - kname = "k" - - param = ratelaw.createParameter() - param.setId(kname) - param.setConstant(True) - if k is not None and propensity_params is None: - param.setValue(k) - annotation_dict["k"] = k - elif 'k' in propensity_params: - param.setValue(propensity_params['k']) - annotation_dict["k"] = propensity_params['k'] - elif k is not None and "k" in propensity_params and propensity_params['k'] != k: - raise ValueError("Keyword k and propensity_params['k'] have different values. Only one of these arguments is needed or they must match.") - else: - raise ValueError("Massaction propensities require a rate k which can be passed into add_reaction as a keyword k= or inside the propensity_params keyword dictionary.") - - ratestring = kname - - #Hill Function Propensities - elif propensity_type in ["hillpositive", "hillnegative", "proportionalhillpositive", "proportionalhillnegative"]: - if not ("k" in propensity_params and "K" in propensity_params and "n" in propensity_params): - raise ValueError(propensity_type+" requires the following keys in the propensity_params dictionary: " - "'k':rate constant (float)" - "'n':cooperativity(float), " - "and 'K':dissociationc constant (float).") - param_k = ratelaw.createParameter() - param_k.setId("k") - param_k.setConstant(True) - param_k.setValue(propensity_params['k']) - - param_n = ratelaw.createParameter() - param_n.setId("n") - param_n.setConstant(True) - param_n.setValue(propensity_params['n']) - - param_K = ratelaw.createParameter() - param_K.setId("K") - param_K.setConstant(True) - param_K.setValue(propensity_params['K']) - - ratestring = "k" - - annotation_dict["k"] = propensity_params['k'] - annotation_dict["K"] = propensity_params['K'] - annotation_dict["n"] = propensity_params['n'] - - - elif propensity_type == "general": - raise NotImplementedError("SBML writing of general propensities not implemented") - else: - raise ValueError(propensity_type+" is not a supported propensity_type") - - # Create the reactants - for i in range(len(inputs)): - species = str(inputs[i]).replace("'", "") - stoichiometry = input_coefs[i] - # species_id = species_sbml_id(species, model.getSBMLDocument()) - - # What to do when there are multiple species with same name? - species_id = getSpeciesByName(model,species).getId() - reactant = reaction.createReactant() - reactant.setSpecies(species_id) # ! TODO: add error checking - reactant.setConstant(False) - if stoichiometry is None or stoichiometry is np.nan: - stoichiometry = 1.0 - reactant.setStoichiometry(stoichiometry) - #Create Rate-strings for massaction propensities - if propensity_type=="massaction" and stochastic: - for i in range(stoichiometry): - if i > 0: - ratestring += f" * ( {species_id} - {i} )" - else: - ratestring += f" * {species_id}" - - elif propensity_type=="massaction" and not stochastic: - if stoichiometry > 1: - ratestring += f" * {species_id}^{stoichiometry}" - else: - ratestring += f" * {species_id}" - - #Create ratestring for non-massaction propensities - if propensity_type == "hillpositive": - if not ("s1" in propensity_params): - raise ValueError("hillpositive propensities, p(s1; k, K, n) " - "= k*s1^n/(s1^n + K), require the following key in the propensity_params dictionary:" - "'s1':species (chemical_reaction_network.species)") - - s = str(propensity_params['s1']).replace("'", "") - s_species_id = getSpeciesByName(model,s).getId() - - ratestring+=f"*{s_species_id}^n/({s_species_id}^n+K)" +def add_all_reactions(model, reactions: List, stochastic=False, **kwargs): + """adds a list of reactions to the SBML model. - annotation_dict["s1"] = s_species_id + :param model: an sbml model created by create_sbml_model() + :param reactions: list of Reactions + :param stochastic: binary flag for stochastic models + :return: None + """ - elif propensity_type == "hillnegative": - if not ("s1" in propensity_params): - raise ValueError("hillnegative propensities, " - "p(s1; k, K, n) = k*1/(s1^n + K), require the following key in the propensity_params dictionary:" - "'s1':species (chemical_reaction_network.species)") - s = str(propensity_params['s1']).replace("'", "") - s_species_id = getSpeciesByName(model,s).getId() + for rxn_count, r in enumerate(reactions): + rxn_id = f'r{rxn_count}' + add_reaction(model=model, crn_reaction=r, reaction_id=rxn_id, stochastic=stochastic, **kwargs) - ratestring+=f"/({s_species_id}^n+K)" + #Reversible reactions are always seperated into two seperate reactions + if r.is_reversible: + rxn_id = f'r{rxn_count}rev' + add_reaction(model=model, crn_reaction=r, reaction_id=rxn_id, stochastic=stochastic, reverse_reaction = True, **kwargs) - annotation_dict["s1"] = s_species_id - elif propensity_type == "proportionalhillpositive": - if not ("s1" in propensity_params and "d" in propensity_params): - raise ValueError("proportionalhillpositive propensities, " - "p(s1, d; k, K, n) = k*d*s1^n/(s1^n + K), require the following key in the propensity_params dictionary:" - "'s1':species (chemical_reaction_network.species)" - "'d':species (chemical_reaction_network.species), ") +def add_reaction(model, crn_reaction, reaction_id: str, stochastic: bool=False, reverse_reaction: bool=False, **kwargs): + """adds a sbml_reaction to an sbml model. - s = str(propensity_params['s1']).replace("'", "") - d = str(propensity_params['d']).replace("'", "") - s_species_id = getSpeciesByName(model,s).getId() - d_species_id = getSpeciesByName(model,d).getId() + :param model: an sbml model created by create_sbml_model() + :param crn_reaction: must be a chemical_reaction_network.reaction object + :param reaction_id: unique id of the reaction + :param stochastic: stochastic model flag + :param reverse_reaction: + :return: SBML Reaction object + """ - ratestring+=f"*{d_species_id}*{s_species_id}^n/({s_species_id}^n + K)" - - annotation_dict["s1"] = s_species_id - annotation_dict["d"] = d_species_id - - elif propensity_type == "proportionalhillnegative": - if not ("s1" in propensity_params and "d" in propensity_params): - raise ValueError("proportionalhillnegative propensities, " - "p(s1, d; k, K, n) = k*d/(s1^n + K), require the following key in the propensity_params dictionary:" - "'s1':species (chemical_reaction_network.species)" - "'d':species (chemical_reaction_network.species), ") - - s = str(propensity_params['s1']).replace("'", "") - d = str(propensity_params['d']).replace("'", "") - s_species_id = getSpeciesByName(model,s).getId() - d_species_id = getSpeciesByName(model,d).getId() + # Create the sbml_reaction in SBML + sbml_reaction = model.createReaction() + all_ids = getAllIds(model.getSBMLDocument().getListOfAllElements()) + trans = SetIdFromNames(all_ids) + sbml_reaction.setId(trans.getValidIdForName(reaction_id)) + sbml_reaction.setName(sbml_reaction.getId()) + #all reactions are set to be non-reversible in BioCRNpyler because this is correct in deterministic and stochastic simulation. + sbml_reaction.setReversible(False) + + # Create the reactants and products for the sbml_reaction + if not reverse_reaction: + _create_reactants(reactant_list=crn_reaction.inputs, sbml_reaction=sbml_reaction, model=model) + _create_products(product_list=crn_reaction.outputs, sbml_reaction=sbml_reaction, model=model) + else: + _create_reactants(reactant_list=crn_reaction.outputs, sbml_reaction=sbml_reaction, model=model) + _create_products(product_list=crn_reaction.inputs, sbml_reaction=sbml_reaction, model=model) - ratestring+=f"*{d_species_id}/({s_species_id}^n+K)" + # Create the kinetic law and corresponding local propensity parameters + crn_reaction.propensity_type.create_kinetic_law(model=model, + sbml_reaction=sbml_reaction, + stochastic=stochastic, + crn_reaction=crn_reaction, + reverse_reaction=reverse_reaction, + **kwargs) + # Create SpeciesModifierReference in SBML for species that are referred by the + # KineticLaw but not in reactants or products + _create_modifiers(crn_reaction = crn_reaction, sbml_reaction = sbml_reaction, model = model) - annotation_dict["s1"] = s_species_id - annotation_dict["d"] = d_species_id + return sbml_reaction - elif propensity_type == "general": - raise NotImplementedError("General propensity SBML Writing Not Implemented") +def _create_reactants(reactant_list, sbml_reaction, model): + for input in reactant_list: + # What to do when there are multiple species with same name? + species_id = getSpeciesByName(model, str(input.species)).getId() + reactant = sbml_reaction.createReactant() + reactant.setSpecies(species_id) + reactant.setConstant(False) + reactant.setStoichiometry(input.stoichiometry) - # Create the products - for i in range(len(outputs)): - species = str(outputs[i]).replace("'", "") - stoichiometry = output_coefs[i] - product = reaction.createProduct() - species_id = getSpeciesByName(model, species).getId() +def _create_products(product_list, sbml_reaction, model): + for output in product_list: + species_id = getSpeciesByName(model, str(output.species)).getId() + product = sbml_reaction.createProduct() product.setSpecies(species_id) - if stoichiometry is None or stoichiometry is np.nan: - stoichiometry = 1.0 - product.setStoichiometry(stoichiometry) + product.setStoichiometry(output.stoichiometry) product.setConstant(False) - # Set the ratelaw to the ratestring - math_ast = libsbml.parseL3Formula(ratestring) - ratelaw.setMath(math_ast) - if propensity_annotation: - annotation_string = "" - for k in annotation_dict: - annotation_string += " "+k + "=" + str(annotation_dict[k]) - annotation_string += "" - reaction.appendAnnotation(annotation_string) - - return reaction +def _create_modifiers(crn_reaction, sbml_reaction, model): + reactants_list = [i.species.name for i in crn_reaction.inputs] + products_list = [i.species.name for i in crn_reaction.outputs] + modifier_species = [i.name for i in crn_reaction.propensity_type.propensity_dict['species'].values()] + for modifier_id in modifier_species: + modifier_id = str(modifier_id) + if modifier_id not in reactants_list and modifier_id not in products_list: + modifier = sbml_reaction.createModifier() + modifier.setSpecies(modifier_id) + +#Creates a local parameter SBML kinetic rate law +def _create_local_parameter(ratelaw, name, value, constant = True): + param = ratelaw.createParameter() + param.setId(name) + param.setConstant(constant) + param.setValue(value) + + return param + +#Creates a global parameter SBML model +def _create_global_parameter(model, name, value, constant = True): + if model.getParameter(name) is None: + param = model.createParameter() + param.setId(name) + param.setConstant(constant) + param.setValue(value) + else: + param = model.getParameter(name) + return param -# !/usr/bin/env python ## ## @file setIdFromNames.py ## @brief Utility program, renaming all SIds that also has @@ -359,11 +311,6 @@ def add_reaction(model, inputs, input_coefs, outputs, output_coefs, ## ## -import sys -import os.path -import time - - # This class implements an identifier transformer, that means it can be used # to rename all sbase elements. class SetIdFromNames(libsbml.IdentifierTransformer): @@ -418,7 +365,8 @@ def nameToSbmlId(self, name): if (Id[len(Id) - 1] != '_'): return Id - return Id[:-1] + return Id + #return Id[:-1] #this code was removing underscores at the end of ComplexSpecies needed for imbedded ComplexSpecies. # # Generates the id out of the name, and ensures it is unique. @@ -458,7 +406,7 @@ def getSpeciesByName(model, name, compartment=''): to look for the species. ''' if type(name) is not str: - raise ValueError('"name" must be a string.') + raise ValueError(f'"name" must be a string. Recievied {name} type={type(name)}.') species_found = [] for species in model.getListOfSpecies(): if species.getName() == name: @@ -479,3 +427,92 @@ def getSpeciesByName(model, name, compartment=''): else: warn('Multiple species with name ' + name + ' found. Returning a list') return species_found + + +## Validate SBML + + +class validateSBML(object): + ''' + libSBML class to validate the generated SBML models + ## @brief Validates SBMLDocument + ## @author Akiya Jouraku (translated from libSBML C++ examples) + ## @author Ben Bornstein + ## @author Michael Hucka + ''' + def __init__(self, ucheck): + self.reader = libsbml.SBMLReader() + self.ucheck = ucheck + + def validate(self, sbml_document, print_results = False): + """sbml_document: libSBML SBMLDocument object. + + print_results: Print toggle for validation warnings. + """ + sbmlDoc = sbml_document + errors = sbmlDoc.getNumErrors() + if print_results: + print("Validating SBML model with ID: {0}...".format(sbmlDoc.getModel().getId())) + seriousErrors = False + + numReadErr = 0 + numReadWarn = 0 + errMsgRead = "" + + if errors > 0: + for i in range(errors): + severity = sbmlDoc.getError(i).getSeverity() + if (severity == libsbml.LIBSBML_SEV_ERROR) or (severity == libsbml.LIBSBML_SEV_FATAL): + seriousErrors = True + numReadErr += 1 + else: + numReadWarn += 1 + errMsgRead = sbmlDoc.getErrorLog().toString() + + # If serious errors are encountered while reading an SBML document, it + # does not make sense to go on and do full consistency checking because + # the model may be nonsense in the first place. + + numCCErr = 0 + numCCWarn = 0 + errMsgCC = "" + + if seriousErrors: + errMsgRead += "Further consistency checking and validation aborted." + else: + sbmlDoc.setConsistencyChecks(libsbml.LIBSBML_CAT_UNITS_CONSISTENCY, self.ucheck) + failures = sbmlDoc.checkConsistency() + if failures > 0: + isinvalid = False + for i in range(failures): + severity = sbmlDoc.getError(i).getSeverity() + if (severity == libsbml.LIBSBML_SEV_ERROR) or (severity == libsbml.LIBSBML_SEV_FATAL): + numCCErr += 1 + isinvalid = True + else: + numCCWarn += 1 + if isinvalid: + errMsgCC = sbmlDoc.getErrorLog().toString() + if errMsgRead or errMsgCC: + if print_results: + print() + print( "===== validation error/warning messages =====\n") + if errMsgRead : + if print_results: + print( errMsgRead) + if errMsgCC : + if print_results: + print( "*** consistency check ***\n") + print( errMsgCC) + if not (numReadErr + numCCErr): + print('Successful!') + return numReadErr + numCCErr + + +def validate_sbml(sbml_document, enable_unit_check = False, print_results = True): + """Validates the generated SBML model by using libSBML SBML validation code.""" + validator = validateSBML(enable_unit_check) + validation_result = validator.validate(sbml_document, print_results = print_results) + if validation_result > 0: + warn('SBML model invalid. Run with print_results = False to hide print statements') + return validation_result diff --git a/biocrnpyler/species.py b/biocrnpyler/species.py new file mode 100644 index 00000000..0dd701d1 --- /dev/null +++ b/biocrnpyler/species.py @@ -0,0 +1,834 @@ +# Copyright (c) 2020, Build-A-Cell. All rights reserved. +# See LICENSE file in the project root directory for details. + +import copy +import warnings +from typing import List, Union + +from .polymer import OrderedMonomer, OrderedPolymer + + +class Species(OrderedMonomer): + + """ A formal species object for a CRN + A Species must have a name. They may also have a material_type (such as DNA, + RNA, Protein), and a list of attributes. + """ + + def __init__(self, name: str, material_type="", attributes: Union[List,None] = None, + initial_concentration=0, **keywords): + OrderedMonomer.__init__(self,**keywords) + + self.name = name + self.material_type = material_type + self.initial_concentration = initial_concentration + self._attributes = [] #Set this to avoid errors + self.attributes = attributes + + @property + def attributes(self): + if(not hasattr(self,"_attributes")): + self._attributes = [] + return self._attributes + + @attributes.setter + def attributes(self, attributes): + if(not hasattr(self,"_attributes")): + self._attributes = [] + if attributes is not None: + if not isinstance(attributes,list): + attributes = list(attributes) + for attribute in attributes: + self.add_attribute(attribute) + elif attributes is None: + self._attributes = [] + def remove_attribute(self,attribute:str): + """ + removes an attribute from a Species + """ + if(not hasattr(self,"_attributes")): + self._attributes = [] + return + assert isinstance(attribute, str) and attribute is not None and attribute.isalnum(), "Attribute: %s must be an alpha-numeric string" % attribute + if attribute in self.attributes: + new_attrib = [] + for attrib in self._attributes: + if(attrib==attribute): + pass + else: + new_attrib += [attrib] + self._attributes = new_attrib + + def add_attribute(self, attribute: str): + """ + Adds attributes to a Species + """ + if(not hasattr(self,"_attributes")): + self._attributes = [] + assert isinstance(attribute, str) and attribute is not None and attribute.isalnum(), "Attribute: %s must be an alpha-numeric string" % attribute + if attribute not in self.attributes: + self._attributes.append(attribute) + + + @property + def name(self): + if self._name is None: + return "" + else: + return self._name + + @name.setter + def name(self, name: str): + if name is None: + raise TypeError("Name must be a string.") + else: + self._name = self._check_name(name) + + + #Use OrderedMonomers getter + direction = property(OrderedMonomer.direction.__get__) + + @direction.setter + def direction(self, direction): + """ + This is inheritted from OrderedMonomer. + A species with direction will use it as an attribute as well. + This is overwritten to make direction an attribute + """ + + self._direction = direction + if direction is not None: + self.add_attribute(direction) + + def remove(self): + """ + Added functionality to remove direction as an attribute. + """ + if self.direction is not None: + self.attributes.remove(self.direction) + OrderedMonomer.remove(self) #call the OrderedMonomer function + + #Note: this is used because properties can't be overwritten without setters being overwritten in subclasses. + def _check_name(self, name): + """ + Check that the string contains only underscores and alpha-numeric characters or is None. + Additionally cannot end in "_" or contain double "__" + """ + if name is None: + return name + elif isinstance(name, str): + no_underscore_string = name.replace("_", "") + if no_underscore_string.isalnum() and "__" not in name and name[len(name)-1] != "_": + return name + else: + raise ValueError(f"name attribute {name} must consist of letters, numbers, or underscores and cannot contained double underscores or end in an underscore.") + else: + raise TypeError("Name must be a string.") + + @property + def material_type(self): + return self._material_type + + @material_type.setter + def material_type(self, material_type: str): + """ + Check that the string contains is alpha-numeric characters or "_" and that the first character is a letter. + If the name is a starts with a number, there must be a material type. + """ + if material_type in [None, ""] and self.name[0].isnumeric(): + raise ValueError(f"species name: {self.name} contains a number as the first character and therefore requires a material_type.") + elif material_type == None: + self._material_type = None + elif (material_type.replace("_", "").isalnum() and material_type.replace("_", "")[0].isalpha() and "__" not in material_type and material_type[len(material_type)-1] != "_") or material_type == "": + self._material_type = material_type + else: + raise ValueError(f"material_type {material_type} must be alpha-numeric and start with a letter.") + + def __repr__(self): + txt = "" + if self.material_type not in ["", None]: + txt = self.material_type + "_" + + txt += self.name + + if len(self.attributes) > 0 and self.attributes != []: + for i in self.attributes: + if i is not None: + txt += "_" + str(i) + txt.replace("'", "") + return txt + + def replace_species(self, species, new_species): + if not isinstance(species, Species): + raise ValueError('species argument must be an instance of Species!') + + if not isinstance(new_species, Species): + raise ValueError('species argument must be an instance of Species!') + + if self == species: + return new_species + else: + return self + + def get_species(self, **kwargs): + """ + Used in some recursive calls where ComplexSpecies returns a list and Species will return just themselves (in a list) + """ + return [self] + + + def pretty_print(self, show_material = True, show_attributes = True, show_initial_condition = False, **kwargs): + """ + #A more powerful printing function. + Useful for understanding CRNs but does not return string identifiers. + show_material toggles whether species.material is printed. + show_attributes toggles whether species.attributes is printed + """ + txt = "" + if self.material_type not in ["", None] and show_material: + txt = self.material_type + "[" + + txt += self.name + + if len(self.attributes) > 0 and self.attributes != [] and show_attributes: + txt += "(" + for i in self.attributes: + if i is not None: + txt += str(i)+", " + txt = txt[:-2]+")" + + txt.replace("'", "") + if(hasattr(self,"direction") and self.direction is not None): + txt += "-"+self.direction + if self.material_type not in ["", None] and show_material: + txt += "]" + + if show_initial_condition: + txt+=f" init_conc = {self.initial_concentration}" + + return txt + + + def __eq__(self, other): + """ + Overrides the default implementation + Two species are equivalent if they have the same name, type, and attributes + :param other: Species instance + :return: boolean + """ + + if isinstance(other, Species) \ + and self.material_type == other.material_type \ + and self.name == other.name \ + and set(self.attributes) == set(other.attributes)\ + and self.parent == other.parent\ + and self.position == other.position: + return True + else: + return False + def __gt__(self,Species2): + return self.name > Species2.name + def __lt__(self,Species2): + return self.name < Species2.name + + def __hash__(self): + return str.__hash__(repr(self)) + def __contains__(self,item): + return item in self.get_species() + @staticmethod + def flatten_list(in_list) -> List: + """Helper function to flatten lists + """ + out_list = [] + if not isinstance(in_list,list): + out_list.append(in_list) + else: + for element in in_list: + if isinstance(element, list): + out_list += Species.flatten_list(element) + else: + out_list += [element] + return out_list + + +class WeightedSpecies: + def __init__(self, species: Species, stoichiometry:int=1): + """Container object for a all types of species and its stoichiometry + """ + self.species: Species = species + self.stoichiometry: int = stoichiometry + + @property + def stoichiometry(self): + return self._stoichiometry + + @stoichiometry.setter + def stoichiometry(self, new_stoichiometry): + if new_stoichiometry <= 0: + raise ValueError(f'Stoichiometry must be positive integer! We got {new_stoichiometry}!') + self._stoichiometry = int(new_stoichiometry) + + def pretty_print(self, **kwargs): + return f'{self.stoichiometry if self.stoichiometry > 1 else ""}{self.species.pretty_print(**kwargs)}' + + def replace_species(self, *args, **kwargs): + return self.species.replace_species(*args, **kwargs) + + @staticmethod + def _count_weighted_species(weighted_species: List): + """Helper function merge the same species in a list with different stoichiometry + + >>> s1 = Species(name='a') + >>> ws1 = WeightedSpecies(species=s1, stoichiometry=2) + >>> ws2 = WeightedSpecies(species=s1, stoichiometry=5) + >>> ws_list = [ws1, ws2] + >>> freq_dict = WeightedSpecies._count_weighted_species(ws_list) + >>> len(freq_dict) + 1 + + :param weighted_species: list of weighted_species + :return: unique list of weighted_species, i.e. set(weighted_species) + """ + # convert to set doesn't work because we need only species equality + unique_species = [] + for w_species in weighted_species: + if not any(w_species.species == u_s.species for u_s in unique_species): + unique_species.append(w_species) + + freq_dict = dict(zip(unique_species, [0]*len(unique_species))) + for w_species in weighted_species: + for key in freq_dict: + if key.species == w_species.species: + freq_dict[key] += w_species.stoichiometry + + return freq_dict + + def __eq__(self, other): + if other.__class__ is self.__class__: + return (other.species, other.stoichiometry) == (self.species, self.stoichiometry) + return False + + def __hash__(self): + return hash(self.species)+hash(self.stoichiometry) + + +class Complex: + """ + !!!ComplexSpecies and OrderedComplexSpecies should ALWAYS be created with the Complex function!!! + + Complex is not a class that gets instantiated - it creates ComplexSpecies and OrderedComplexSpecies. + The Logic encoded in the __new__ function is used to insert these classes into the binding sites of + OrderedPolymerSpecies. + + arguments: + species: a list of species to put into ComplexSpecies or OrderedComplexSpecies + + keywords: + ordered: whether to produce an OrderedComplexSpecies (default = False) + """ + def __new__(cls,*args,**keywords): + species = [] + #below is extracting the "species" keywords from the args + keywarg = None + if("species" in keywords): + keywarg = True + species = keywords["species"] + del keywords["species"] + elif(len(args)>=1): + keywarg = False + species = args[0] + args = args[1:] + + #Check whether ot make a ComplexSpecies or OrderedComplexSpecies + if "ordered" in keywords: + ordered = keywords["ordered"] + del keywords["ordered"] + else: + ordered = False + + valent_complex = None #valent_complex is an OrderedPolymer Species + bindloc = None #bindloc is the location a Species is bound to valent_complex + other_species = [] #Other species in the Complex + + #Below cycle through species and see if one has a parent. If it does, that means the species is + #in an OrderedPolymerSpecies and the Complex should be formed around it. + for specie in species: + if(hasattr(specie,"parent") and (specie.parent is not None)): + if(valent_complex is None): + #It is very important to deepcopy here because the underlying OrderedPolymerSpecies will be modified. + valent_complex = copy.deepcopy(specie.parent) + bindloc = specie.position + else: + #If valent_complex has already been found - it means there are two OrderedPolymer + #or two Species in the same OrderedPolymer. This kind of binding has not been implemented. + raise NotImplementedError("binding together two OrderedPolymerSpecies or two species in the same OrderedPolymerSpecies!") + else: + other_species += [specie] + + if len(other_species) == 0: + raise ValueError("Trying to create a Complex from a single species!") + + #If no OrderedPolymerSpecies is found, just call the regular constructor. + if(valent_complex is None): + if ordered: + #this creates an OrderedComplexSpecies + #pass in all the args and keywords appropriately + keywords["called_from_complex"] = True + return OrderedComplexSpecies(species,*args,**keywords) + else: + #this creates a ComplexSpecies + #pass in all the args and keywords appropriately + keywords["called_from_complex"] = True + return ComplexSpecies(species,*args,**keywords) + + #This means the Complex is being formed inside an OrderedPolymerSpecies + else: + #this is the species around which the complex is being formed + #basically we want to "unclone" this and then "clone the new ComplexSpecies we will have created" + prev_species = copy.deepcopy(valent_complex[bindloc]) + prev_species.remove() + prev_direction = copy.deepcopy(valent_complex[bindloc].direction) + + #combine what was in the OrderedMonomer with the new stuff in the list + new_species = other_species+[prev_species] + + #Create an OrderedcomplexSepcies + if ordered: + keywords["called_from_complex"] = True + new_complex = OrderedComplexSpecies(new_species,*args,**keywords) + #Create a ComplexSpecies + else: + keywords["called_from_complex"] = True + new_complex = ComplexSpecies(new_species,*args,**keywords) + #now we replace the monomer inside the parent polymer + valent_complex.replace(bindloc,new_complex,prev_direction) + valent_complex.material_type = OrderedPolymerSpecies.default_material #this is saying that we are now a complex + return valent_complex[bindloc] + +class ComplexSpecies(Species): + """ + !!!ComplexSpecies and OrderedComplexSpecies should ALWAYS be created with the Complex function!!! + + A special kind of species which is formed as a complex of two or more species. + Used for attribute inheritance and storing groups of bounds Species. + Note taht in a ComplexSpecies, the order of the species list does not matter. + This means that ComplexSpecies([s1, s2]) = ComplexSpecies([s2, s1]). + This is good for modelling order-indpendent binding complexes. + For a case where species order matters (e.g. polymers) use OrderedComplexSpecies + """ + def __init__(self, species: List[Union[Species,str]], name: Union[str,None] = None, material_type = "complex", attributes = None, initial_concentration = 0, **keywords): + + #A little check to enforce use of Complex() to create ComplexSpecies + if "called_from_complex" not in keywords or not keywords["called_from_complex"]: + warnings.warn("ComplexSpecies should be created using the Complex([List of Species]) function, not directly!") + + #Set species because it is used for default naming + if len(Species.flatten_list(species)) <= 1: + raise ValueError("chemical_reaction_network.complex requires 2 " + "or more species in its constructor.") + self.species = species + + #call super class + Species.__init__(self, name = name, material_type = material_type, attributes = attributes, initial_concentration = initial_concentration) + + def __repr__(self): + """ + ComplexSpecies add an additional "_" onto the end of their string representation + This ensures that some edge cases are differentiated. + """ + txt = Species.__repr__(self) + txt += "_" + return txt + @property + def name(self): + if self._name is None: + name = "" + for s in self.species_set: + count = self.species.count(s) + name+=str(s)+"_" + if count > 1: + name+=f"{count}x_" + name = name[:-1] + return name + else: + return self._name + + @name.setter + def name(self, name: str): + self._name = self._check_name(name) + + def __contains__(self,item): + """ + Returns a list of species inside the ComplexSpecies + """ + if not isinstance(item, Species): + raise ValueError("Operator 'in' requires chemical_reaction_network.Species (or a subclass). Received: "+str(item)) + if item in self.species: + #this is the base case + return True + else: + #this is the recursive part. We want to check all + #internal complexes for the thing we're looking for + for content in self.species: + if isinstance(content,ComplexSpecies) : + if item in content: + return True + #if we got here then we've failed to find it + return False + + @property + def species_set(self): + species_set = list(set(self.species)) + list.sort(species_set, key = lambda s:repr(s)) + return species_set + @property + def species(self): + return self._species + @species.setter + def species(self, species): + if not isinstance(species, list): + raise TypeError(f"species must be a list: recieved {species}.") + species = Species.flatten_list(species) + if not all(isinstance(s, Species) for s in species): + raise TypeError(f"recieved a non-species as a member of the list species: {species}.") + else: + list.sort(species, key = lambda s:repr(s)) + self._species = species + + def replace_species(self, species: Species, new_species: Species): + """ + Replaces species with new_species in the entire Complex Species. Acts recursively on nested ComplexSpecies + Does not act in place - returns a new ComplexSpecies. + """ + if not isinstance(species, Species): + raise ValueError('species argument must be an instance of Species!') + + if not isinstance(new_species, Species): + raise ValueError('species argument must be an instance of Species!') + + new_species_list = [] + for s in self.species: + new_s = s.replace_species(species, new_species) + new_species_list.append(new_s) + + new_name = None + if self._name is not None: + new_name = self.name + + return Complex(species = new_species_list, name = new_name, material_type = self.material_type, attributes = self.attributes) + + + def get_species(self, recursive = False): + """ + Returns all species in the ComplexSpecies. If recursive = True, returns species inside internal ComplexSpecies recursively as well. + """ + if not recursive: + species = [self] + else: + species = [self] + for s in self.species: + species += s.get_species(recursive = True) + + return species + + + def pretty_print(self, show_material = True, show_attributes = True, show_initial_condition = False, **kwargs): + """ + A more powerful printing function. + Useful for understanding CRNs but does not return string identifiers. + show_material toggles whether species.material is printed. + show_attributes toggles whether species.attributes is printed + """ + + txt = "" + if self.material_type not in ["", None] and show_material: + txt += self.material_type + txt += "[" + for s in self.species_set: + count = self.species.count(s) + if count > 1: + txt += f"{count}x_" + txt += s.pretty_print(show_material = show_material, show_attributes = False)+":" + txt = txt[:-1] + + if len(self.attributes) > 0 and self.attributes != [] and show_attributes: + txt += "(" + for i in self.attributes: + if i is not None: + txt += str(i)+", " + txt = txt[:-2]+")" + + txt.replace("'", "") + if(hasattr(self,"direction") and self.direction is not None): + txt += "-"+self.direction + txt += "]" + + if show_initial_condition: + txt+=f" init_conc = {self.initial_concentration}" + + return txt + + +class Multimer(ComplexSpecies): + """A subclass of ComplexSpecies for Complexes made entirely of the same kind of species, + eg dimers, tetramers, etc. + """ + def __init__(self, species, multiplicity, name = None, material_type = "complex", attributes = None, initial_concentration = 0, **keywords): + + if "called_from_complex" not in keywords or not keywords["called_from_complex"]: + warnings.warn("OrderedComplexSpecies should be created from the Complex([List of Species], ordered = True) function, not directly!") + + if isinstance(species, str): + species = [Species(name = species)] + elif not isinstance(species, Species): + raise ValueError("Multimer must be defined by a Species (or subclasses thereof) and a multiplicity (int).") + else: + species = [species] + + ComplexSpecies.__init__(self, species = species*multiplicity, name = name, material_type = material_type, attributes = attributes, initial_concentration = initial_concentration, **keywords) + +class OrderedComplexSpecies(ComplexSpecies): + """ + !!!ComplexSpecies and OrderedComplexSpecies should ALWAYS be created with the Complex function!!! + + A special kind of species which is formed as a complex of two or more species. + In OrderedComplexSpecies the order in which the complex subspecies are is defined + denote different species, eg [s1, s2, s3] != [s1, s3, s2]. + Used for attribute inheritance and storing groups of bounds Species. + """ + + def __init__(self, species, name = None, material_type = "ordered_complex", attributes = None, initial_concentration = 0, **keywords): + #Set species because it is used for default naming + if len(Species.flatten_list(species)) <= 1: + raise ValueError("chemical_reaction_network.complex requires 2 " + "or more species in its constructor.") + self.species = species + + #Call the Species superclass constructor + Species.__init__(self, name = name, material_type = material_type, attributes = attributes, initial_concentration = initial_concentration) + + + + @property + def name(self): + if self._name is None: + name = "" + for s in self.species: + if isinstance(s, str): + s = Species(name = s) + if s.material_type not in [""]: + name+=f"{s.material_type}_{s.name}_" + else: + name+=f"{s.name}_" + name = name[:-1] + return name + else: + return self._name + + @name.setter + def name(self, name: str): + self._name = self._check_name(name) + + @property + def species(self): + return self._species + + @species.setter + def species(self, species): + if not isinstance(species, list): + raise TypeError(f"species must be a list: recieved {species}.") + species = Species.flatten_list(species) + if not all(isinstance(s, Species) for s in species): + raise TypeError(f"recieved a non-species as a member of the list species: {species}.") + else: + self._species = species + + def replace_species(self, species: Species, new_species: Species): + """ + Replaces species with new_species in the entire Complex Species. Acts recursively on nested ComplexSpecies + """ + if not isinstance(species, Species): + raise ValueError('species argument must be an instance of Species!') + + if not isinstance(new_species, Species): + raise ValueError('species argument must be an instance of Species!') + + new_species_list = [] + for s in self.species: + new_s = s.replace_species(species, new_species) + new_species_list.append(new_s) + + new_name = None + if self._name is not None: + new_name = self.name + + return Complex(species = new_species_list, name = new_name, material_type = self.material_type, attributes = self.attributes, ordered = True) + + def pretty_print(self, show_material = True, show_attributes = True, show_initial_condition = False, **kwargs): + """ + A more powerful printing function. + Useful for understanding CRNs but does not return string identifiers. + show_material toggles whether species.material is printed. + show_attributes toggles whether species.attributes is printed + """ + + txt = "" + if self.material_type not in ["", None] and show_material: + txt += self.material_type + + txt += "[" + + for s in self.species: + txt += s.pretty_print(show_material = show_material, show_attributes = False)+":" + txt = txt[:-1] + + if len(self.attributes) > 0 and self.attributes != [] and show_attributes: + txt += "(" + for i in self.attributes: + if i is not None: + txt += str(i)+", " + txt = txt[:-2]+")" + + txt.replace("'", "") + txt += "]" + + if show_initial_condition: + txt+=f" init_conc = {self.initial_concentration}" + + return txt + +class OrderedPolymerSpecies(OrderedComplexSpecies,OrderedPolymer): + """ + A class to represent OrderedPolymers which can also participate in chemical reactions. + OrderedPolymerSpecies is made up of Species (which are also OrderedMonomers). + + The Species inside an OrderedPolymerSpecies are meant to model multiple binding sites and/or + functional regions. ComplexSpecies can be formed inside an OrderedPolymer by passing + the internal Species at a specific location. + + When used as an input to a reaction, OrderedPolymerSpecies can be passed + or one if its internal Species (eg a Species with Species.parent = OrderedPolymerSpecies) + can also be used to produce the same reaction. This allows flexibility in the arguments to + different Mechanisms. Sometimes, it is convenient to pass in the OrderedPolymerSpecies, + sometimes it is convenient to pass an internal Species. Both will work from the point of view + of any Mechanism. + """ + default_material="ordered_polymer" + def __init__(self,species, name=None, base_species = None, material_type = default_material, \ + attributes = None, initial_concentration = 0,circular = False): + + self.material_type = material_type + self.parent=None + self.position=None + self.direction=None + + self.initial_concentration = initial_concentration + self.circular = circular + + if attributes is None: + self.attributes = [] + else: + self.attributes = attributes + + self._name = OrderedComplexSpecies._check_name(self,name) + + self.material_type = material_type + #self.species = [] + monomers = [] + for specie in species: + if isinstance(specie,Species) and isinstance(specie, OrderedMonomer): + monomers += [specie] + elif (isinstance(specie, tuple) or isinstance(specie, list)) and (isinstance(specie[0],Species) and isinstance(specie[0], OrderedMonomer)): + monomers += [specie] + elif isinstance(specie, OrderedPolymer): + raise NotImplementedError(f"OrderedPolymer cannot be used as a Monomer at this time.") + else: + raise ValueError("{} should be a Species or list [Species, 'direction']".format(specie)) + #only species are acceptable + + OrderedPolymer.__init__(self, monomers) + self.material_type = material_type + + if(base_species is None): + self.base_species = Species(self.name, material_type = material_type) + elif(isinstance(base_species,Species)): + self.base_species = base_species + else: + raise TypeError("base_species is of type "+type(base_species)+" which is not acceptable. Use Species or str") + + @property + def species_set(self): + return set(self._polymer) + @property + def species(self): + return self._polymer + + def get_species_list(self): + return self._polymer + + @property + def circular(self): + if("circular" in self.attributes): + return True + else: + return False + + @circular.setter + def circular(self,value:bool): + if(value): + self.add_attribute("circular") + else: + self.remove_attribute("circular") + + def set_species_list(self,spec_tuple:tuple): + OrderedPolymer.__init__(self,spec_tuple) + + @property + def name(self): + if self._name is None: + name = "" + else: + name = self._name + outlst = [] + + for monomer in self._polymer: + assert(isinstance(monomer,Species)) + pname = monomer.name + pdir = None + if(hasattr(monomer,"direction")): + pdir =monomer.direction + if(pdir is not None): + outlst += [pname+"_"+str(pdir)[0]] + else: + outlst += [pname] + if(self.circular): + outlst += ["o"] + name = '_'.join(outlst) + return name + + def __hash__(self): + ophash = OrderedPolymer.__hash__(self) + ophash += hash(self.circular)+hash(self.base_species)+hash(self.name)+hash(self.material_type) + return ophash + + + def replace(self,position,part,direction=None): + #TODO only change the name if the part we are replacing is actually different + mydir = direction + if((mydir is None) and (part.direction is not None)): + mydir = part.direction + if(part == self._polymer[position] and self._polymer[position].direction == mydir): + #in this case we are replacing a part with the same thing, so do nothing + #but it could be true that the reference changes? That shouldnt be + pass + else: + OrderedPolymer.replace(self,position=position,part=part,direction=mydir) + #print("replacing") + #print([a.data for a in self._polymer]) + #self.name = self.make_name() + + def __contains__(self,item): + for part in self.species: + if((part==item ) or (item == part.data) or (item in part)): + return True + return False diff --git a/biocrnpyler/utils.py b/biocrnpyler/utils.py new file mode 100644 index 00000000..84cf2bec --- /dev/null +++ b/biocrnpyler/utils.py @@ -0,0 +1,41 @@ +################################################################ +# DNA_construct: a higher level for construct compilation +# Author: Andrey Shur +# Latest update: 7/31/2020 +# Copyright (c) 2020, Build-A-Cell. All rights reserved. +# See LICENSE file in the project root directory for details. +# +################################################################ +import itertools as it + +from .species import WeightedSpecies + + +def all_comb(input_list): + out_list = [] + for i in range(1,len(input_list)+1): + out_list += it.combinations(input_list,i) + return out_list + + +def rev_dir(dir): + reversedict = {"forward":"reverse","reverse":"forward"} + return reversedict[dir] + + +def remove_bindloc(spec_list): + """go through every species on a list and remove any "bindloc" attributes""" + #spec_list2 = copy.copy(spec_list) + out_sp_list = [] + for specie in spec_list: + #go through the species and remove the "bindloc" attribute + #I don't care about the binding now that I am done generating species + if(type(specie)==WeightedSpecies): + spec2 = specie.species + if(hasattr(spec2,"parent") and (spec2.parent is not None)): + specie.species = spec2.parent + if(hasattr(specie,"parent") and (specie.parent is not None)): + out_sp_list += [specie.parent] + else: + out_sp_list+= [specie] + return out_sp_list diff --git a/conf.py b/conf.py new file mode 100644 index 00000000..7a60c718 --- /dev/null +++ b/conf.py @@ -0,0 +1,62 @@ +# Configuration file for the Sphinx documentation builder. +# +# This file only contains a selection of the most common options. For a full +# list see the documentation: +# https://www.sphinx-doc.org/en/master/usage/configuration.html + +# -- Path setup -------------------------------------------------------------- + +# If extensions (or modules to document with autodoc) are in another directory, +# add these directories to sys.path here. If the directory is relative to the +# documentation root, use os.path.abspath to make it absolute, like shown here. +# +# import os +# import sys +# sys.path.insert(0, os.path.abspath('.')) + + +# -- Project information ----------------------------------------------------- + +project = 'BioCRNpyler' +copyright = '2020, William Poole, Ayush Pandey, Andrey Shur, Zoltan Tuza, Richard M. Murray' +author = 'William Poole, Ayush Pandey, Andrey Shur, Zoltan Tuza, Richard M. Murray' + +# The full version, including alpha/beta/rc tags +release = '1.0' + + +# -- General configuration --------------------------------------------------- + +# Add any Sphinx extension module names here, as strings. They can be +# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom +# ones. +extensions = [ +] + +# Add any paths that contain templates here, relative to this directory. +templates_path = ['_templates'] + +# The language for content autogenerated by Sphinx. Refer to documentation +# for a list of supported languages. +# +# This is also used if you do content translation via gettext catalogs. +# Usually you set "language" from the command line for these cases. +language = 'Python' + +# List of patterns, relative to source directory, that match files and +# directories to ignore when looking for source files. +# This pattern also affects html_static_path and html_extra_path. +exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store'] + + +# -- Options for HTML output ------------------------------------------------- + +# The theme to use for HTML and HTML Help pages. See the documentation for +# a list of builtin themes. +# +html_theme = 'alabaster' + +# Add any paths that contain custom static files (such as style sheets) here, +# relative to this directory. They are copied after the builtin static files, +# so a file named "default.css" will overwrite the builtin "default.css". +html_static_path = ['_static'] \ No newline at end of file diff --git a/docs/CONTRIBUTING.md b/docs/CONTRIBUTING.md new file mode 100644 index 00000000..4dd75e34 --- /dev/null +++ b/docs/CONTRIBUTING.md @@ -0,0 +1,39 @@ +# Contributing to BioCRNpyler + +Thank you for your interest in contributing to BioCRNpyler! + +In this file you will find detailed instructions on how you can start making contributions to the package. BioCRNpyler is hosted on the [BuildACell](https://github.com/buildacell) organization page on GitHub. For more information on getting started with the package, refer to the README file on the [home page](https://github.com/BuildACell/biocrnpyler) and the tutorial style example jupyter notebooks under the [examples](https://github.com/BuildACell/BioCRNPyler/tree/master/examples) directory. For a detailed software documentation refer to the BioCRNpyler documentation [here](https://readthedocs.org/projects/biocrnpyler/). + +## How to contribute? +To get started, set up your BioCRNpyler fork - detailed instructions for doing so can be found [here](https://github.com/BuildACell/BioCRNPyler/wiki/How-to-sync-your-BioCRNPyler-fork). All contributions to BioCRNpyler should be made as a Github pull request to the **dev** branch [here](https://github.com/BuildACell/BioCRNPyler/tree/dev). + +### Reporting Bugs/Asking for help + +Use the Github issues page on BioCRNpyler to report a bug or to ask for help with running BioCRNpyler. The Github issues have labels that you can use so that the issues can be filtered easily: + +* If you are unsure where to begin contributing to BioCRNpyler, you can start by looking through the issues with the label `beginner` or `help-wanted`. A beginner issue usually requires only changing a few lines of code to fix something or add a new enhancement. The `help-wanted` issues are slightly more involved and may require an understanding of the BioCRNpyler modules. + +* If you have a particular feature idea in mind, feel free to suggest that as an `enhancement` or a `feature-request` tagged issue. If you would like to get in touch with the developers working on the package to discuss your contribution ideas, you can also join our Slack channel (details at the end of this page). + +### Pull Requests + +All pull requests should be made to the `dev` branch of BioCRNpyler. To maintain code readability and validity, we encourage you to document your pull requests using the following ways: +* Add a detailed comment when creating the pull request that summarizes the changes, features and/or bugs fixed. +* All new functions and classes must have [docstrings](https://www.python.org/dev/peps/pep-0257/) so that automated documentation can be generated. +* If possible, we encourage you to add test functions in the Tests directory that validate the code contributions. +* If your pull request is adding a new feature to the package, we also highly recommend a jupyter notebook example that goes along with that feature that discusses the use case. + +## Styleguides + +* Following the PEP8 guideline, limit the first line to 72 characters or less +* Reference issues and pull requests in your pull request comment +* + +## Have any questions? + +If you have questions or would like to connect to the BioCRNpyler team on a regular basis, you can join our Slack channel. BioCRNpyler is a channel under the Synthetic Biology Modeling and Analysis Tools (SBTools) slack team. + +* [Join the SBTools Slack](https://join.slack.com/t/sbtools/shared_invite/zt-g82qjmvm-GAsNFLjyXGPlRBapqGDgFg) + * Use the `#biocrnpyler` channel for general questions or discussion about BioCRNpyler + * Use the `#general` channel for general questions about SBTools + * There are many other channels available for other synthetic biology modeling and analysis tools, check the channel list diff --git a/docs/conf.py b/docs/conf.py index 5d8f85ea..8c0ea6f7 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -20,13 +20,13 @@ # -- Project information ----------------------------------------------------- project = 'BioCRNPyler' -copyright = '2019, William Poole, Ayush Pandey, Zoltan Tuza' -author = 'William Poole, Ayush Pandey, Zoltan Tuza' +copyright = '2020, William Poole, Ayush Pandey, Andrey Shur, Zoltan Tuza, Richard M. Murray' +author = 'William Poole, Ayush Pandey, Andrey Shur, Zoltan Tuza, Richard M. Murray' # The short X.Y version -version = '' +version = '1.0' # The full version, including alpha/beta/rc tags -release = '' +release = '1.0.0' # -- General configuration --------------------------------------------------- @@ -129,7 +129,7 @@ # author, documentclass [howto, manual, or own class]). latex_documents = [ (master_doc, 'BioCRNPyler.tex', 'BioCRNPyler Documentation', - 'William Poole, Ayush Pandey, Zoltan Tuza', 'manual'), + 'William Poole, Ayush Pandey, Andrey Shur, Zoltan Tuza, Richard M. Murray', 'manual'), ] diff --git a/examples/1. Building CRNs Directly.ipynb b/examples/1. Building CRNs Directly.ipynb index 95eec031..5cd6e03b 100644 --- a/examples/1. Building CRNs Directly.ipynb +++ b/examples/1. Building CRNs Directly.ipynb @@ -25,16 +25,12 @@ }, { "cell_type": "code", - "execution_count": 2, + "execution_count": 1, "metadata": {}, "outputs": [], "source": [ "#Import everything from biocrnpyler\n", - "from biocrnpyler import *\n", - "\n", - "#Used for simulating and plotting\n", - "import numpy as np\n", - "import pylab as plt" + "from biocrnpyler import *" ] }, { @@ -74,7 +70,7 @@ }, { "cell_type": "code", - "execution_count": 3, + "execution_count": 2, "metadata": {}, "outputs": [ { @@ -84,23 +80,28 @@ "Species can be printed to show their string representation: m1_A_attribute m1_B m2_B D\n", "\n", "Reactions can be printed as well:\n", - " m1_A_attribute --> 2 m1_B massaction: k_f(m1_A_attribute)=3.0*m1_A_attribute \n", - " m1_B --> m2_B + D massaction: k_f(m1_B)=1.4*m1_B\n", + " m1[A(attribute)] --> 2m1[B] \n", + " m1[B] --> m2[B]+D\n", "\n", "Directly printing a CRN shows the string representation of the species used in BioCRNpyler:\n", "Species = m1_A_attribute, m1_B, m2_B, D\n", "Reactions = [\n", - "\tm1_A_attribute --> 2 m1_B massaction: k_f(m1_A_attribute)=3.0*m1_A_attribute\n", - "\tm1_B --> m2_B + D massaction: k_f(m1_B)=1.4*m1_B\n", + "\tm1[A(attribute)] --> 2m1[B]\n", + "\tm1[B] --> m2[B]+D\n", "]\n", "\n", "CRN.pretty_print(...) is a function that prints a more customizable version of the CRN, but doesn't show the proper string representation of species.\n", "Species (4) = {0. m1[A(attribute)], 1. m1[B], 2. m2[B], 3. D}\n", + "\n", "Reactions (2) = [\n", - "0. m1[A(attribute)] --> 2 m1[B] \n", - " massaction: k_f(m1[A(attribute)])=3.0*m1[A(attribute)]\n", - "1. m1[B] --> m2[B] + D \n", - " massaction: k_f(m1[B])=1.4*m1[B]\n", + "0. m1[A(attribute)] --> 2m1[B]\n", + " Kf=k_forward * m1_A_attribute\n", + " k_forward=3.0\n", + "\n", + "1. m1[B] --> m2[B]+D\n", + " Kf=k_forward * m1_B\n", + " k_forward=1.4\n", + "\n", "]\n" ] } @@ -120,8 +121,8 @@ "k2rev = 0.15\n", "\n", "#Reaciton Objects\n", - "R1 = Reaction([A], [B, B], k1)\n", - "R2 = Reaction([B], [C, D], k2)\n", + "R1 = Reaction.from_massaction([A], [B, B], k_forward = k1)\n", + "R2 = Reaction.from_massaction([B], [C, D], k_forward = k2)\n", "\n", "print(\"\\nReactions can be printed as well:\\n\", R1,\"\\n\", R2)\n", "\n", @@ -155,12 +156,12 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": 3, "metadata": {}, "outputs": [ { "data": { - "image/png": "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\n", + "image/png": "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\n", "text/plain": [ "
" ] @@ -185,19 +186,18 @@ " #Initial conditions can be set with a dictionary:\n", " x0 = {str(A):120}\n", " timepoints = np.linspace(0, 1, 100)#Timepoints to simulate over\n", + " \n", + " #This function can also take a filename keyword to save the file at the same time\n", + " R = CRN.simulate_with_bioscrape_via_sbml(timepoints = timepoints, initial_condition_dict = x0)\n", "\n", - " R = CRN.simulate_with_bioscrape(timepoints = timepoints, initial_condition_dict = x0)\n", - " #Can also simulate and save at the same time\n", - " #R, M = CRN.simulate_with_bioscrape_via_sbml(timepoints = timepoints, initial_condition_dict = x0, file_name = \"build_crns_directly.xml\")\n", - "\n", - " #Check to ensure simulation worked\n", + " #Check to ensure simulation worked\n", " #Results are in a Pandas Dictionary and can be accessed via string-names of species\n", " plt.plot(R['time'], R[str(A)], label = \"A\")\n", " plt.plot(R['time'], R[str(B)], label = \"B\")\n", " plt.plot(R['time'], R[str(C)], \"--\", label = \"C\")\n", " plt.plot(R['time'], R[str(D)],\":\", label = \"D\")\n", " plt.legend()\n", - "\n", + " \n", "except ModuleNotFoundError:\n", " print(\"Plotting Modules not installed.\")" ] @@ -208,45 +208,63 @@ "source": [ "## ComplexSpecies and OrderedComplexSpecies\n", "\n", - "When Species bind together to form complexes, it is recommended to use the ComplexSpecies, Multimer, or OrderedComplexSpecies subclasses which contain information about the species inside of them. ComplexSpecies treats its internal species as an unordered multiset. Multimer contains $n$ compies of a sinlge Species. OrderedComplexSpecies treats its internal species as an ordered list.\n", + "When Species bind together to form complexes, it is recommended to use the Complex function:\n", + "\n", + " Complex([list of species], ordered = True/False) \n", + "\n", + "This function returns the classes ComplexSpecies or OrderedComplexSpecies subclasses which contain information about the species inside of them. ComplexSpecies treats its internal species as an unordered multiset. OrderedComplexSpecies treats its internal species as an ordered list. It is recommended to always use the function Complex to create these types of Species for compatability reasons discussed in the OrderedPolymerSpecies example notebook.\n", "\n", "_Note: These objects do not automatically generate binding reactions. To do that, use the Component wrappers ChemicalComplex and OrderedChemicalComplex._" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 4, "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "For ComplexSpecies, the order of the elements does not matter:\n", + "C1=ComplexSpecies([A, B, B2, A])= complex_m1_A_2x_m1_B_m2_B\n", + "C2=ComplexSpecies([B, A, B2, A])= complex_m1_A_2x_m1_B_m2_B\n", + "C1==C2 ==> True\n", + "\n", + "For OrderedComplexSpecies, the Order Does Matter:\n", + "C3=OrderedComplexSpecies([A, B, B2, A])= ordered_complex_m1_A_m1_B_m2_B_m1_A\n", + "C4=OrderedComplexSpecies([B, A, B2, A])= ordered_complex_m1_B_m1_A_m2_B_m1_A\n", + "C3==C4 ==> False\n", + "\n", + "ComplexSpecies (and the OrderedComplexSpecies and Multimers) are Species and can be used in reactions:\n", + "Reaction.from_massaction([A, B, B2, A], [C1], k_forward = 10)=\n", + "2m1[A]+m1[B]+m2[B] --> complex[2x_m1[A]:m1[B]:m2[B]]\n" + ] + } + ], "source": [ "A = Species(\"A\", material_type = \"m1\")\n", "B = Species(\"B\", material_type = \"m1\")\n", "B2 = Species(\"B\", material_type = \"m2\")\n", "\n", "print(\"\\nFor ComplexSpecies, the order of the elements does not matter:\")\n", - "C1 = ComplexSpecies([A, B, B2, A])\n", - "C2 = ComplexSpecies([B, A, B2, A])\n", + "C1 = Complex([A, B, B2, A])\n", + "C2 = Complex([B, A, B2, A])\n", "print(\"C1=ComplexSpecies([A, B, B2, A])=\", C1)\n", "print(\"C2=ComplexSpecies([B, A, B2, A])=\", C2)\n", "print(\"C1==C2 ==>\", C1==C2)\n", "\n", - "print(\"\\nMultimers are the same as ComplexSpecies:\")\n", - "M1 = ComplexSpecies([A]*3)\n", - "M2 = Multimer(A, 3)\n", - "print(\"ComplexSpecies([A]*3)\", M1)\n", - "print(\"Multimer(A, 3)\", M2)\n", - "print(\"M1 == M2 ==>\", M1 == M2)\n", - "\n", "print(\"\\nFor OrderedComplexSpecies, the Order Does Matter:\")\n", - "C3 = OrderedComplexSpecies([A, B, B2, A])\n", - "C4 = OrderedComplexSpecies([B, A, B2, A])\n", + "C3 = Complex([A, B, B2, A], ordered = True)\n", + "C4 = Complex([B, A, B2, A], ordered = True)\n", "print(\"C3=OrderedComplexSpecies([A, B, B2, A])=\", C3)\n", "print(\"C4=OrderedComplexSpecies([B, A, B2, A])=\", C4)\n", "print(\"C3==C4 ==>\", C3==C4)\n", "\n", "print(\"\\nComplexSpecies (and the OrderedComplexSpecies and Multimers) are Species and can be used in reactions:\")\n", - "R = Reaction([A, B, B2, A], [C1], k = 10)\n", - "print(\"Reaction([A, B, B2, A], [C1], k = 10)=\")\n", + "R = Reaction.from_massaction([A, B, B2, A], [C1], k_forward=10)\n", + "print(\"Reaction.from_massaction([A, B, B2, A], [C1], k_forward = 10)=\")\n", "print(R)" ] }, @@ -269,11 +287,59 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 5, "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "Massaction Activation Species = dna_G, protein_A, complex_dna_G_protein_A_2x, protein_X\n", + "Reactions = [\n", + "\tdna[G]+2protein[A] <--> complex[dna[G]:2x_protein[A]]\n", + "\tcomplex[dna[G]:2x_protein[A]] --> complex[dna[G]:2x_protein[A]]+protein[X]\n", + "\tprotein[X] --> \n", + "]\n", + "\n", + "Massaction Repression Species = dna_G, protein_A, complex_dna_G_protein_A_2x, protein_X\n", + "Reactions = [\n", + "\tdna[G]+2protein[A] <--> complex[dna[G]:2x_protein[A]]\n", + "\tdna[G] --> dna[G]+protein[X]\n", + "\tprotein[X] --> \n", + "]\n", + "\n", + "Hill Positive CRN Species = dna_G, protein_A, protein_X\n", + "Reactions = [\n", + "\tdna[G] --> dna[G]+protein[X]\n", + "\tprotein[X] --> \n", + "]\n", + "\n", + "Proportional Hill Positive CRN Species = dna_G, protein_A, protein_X\n", + "Reactions = [\n", + "\tdna[G] --> dna[G]+protein[X]\n", + "\tprotein[X] --> \n", + "]\n", + "\n", + "Hill Negative CRN Species = dna_G, protein_A, protein_X\n", + "Reactions = [\n", + "\tdna[G] --> dna[G]+protein[X]\n", + "\tprotein[X] --> \n", + "]\n", + "\n", + "Proportional Hill Negative CRN Species = dna_G, protein_A, protein_X\n", + "Reactions = [\n", + "\tdna[G] --> dna[G]+protein[X]\n", + "\tprotein[X] --> \n", + "]\n" + ] + } + ], "source": [ - "from biocrnpyler.chemical_reaction_network import Species, Reaction, ComplexSpecies, ChemicalReactionNetwork\n", + "from biocrnpyler.chemical_reaction_network import ChemicalReactionNetwork\n", + "from biocrnpyler.species import Species\n", + "from biocrnpyler.reaction import Reaction\n", + "\n", "\n", "#Parameter Values\n", "kb = 100\n", @@ -284,42 +350,47 @@ "#Species\n", "G = Species(name = \"G\", material_type = \"dna\") #DNA\n", "A = Species(name = \"A\", material_type = \"protein\") #Activator\n", - "GA = ComplexSpecies([G, A, A]) #Activated Gene\n", + "GA = Complex([G, A, A]) #Activated Gene\n", "X = Species(name = \"X\", material_type = \"protein\")\n", "\n", - "rxnd = Reaction([X], [], kd)\n", + "rxnd = Reaction.from_massaction([X], [], k_forward=kd)\n", "\n", "#Massaction Activation\n", "species1 = [G, A, GA, X]\n", - "rxn0_1 = Reaction([G, A, A], [GA], k=kb, k_rev = ku)\n", - "rxn0_2 = Reaction([GA], [GA, X], k=kex)\n", + "mak = MassAction(k_forward=kb, k_reverse=ku)\n", + "rxn0_1 = Reaction([G, A, A], [GA], propensity_type=mak)\n", + "rxn0_2 = Reaction.from_massaction([GA], [GA, X], k_forward=kex)\n", "CRN0 = ChemicalReactionNetwork(species1, [rxn0_1, rxn0_2, rxnd])\n", "print(\"\\nMassaction Activation\", repr(CRN0))\n", "\n", - "#Massaction Repressed\n", - "rxn1_1 = Reaction([G, A, A], [GA], k=kb, k_rev = ku)\n", - "rxn1_2 = Reaction([G], [G, X], k=kex)\n", + "#Massaction Repression\n", + "rxn1_1 = Reaction.from_massaction([G, A, A], [GA], k_forward=kb, k_reverse=ku)\n", + "rxn1_2 = Reaction.from_massaction([G], [G, X], k_forward=kex)\n", "CRN1 = ChemicalReactionNetwork(species1, [rxn1_1, rxn1_2, rxnd])\n", "print(\"\\nMassaction Repression\", repr(CRN1))\n", "\n", - "#hill positive\n", + "#Hill positive\n", "species2 = [G, A, X]\n", - "rxn2_1 = Reaction([G], [G, X], propensity_type = \"hillpositive\", propensity_params = {\"k\":kex, \"n\":2, \"K\":float(kb/ku), \"s1\":A})\n", + "hill_positive = HillPositive(k=kex, K=float(kb/ku), s1=A, n=2)\n", + "rxn2_1 = Reaction([G], [G, X], propensity_type=hill_positive)\n", "CRN2 = ChemicalReactionNetwork(species2, [rxn2_1, rxnd])\n", "print(\"\\nHill Positive CRN\", repr(CRN2))\n", "\n", - "#proportional hill positive\n", - "rxn3_1 = Reaction([G], [G, X], propensity_type = \"proportionalhillpositive\", propensity_params = {\"k\":kex, \"n\":2, \"K\":float(kb/ku), \"s1\":A, \"d\":G})\n", + "#proportional Hill positive\n", + "prop_hill_positive = ProportionalHillPositive(k=kex, K=float(kb/ku), s1=A, d=G, n=2)\n", + "rxn3_1 = Reaction([G], [G, X], propensity_type=prop_hill_positive)\n", "CRN3 = ChemicalReactionNetwork(species2, [rxn3_1, rxnd])\n", "print(\"\\nProportional Hill Positive CRN\", repr(CRN3))\n", "\n", - "#hill Negative\n", - "rxn4_1 = Reaction([G], [G, X], propensity_type = \"hillnegative\", propensity_params = {\"k\":kex, \"n\":2, \"K\":float(kb/ku), \"s1\":A})\n", + "#Hill Negative\n", + "hill_negative = HillNegative(k=kex, K=float(kb/ku), n=2, s1=A)\n", + "rxn4_1 = Reaction([G], [G, X], propensity_type=hill_negative)\n", "CRN4 = ChemicalReactionNetwork(species2, [rxn4_1, rxnd])\n", "print(\"\\nHill Negative CRN\", repr(CRN4))\n", "\n", "#proportional hill negative\n", - "rxn5_1 = Reaction([G], [G, X], propensity_type = \"proportionalhillnegative\", propensity_params = {\"k\":kex, \"n\":2, \"K\":float(kb/ku), \"s1\":A, \"d\":G})\n", + "prop_hill_negative = ProportionalHillNegative(k=kex, K=float(kb/ku), s1=A, d=G, n=2)\n", + "rxn5_1 = Reaction([G], [G, X], propensity_type=prop_hill_negative)\n", "CRN5 = ChemicalReactionNetwork(species2, [rxn5_1, rxnd])\n", "print(\"\\nProportional Hill Negative CRN\", repr(CRN5))" ] @@ -346,4 +417,4 @@ }, "nbformat": 4, "nbformat_minor": 4 -} +} \ No newline at end of file diff --git a/examples/2. Compiling CRNs with Enzymes Catalysis and Binding.ipynb b/examples/2. Compiling CRNs with Enzymes Catalysis and Binding.ipynb index 3a54eb9c..91c889b8 100644 --- a/examples/2. Compiling CRNs with Enzymes Catalysis and Binding.ipynb +++ b/examples/2. Compiling CRNs with Enzymes Catalysis and Binding.ipynb @@ -30,7 +30,7 @@ "In this context, Enzyme is a Component which looks for a 'catalysis' Mechanism. Two different Mixtures will be compared with different default 'catalysis' Mechanisms.\n", "\n", "1. Baisc Catalysis: $E + S \\xrightarrow{k_{cat}} E + P$\n", - "2. Michalis Menten Catalysis: $E + S \\underset{k_u}{\\overset{k_b}{\\rightleftharpoons}}E:S \\xrightarrow{k_{cat}} E + P$\n", + "2. Michaelis Menten Catalysis: $E + S \\underset{k_u}{\\overset{k_b}{\\rightleftharpoons}}E:S \\xrightarrow{k_{cat}} E + P$\n", "\n", "By default, the Enzyme Component will inherit the Mechanism in its Mixture." ] @@ -49,27 +49,28 @@ "Components = [\n", "\tEnzyme: E ]\n", "Mechanisms = {\n", - "\tcatalysis:basic_catalysis }\n", - "Global Mechanisms = { } \n", + "\tcatalysis:basic_catalysis } \n", "\n", "String representation of a CRN shows the string names of all species:\n", " Species = protein_E, S, P\n", "Reactions = [\n", - "\tprotein_E + S --> protein_E + P massaction: k_f(protein_E,S)=1.0*protein_E*S\n", + "\tprotein[E]+S --> protein[E]+P\n", "] \n", "\n", "\n", "Pretty_print representation of a CRN has formatting options and is easier to read:\n", " Species (3) = {0. protein[E], 1. S, 2. P}\n", + "\n", "Reactions (1) = [\n", - "0. protein[E] + S --> protein[E] + P \n", - " massaction: k_f(protein[E],S)=1.0*protein[E]*S\n", + "0. protein[E]+S --> protein[E]+P\n", + " Kf=k_forward * protein_E * S\n", + " k_forward=1.0\n", + "\n", "]\n" ] } ], "source": [ - "%matplotlib inline\n", "from biocrnpyler import *\n", "\n", "#We will use default parameter names\n", @@ -80,7 +81,7 @@ "\n", "#Choose a catalysis mechanism by commenting out one of them.\n", "mech_cat = BasicCatalysis()\n", - "#mech_cat = MichalisMenten()\n", + "#mech_cat = MichaelisMenten()\n", "\n", "#place that mechanism in a dictionary: \"catalysis\":mech_cat\n", "default_mechanisms = {mech_cat.mechanism_type:mech_cat}\n", @@ -89,7 +90,7 @@ "#Components is a list of Components in the mixture\n", "#parameters is a dictionary of parameters. Can also accept parameter_file.\n", "#default_mechanisms = dict sets the default_mechanisms in the Mixture\n", - "M = Mixture(\"Catalysis Mixture\", components = [E], parameters = default_parameters, default_mechanisms = default_mechanisms)\n", + "M = Mixture(\"Catalysis Mixture\", components = [E], parameters = default_parameters, mechanisms = default_mechanisms)\n", "print(\"repr(Mixture) gives a printout of what is in a mixture and what it's Mechanisms are:\\n\", repr(M),\"\\n\")\n", "\n", "#Compile the CRN with Mixture.compile_crn\n", @@ -98,7 +99,7 @@ "#CRNs can be printed in two ways\n", "print(\"String representation of a CRN shows the string names of all species:\\n\",CRN, \"\\n\\n\")\n", "print(\"Pretty_print representation of a CRN has formatting options and is easier to read:\\n\",\n", - " CRN.pretty_print(show_rates = True, show_attributes = True, show_materials = True))" + " CRN.pretty_print(show_rates = True, show_attributes = True, show_materials = True, show_keys = False))" ] }, { @@ -136,17 +137,23 @@ "\tEnzyme: E2\n", "\tMultiEnzyme: E3 ]\n", "Mechanisms = {\n", - "\tcatalysis:basic_catalysis }\n", - "Global Mechanisms = { } \n", + "\tcatalysis:basic_catalysis } \n", "\n", "Species (8) = {0. protein[E1], 1. A, 2. B, 3. protein[E2], 4. C, 5. D, 6. protein[E3], 7. F}\n", + "\n", "Reactions (3) = [\n", - "0. protein[E1] + A --> protein[E1] + B \n", - " massaction: k_f(protein[E1],A)=1.0*protein[E1]*A\n", - "1. protein[E2] + C --> protein[E2] + D \n", - " massaction: k_f(protein[E2],C)=1.0*protein[E2]*C\n", - "2. protein[E3] + B + D --> protein[E3] + F \n", - " massaction: k_f(protein[E3],B,D)=1.0*protein[E3]*B*D\n", + "0. protein[E1]+A --> protein[E1]+B\n", + " Kf=k_forward * protein_E1 * A\n", + " k_forward=1.0\n", + "\n", + "1. protein[E2]+C --> protein[E2]+D\n", + " Kf=k_forward * protein_E2 * C\n", + " k_forward=1.0\n", + "\n", + "2. protein[E3]+B+D --> protein[E3]+F\n", + " Kf=k_forward * protein_E3 * B * D\n", + " k_forward=1.0\n", + "\n", "]\n" ] } @@ -161,7 +168,7 @@ "\n", "#creeate a catalysis mechanism. \n", "mech_cat = BasicCatalysis()\n", - "#mech_cat = MichalisMenten()\n", + "#mech_cat = MichaelisMenten()\n", "\n", "#place that mechanism in a dictionary: \"catalysis\":mech_cat\n", "default_mechanisms = {mech_cat.mechanism_type:mech_cat}\n", @@ -170,12 +177,12 @@ "#Components is a list of Components in the mixture\n", "#parameters is a dictionary of parameters. Can also accept parameter_file.\n", "#default_mechanisms = dict sets the default_mechanisms in the Mixture\n", - "M = Mixture(\"Default Param Pathway\", components = [E1, E2, E3], parameters = default_parameters, default_mechanisms = default_mechanisms)\n", + "M = Mixture(\"Default Param Pathway\", components = [E1, E2, E3], parameters = default_parameters, mechanisms = default_mechanisms)\n", "print(\"repr(Mixture) gives a printout of what is in a mixture and what it's Mechanisms are:\\n\", repr(M),\"\\n\")\n", "\n", "#Compile the CRN with Mixture.compile_crn\n", "CRN = M.compile_crn()\n", - "print(CRN.pretty_print(show_rates = True, show_attributes = True, show_materials = True))" + "print(CRN.pretty_print(show_rates = True, show_attributes = True, show_materials = True, show_keys = False))" ] }, { @@ -183,9 +190,9 @@ "metadata": {}, "source": [ "# Example 3: A Pathway of Enzymes with Specific Parameters for Each Enzyme\n", - "In the previous example, the same default parameters used by all the Enzymes. It is also easy to have specific parameters for each enzyme. Specific parameters can be given in a dictionary or parameter file using a variety of keys (see the Parameters notebook for details). The simplest, however, is:\n", + "In the previous example, the same default parameters used by all the Enzymes. It is also easy to have specific parameters for each enzyme. Specific parameters can be given in a dictionary or parameter file using a variety of keys (see the Parameters notebook for details). The simplest, however, is to make a dictionary of ParameterKeys:\n", "\n", - " (\"mechanism name/type\", \"component name\", \"parameter name\") : value\n", + " ParameterKey(mechanism = \"mechanism name/type\", part_id = \"component name\", name = \"parameter name\") : value\n", "\n", "Notice that by switching the catalysis Mechanism, different parameters are used." ] @@ -200,23 +207,59 @@ "output_type": "stream", "text": [ "Using Specific Parameters for all reactions:\n", - " Species (11) = {0. protein[E1], 1. A, 2. B, 3. complex[A:protein[E1]], 4. protein[E2], 5. C, 6. D, 7. complex[C:protein[E2]], 8. protein[E3], 9. F, 10. complex[B:D:protein[E3]]}\n", + "Viewing the ParameterKeys used in a CRN can be toggled with the show_keys=True/False keyword in CRN.pretty_print.\n", + "\n", + "Species (11) = {0. protein[E1], 1. A, 2. B, 3. complex[A:protein[E1]], 4. protein[E2], 5. C, 6. D, 7. complex[C:protein[E2]], 8. protein[E3], 9. F, 10. complex[B:D:protein[E3]]}\n", + "\n", "Reactions (6) = [\n", - "0. A + protein[E1] <--> complex[A:protein[E1]] \n", - " massaction: k_f(A,protein[E1])=111*A*protein[E1]\n", - " k_r(complex[A:protein[E1]])=11*complex[A:protein[E1]]\n", - "1. complex[A:protein[E1]] --> B + protein[E1] \n", - " massaction: k_f(complex[A:protein[E1]])=1.11*complex[A:protein[E1]]\n", - "2. C + protein[E2] <--> complex[C:protein[E2]] \n", - " massaction: k_f(C,protein[E2])=222*C*protein[E2]\n", - " k_r(complex[C:protein[E2]])=22*complex[C:protein[E2]]\n", - "3. complex[C:protein[E2]] --> D + protein[E2] \n", - " massaction: k_f(complex[C:protein[E2]])=2.22*complex[C:protein[E2]]\n", - "4. B + D + protein[E3] <--> complex[B:D:protein[E3]] \n", - " massaction: k_f(B,D,protein[E3])=333*B*D*protein[E3]\n", - " k_r(complex[B:D:protein[E3]])=33*complex[B:D:protein[E3]]\n", - "5. complex[B:D:protein[E3]] --> F + protein[E3] \n", - " massaction: k_f(complex[B:D:protein[E3]])=3.33*complex[B:D:protein[E3]]\n", + "0. A+protein[E1] <--> complex[A:protein[E1]]\n", + " Kf=k_forward * A * protein_E1\n", + " Kr=k_reverse * complex_A_protein_E1\n", + " k_forward=111\n", + " found_key=(mech=michalis_menten, partid=E1, name=kb).\n", + " search_key=(mech=michalis_menten, partid=E1, name=kb).\n", + " k_reverse=11\n", + " found_key=(mech=michalis_menten, partid=E1, name=ku).\n", + " search_key=(mech=michalis_menten, partid=E1, name=ku).\n", + "\n", + "1. complex[A:protein[E1]] --> B+protein[E1]\n", + " Kf=k_forward * complex_A_protein_E1\n", + " k_forward=1.11\n", + " found_key=(mech=michalis_menten, partid=E1, name=kcat).\n", + " search_key=(mech=michalis_menten, partid=E1, name=kcat).\n", + "\n", + "2. C+protein[E2] <--> complex[C:protein[E2]]\n", + " Kf=k_forward * C * protein_E2\n", + " Kr=k_reverse * complex_C_protein_E2\n", + " k_forward=222\n", + " found_key=(mech=michalis_menten, partid=E2, name=kb).\n", + " search_key=(mech=michalis_menten, partid=E2, name=kb).\n", + " k_reverse=22\n", + " found_key=(mech=michalis_menten, partid=E2, name=ku).\n", + " search_key=(mech=michalis_menten, partid=E2, name=ku).\n", + "\n", + "3. complex[C:protein[E2]] --> D+protein[E2]\n", + " Kf=k_forward * complex_C_protein_E2\n", + " k_forward=2.22\n", + " found_key=(mech=michalis_menten, partid=E2, name=kcat).\n", + " search_key=(mech=michalis_menten, partid=E2, name=kcat).\n", + "\n", + "4. B+D+protein[E3] <--> complex[B:D:protein[E3]]\n", + " Kf=k_forward * B * D * protein_E3\n", + " Kr=k_reverse * complex_B_D_protein_E3\n", + " k_forward=333\n", + " found_key=(mech=michalis_menten, partid=E3, name=kb).\n", + " search_key=(mech=michalis_menten, partid=E3, name=kb).\n", + " k_reverse=33\n", + " found_key=(mech=michalis_menten, partid=E3, name=ku).\n", + " search_key=(mech=michalis_menten, partid=E3, name=ku).\n", + "\n", + "5. complex[B:D:protein[E3]] --> F+protein[E3]\n", + " Kf=k_forward * complex_B_D_protein_E3\n", + " k_forward=3.33\n", + " found_key=(mech=michalis_menten, partid=E3, name=kcat).\n", + " search_key=(mech=michalis_menten, partid=E3, name=kcat).\n", + "\n", "]\n" ] } @@ -224,11 +267,21 @@ "source": [ "#Or specific parameters can be made which give different rates for each enzyme\n", "#The first row of parameters is used by BasicCatalysis\n", - "#The second-fourth row of parameters is used my MichalisMenten catalysis\n", - "specific_parameters = {(\"basic_catalysis\", \"E1\", \"kcat\"):100, (\"basic_catalysis\", \"E2\", \"kcat\"):200, (\"basic_catalysis\", \"E3\", \"kcat\"):300,\n", - " (\"michalis_menten\", \"E1\", \"kb\"):111, (\"michalis_menten\", \"E1\", \"ku\"):11, (\"michalis_menten\", \"E1\", \"kcat\"): 1.11,\n", - " (\"michalis_menten\", \"E2\", \"kb\"):222, (\"michalis_menten\", \"E2\", \"ku\"):22, (\"michalis_menten\", \"E2\", \"kcat\"): 2.22,\n", - " (\"michalis_menten\", \"E3\", \"kb\"):333, (\"michalis_menten\", \"E3\", \"ku\"):33, (\"michalis_menten\", \"E3\", \"kcat\"): 3.33}\n", + "#The second-fourth row of parameters is used my MichaelisMenten catalysis\n", + "specific_parameters = {\n", + " ParameterKey(mechanism = \"basic_catalysis\", part_id = \"E1\", name = \"kcat\"):100,\n", + " ParameterKey(mechanism = \"basic_catalysis\", part_id = \"E2\", name = \"kcat\"):200, \n", + " ParameterKey(mechanism = \"basic_catalysis\", part_id = \"E3\", name = \"kcat\"):300,\n", + " ParameterKey(mechanism = \"michalis_menten\", part_id = \"E1\", name = \"kb\"):111,\n", + " ParameterKey(mechanism = \"michalis_menten\", part_id = \"E1\", name = \"ku\"):11, \n", + " ParameterKey(mechanism = \"michalis_menten\", part_id = \"E1\", name = \"kcat\"): 1.11,\n", + " ParameterKey(mechanism = \"michalis_menten\", part_id = \"E2\", name = \"kb\"):222, \n", + " ParameterKey(mechanism = \"michalis_menten\", part_id = \"E2\", name = \"ku\"):22, \n", + " ParameterKey(mechanism = \"michalis_menten\", part_id = \"E2\", name = \"kcat\"): 2.22,\n", + " ParameterKey(mechanism = \"michalis_menten\", part_id = \"E3\", name = \"kb\"):333, \n", + " ParameterKey(mechanism = \"michalis_menten\", part_id = \"E3\", name = \"ku\"):33, \n", + " ParameterKey(mechanism = \"michalis_menten\", part_id = \"E3\", name = \"kcat\"): 3.33\n", + "}\n", "\n", "E1 = Enzyme(\"E1\", substrate = \"A\", product = \"B\")\n", "E2 = Enzyme(\"E2\", substrate = \"C\", product = \"D\")\n", @@ -236,15 +289,17 @@ "\n", "#choose a catalysis mechanism. \n", "#mech_cat = BasicCatalysis()\n", - "mech_cat = MichalisMenten()\n", + "mech_cat = MichaelisMenten()\n", "\n", "#place that mechanism in a dictionary: \"catalysis\":mech_cat\n", "default_mechanisms = {mech_cat.mechanism_type:mech_cat}\n", "\n", "#To change the parameters, pass in a different dictionary using the parameter keyword\n", - "M = Mixture(\"Catalysis Mixture\", components = [E1, E2, E3], parameters = specific_parameters, default_mechanisms = default_mechanisms)\n", + "M = Mixture(\"Catalysis Mixture\", components = [E1, E2, E3], parameters = specific_parameters, mechanisms = default_mechanisms)\n", "CRN = M.compile_crn()\n", - "print(\"Using Specific Parameters for all reactions:\\n\", CRN.pretty_print())" + "print(\"Using Specific Parameters for all reactions:\")\n", + "print(\"Viewing the ParameterKeys used in a CRN can be toggled with the show_keys=True/False keyword in CRN.pretty_print.\\n\")\n", + "print(CRN.pretty_print(show_rates = True, show_keys = True))" ] }, { @@ -254,7 +309,7 @@ "# Example 4: Adding a Custom Mechanism to a Component\n", "Notice that in the above CRN, the enzymatic process is irreversible. However, many biochemists would argue that irreversibility is actually an approximation. In reality, the products of the reaction can bind to the enzyme and, if the chemical potential is high enough, cause the reverse reaction to occur. In many cases, it might be desirable to to only include the reverse reaction for some of the enzymatic reactions being in the Model. In BioCRNpyler, this can be done easily by adding a custom Mechanism to an individual Component which will override the default Mechanism provided by the Mixture.\n", "\n", - "This is illustrated on the pathway built above, where here Enzyme 3 will be given a new catalysis mechanism called MichalisMentenReversible: $E + S \\rightleftarrows E:S \\rightleftarrows E:P \\rightleftarrows E + P$" + "This is illustrated on the pathway built above, where here Enzyme 3 will be given a new catalysis mechanism called MichaelisMentenReversible: $E + S \\rightleftarrows E:S \\rightleftarrows E:P \\rightleftarrows E + P$" ] }, { @@ -268,32 +323,52 @@ "text": [ "Notice that there are additional reactions involving E3:\n", " Species (12) = {0. protein[E1], 1. A, 2. B, 3. complex[A:protein[E1]], 4. protein[E2], 5. C, 6. D, 7. complex[C:protein[E2]], 8. protein[E3], 9. F, 10. complex[B:D:protein[E3]], 11. complex[F:protein[E3]]}\n", + "\n", "Reactions (7) = [\n", - "0. A + protein[E1] <--> complex[A:protein[E1]] \n", - " massaction: k_f(A,protein[E1])=100*A*protein[E1]\n", - " k_r(complex[A:protein[E1]])=10*complex[A:protein[E1]]\n", - "1. complex[A:protein[E1]] --> B + protein[E1] \n", - " massaction: k_f(complex[A:protein[E1]])=1.0*complex[A:protein[E1]]\n", - "2. C + protein[E2] <--> complex[C:protein[E2]] \n", - " massaction: k_f(C,protein[E2])=100*C*protein[E2]\n", - " k_r(complex[C:protein[E2]])=10*complex[C:protein[E2]]\n", - "3. complex[C:protein[E2]] --> D + protein[E2] \n", - " massaction: k_f(complex[C:protein[E2]])=1.0*complex[C:protein[E2]]\n", - "4. B + D + protein[E3] <--> complex[B:D:protein[E3]] \n", - " massaction: k_f(B,D,protein[E3])=111*B*D*protein[E3]\n", - " k_r(complex[B:D:protein[E3]])=11*complex[B:D:protein[E3]]\n", - "5. F + protein[E3] <--> complex[F:protein[E3]] \n", - " massaction: k_f(F,protein[E3])=22*F*protein[E3]\n", - " k_r(complex[F:protein[E3]])=22*complex[F:protein[E3]]\n", - "6. complex[B:D:protein[E3]] <--> complex[F:protein[E3]] \n", - " massaction: k_f(complex[B:D:protein[E3]])=1.0*complex[B:D:protein[E3]]\n", - " k_r(complex[F:protein[E3]])=0.001*complex[F:protein[E3]]\n", + "0. A+protein[E1] <--> complex[A:protein[E1]]\n", + " Kf=k_forward * A * protein_E1\n", + " Kr=k_reverse * complex_A_protein_E1\n", + " k_forward=100\n", + " k_reverse=10\n", + "\n", + "1. complex[A:protein[E1]] --> B+protein[E1]\n", + " Kf=k_forward * complex_A_protein_E1\n", + " k_forward=1.0\n", + "\n", + "2. C+protein[E2] <--> complex[C:protein[E2]]\n", + " Kf=k_forward * C * protein_E2\n", + " Kr=k_reverse * complex_C_protein_E2\n", + " k_forward=100\n", + " k_reverse=10\n", + "\n", + "3. complex[C:protein[E2]] --> D+protein[E2]\n", + " Kf=k_forward * complex_C_protein_E2\n", + " k_forward=1.0\n", + "\n", + "4. B+D+protein[E3] <--> complex[B:D:protein[E3]]\n", + " Kf=k_forward * B * D * protein_E3\n", + " Kr=k_reverse * complex_B_D_protein_E3\n", + " k_forward=111\n", + " k_reverse=11\n", + "\n", + "5. F+protein[E3] <--> complex[F:protein[E3]]\n", + " Kf=k_forward * F * protein_E3\n", + " Kr=k_reverse * complex_F_protein_E3\n", + " k_forward=22\n", + " k_reverse=22\n", + "\n", + "6. complex[B:D:protein[E3]] <--> complex[F:protein[E3]]\n", + " Kf=k_forward * complex_B_D_protein_E3\n", + " Kr=k_reverse * complex_F_protein_E3\n", + " k_forward=1.0\n", + " k_reverse=0.001\n", + "\n", "]\n" ] } ], "source": [ - "#The MichalisMentenReversible has different parameter names: kb1, ku1, kb2, ku2, and kcat_rev\n", + "#The MichaelisMentenReversible has different parameter names: kb1, ku1, kb2, ku2, and kcat_rev\n", "default_parameters = {\"kb\":100, \"ku\":10, \"kcat\":1., \"kb1\":111, \"kb2\":22, \"ku1\":11, \"ku2\":22, \"kcat_rev\":.001}\n", "\n", "#Enzymes 1 and 2 are the same as above\n", @@ -301,21 +376,21 @@ "E2 = Enzyme(\"E2\", substrate = \"C\", product = \"D\")\n", "\n", "#Create a dictionary of custom mechanisms to pass into E3 with the mechanisms keyword\n", - "mm_reversible = MichalisMentenReversible()\n", + "mm_reversible = MichaelisMentenReversible()\n", "custom_mechanisms = {mm_reversible.mechanism_type:mm_reversible}\n", "E3 = MultiEnzyme(\"E3\", substrates = [\"B\", \"D\"], products = [\"F\"], mechanisms = custom_mechanisms)\n", "\n", "#choose a catalysis mechanism. \n", "#mech_cat = BasicCatalysis()\n", - "mech_cat = MichalisMenten()\n", + "mech_cat = MichaelisMenten()\n", "#place that mechanism in a dictionary: \"catalysis\":mech_cat\n", "default_mechanisms = {mech_cat.mechanism_type:mech_cat}\n", "#Make the Mixture\n", - "M = Mixture(\"Catalysis Mixture\", components = [E1, E2, E3], parameters = default_parameters, default_mechanisms = default_mechanisms)\n", + "M = Mixture(\"Catalysis Mixture\", components = [E1, E2, E3], parameters = default_parameters, mechanisms = default_mechanisms)\n", "#Compile the CRN\n", "CRN = M.compile_crn()\n", "\n", - "print(\"Notice that there are additional reactions involving E3:\\n\", CRN.pretty_print())" + "print(\"Notice that there are additional reactions involving E3:\\n\", CRN.pretty_print(show_rates = True, show_keys = False))" ] }, { @@ -341,26 +416,46 @@ "output_type": "stream", "text": [ "Species (12) = {0. protein[E1], 1. A, 2. B, 3. complex[A:protein[E1]], 4. protein[E2], 5. C, 6. D, 7. complex[C:protein[E2]], 8. protein[E3], 9. F, 10. complex[B:D:protein[E3]], 11. complex[F:protein[E3]]}\n", + "\n", "Reactions (7) = [\n", - "0. A + protein[E1] <--> complex[A:protein[E1]] \n", - " massaction: k_f(A,protein[E1])=100*A*protein[E1]\n", - " k_r(complex[A:protein[E1]])=10*complex[A:protein[E1]]\n", - "1. complex[A:protein[E1]] --> B + protein[E1] \n", - " massaction: k_f(complex[A:protein[E1]])=1.0*complex[A:protein[E1]]\n", - "2. C + protein[E2] <--> complex[C:protein[E2]] \n", - " massaction: k_f(C,protein[E2])=100*C*protein[E2]\n", - " k_r(complex[C:protein[E2]])=10*complex[C:protein[E2]]\n", - "3. complex[C:protein[E2]] --> D + protein[E2] \n", - " massaction: k_f(complex[C:protein[E2]])=1.0*complex[C:protein[E2]]\n", - "4. B + D + protein[E3] <--> complex[B:D:protein[E3]] \n", - " massaction: k_f(B,D,protein[E3])=111*B*D*protein[E3]\n", - " k_r(complex[B:D:protein[E3]])=11*complex[B:D:protein[E3]]\n", - "5. F + protein[E3] <--> complex[F:protein[E3]] \n", - " massaction: k_f(F,protein[E3])=22*F*protein[E3]\n", - " k_r(complex[F:protein[E3]])=22*complex[F:protein[E3]]\n", - "6. complex[B:D:protein[E3]] <--> complex[F:protein[E3]] \n", - " massaction: k_f(complex[B:D:protein[E3]])=1.0*complex[B:D:protein[E3]]\n", - " k_r(complex[F:protein[E3]])=0.001*complex[F:protein[E3]]\n", + "0. A+protein[E1] <--> complex[A:protein[E1]]\n", + " Kf=k_forward * A * protein_E1\n", + " Kr=k_reverse * complex_A_protein_E1\n", + " k_forward=100\n", + " k_reverse=10\n", + "\n", + "1. complex[A:protein[E1]] --> B+protein[E1]\n", + " Kf=k_forward * complex_A_protein_E1\n", + " k_forward=1.0\n", + "\n", + "2. C+protein[E2] <--> complex[C:protein[E2]]\n", + " Kf=k_forward * C * protein_E2\n", + " Kr=k_reverse * complex_C_protein_E2\n", + " k_forward=100\n", + " k_reverse=10\n", + "\n", + "3. complex[C:protein[E2]] --> D+protein[E2]\n", + " Kf=k_forward * complex_C_protein_E2\n", + " k_forward=1.0\n", + "\n", + "4. B+D+protein[E3] <--> complex[B:D:protein[E3]]\n", + " Kf=k_forward * B * D * protein_E3\n", + " Kr=k_reverse * complex_B_D_protein_E3\n", + " k_forward=111\n", + " k_reverse=11\n", + "\n", + "5. F+protein[E3] <--> complex[F:protein[E3]]\n", + " Kf=k_forward * F * protein_E3\n", + " Kr=k_reverse * complex_F_protein_E3\n", + " k_forward=22\n", + " k_reverse=22\n", + "\n", + "6. complex[B:D:protein[E3]] <--> complex[F:protein[E3]]\n", + " Kf=k_forward * complex_B_D_protein_E3\n", + " Kr=k_reverse * complex_F_protein_E3\n", + " k_forward=1.0\n", + " k_reverse=0.001\n", + "\n", "]\n" ] } @@ -382,8 +477,8 @@ "\n", "#choose a catalysis mechanism. \n", "#mech_cat = BasicCatalysis()\n", - "mech_cat = MichalisMenten()\n", - "#mech_cat = MichalisMentenReversible()\n", + "mech_cat = MichaelisMenten()\n", + "#mech_cat = MichaelisMentenReversible()\n", "\n", "#create a binding mechanism\n", "mech_bind = One_Step_Binding() #All species bind together in a single step\n", @@ -392,15 +487,17 @@ "default_mechanisms = {mech_cat.mechanism_type:mech_cat, mech_bind.mechanism_type:mech_bind}\n", "\n", "#Make the Mixture\n", - "M = Mixture(\"Catalysis Mixture\", components = [E1, E2, E3], parameters = default_parameters, default_mechanisms = default_mechanisms)\n", + "M = Mixture(\"Catalysis Mixture\", components = [E1, E2, E3], parameters = default_parameters, mechanisms = default_mechanisms)\n", "#Compile the CRN\n", "CRN = M.compile_crn()\n", - "print(CRN.pretty_print())" + "print(CRN.pretty_print(show_rates = True, show_keys = False))" ] }, { - "cell_type": "markdown", + "cell_type": "code", + "execution_count": null, "metadata": {}, + "outputs": [], "source": [] } ], @@ -425,4 +522,4 @@ }, "nbformat": 4, "nbformat_minor": 4 -} +} \ No newline at end of file diff --git a/examples/3. DNA Assemblies, gene expression, transcription, and translation.ipynb b/examples/3. DNA Assemblies, gene expression, transcription, and translation.ipynb index 0f398828..2d5a2052 100644 --- a/examples/3. DNA Assemblies, gene expression, transcription, and translation.ipynb +++ b/examples/3. DNA Assemblies, gene expression, transcription, and translation.ipynb @@ -18,11 +18,10 @@ }, { "cell_type": "code", - "execution_count": 10, + "execution_count": 1, "metadata": {}, "outputs": [ { - "name": "stdout", "output_type": "stream", "text": [ "repr(Mixture) gives a printout of what is in a mixture and what it's Mechanisms are:\n", @@ -31,22 +30,29 @@ "\tDNAassembly: X ]\n", "Mechanisms = {\n", "\ttranscription:simple_transcription\n", - "\ttranslation:simple_translation }\n", - "Global Mechanisms = { } \n", + "\ttranslation:simple_translation } \n", "\n", "Pretty_print representation of the CRN:\n", - " Species (3) = {0. dna[X], 1. protein[X], 2. rna[X]}\n", + " Species (3) = {0. dna[X], 1. rna[X], 2. protein[X]}\n", + "\n", "Reactions (2) = [\n", - "0. dna[X] --> dna[X] + rna[X] \n", - " massaction: k_f(dna[X])=0.5*dna[X]\n", - "1. rna[X] --> rna[X] + protein[X] \n", - " massaction: k_f(rna[X])=2*rna[X]\n", + "0. dna[X] --> dna[X]+rna[X]\n", + " Kf=k_forward * dna_X\n", + " k_forward=0.5\n", + " found_key=(mech=None, partid=None, name=ktx).\n", + " search_key=(mech=simple_transcription, partid=P, name=ktx).\n", + "\n", + "1. rna[X] --> rna[X]+protein[X]\n", + " Kf=k_forward * rna_X\n", + " k_forward=2\n", + " found_key=(mech=None, partid=None, name=ktl).\n", + " search_key=(mech=simple_translation, partid=RBS, name=ktl).\n", + "\n", "]\n" ] } ], "source": [ - "%matplotlib inline\n", "from biocrnpyler import *\n", "\n", "#promoter is the name of the promoter or a Promoter component\n", @@ -66,7 +72,8 @@ "#Use default parameters for conviencience\n", "default_parameters = {\"kb\":100, \"ku\":10, \"ktx\":.5, \"ktl\":2}\n", "#Create a mixture.\n", - "M = Mixture(\"Catalysis Mixture\", components = [G], parameters = default_parameters, default_mechanisms = default_mechanisms)\n", + "M = Mixture(\"Catalysis Mixture\", components = [G], parameters = default_parameters, mechanisms = default_mechanisms)\n", + " \n", "print(\"repr(Mixture) gives a printout of what is in a mixture and what it's Mechanisms are:\\n\", repr(M),\"\\n\")\n", "\n", "#Compile the CRN with Mixture.compile_crn\n", @@ -105,11 +112,10 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": 2, "metadata": {}, "outputs": [ { - "name": "stdout", "output_type": "stream", "text": [ "ExpressionDilutionMixture: ExpressionDilution\n", @@ -123,11 +129,20 @@ "Global Mechanisms = {\n", "\tdilution:dilution } \n", " Species (2) = {0. dna[X], 1. protein[X]}\n", + "\n", "Reactions (2) = [\n", - "0. dna[X] --> dna[X] + protein[X] \n", - " massaction: k_f(dna[X])=0.28125*dna[X]\n", - "1. protein[X] --> \n", - " massaction: k_f(protein[X])=0.001*protein[X]\n", + "0. dna[X] --> dna[X]+protein[X]\n", + " Kf=k_forward * dna_X\n", + " k_forward=0.28125\n", + " found_key=(mech=gene_expression, partid=None, name=kexpress).\n", + " search_key=(mech=gene_expression, partid=strong, name=kexpress).\n", + "\n", + "1. protein[X] --> \n", + " Kf=k_forward * protein_X\n", + " k_forward=0.001\n", + " found_key=(mech=None, partid=None, name=kdil).\n", + " search_key=(mech=dilution, partid=protein_X, name=kdil).\n", + "\n", "] \n", "\n", "\n", @@ -142,12 +157,51 @@ "Global Mechanisms = {\n", "\tdilution:global_degredation_via_dilution\n", "\trna_degredation:rna_degredation } \n", - " Species (2) = {0. dna[X], 1. protein[X]}\n", - "Reactions (2) = [\n", - "0. dna[X] --> dna[X] + protein[X] \n", - " massaction: k_f(dna[X])=0.28125*dna[X]\n", - "1. protein[X] --> \n", - " massaction: k_f(protein[X])=0.001*protein[X]\n", + " Species (3) = {0. dna[X], 1. rna[X], 2. protein[X]}\n", + "\n", + "Reactions (7) = [\n", + "0. dna[X] --> dna[X]+rna[X]\n", + " Kf=k_forward * dna_X\n", + " k_forward=0.4775625\n", + " found_key=(mech=simple_transcription, partid=strong, name=ktx).\n", + " search_key=(mech=simple_transcription, partid=strong, name=ktx).\n", + "\n", + "1. rna[X] --> rna[X]+protein[X]\n", + " Kf=k_forward * rna_X\n", + " k_forward=0.06\n", + " found_key=(mech=simple_translation, partid=weak, name=ktl).\n", + " search_key=(mech=simple_translation, partid=weak, name=ktl).\n", + "\n", + "2. rna[X] --> \n", + " Kf=k_forward * rna_X\n", + " k_forward=0.001\n", + " found_key=(mech=None, partid=None, name=kdil).\n", + " search_key=(mech=global_degredation_via_dilution, partid=rna_X, name=kdil).\n", + "\n", + "3. rna[X] --> \n", + " Kf=k_forward * rna_X\n", + " k_forward=0.001\n", + " found_key=(mech=None, partid=None, name=kdil).\n", + " search_key=(mech=global_degredation_via_dilution, partid=rna_X, name=kdil).\n", + "\n", + "4. protein[X] --> \n", + " Kf=k_forward * protein_X\n", + " k_forward=0.001\n", + " found_key=(mech=None, partid=None, name=kdil).\n", + " search_key=(mech=global_degredation_via_dilution, partid=protein_X, name=kdil).\n", + "\n", + "5. rna[X] --> \n", + " Kf=k_forward * rna_X\n", + " k_forward=0.001\n", + " found_key=(mech=rna_degredation, partid=None, name=kdil).\n", + " search_key=(mech=rna_degredation, partid=rna_X, name=kdil).\n", + "\n", + "6. rna[X] --> \n", + " Kf=k_forward * rna_X\n", + " k_forward=0.001\n", + " found_key=(mech=rna_degredation, partid=None, name=kdil).\n", + " search_key=(mech=rna_degredation, partid=rna_X, name=kdil).\n", + "\n", "] \n", "\n", "\n", @@ -166,38 +220,165 @@ "\tbinding:one_step_binding }\n", "Global Mechanisms = {\n", "\tdilution:global_degredation_via_dilution } \n", - " Species (13) = {0. dna[X], 1. rna[X], 2. protein[RNAase(machinery)], 3. protein[X], 4. complex[protein[RNAase]:rna[X](machinery)], 5. protein[RNAP(machinery)], 6. protein[Ribo(machinery)], 7. rna[cellular_processes], 8. complex[protein[RNAase]:rna[cellular_processes](machinery)], 9. protein[cellular_processes], 10. complex[dna[cellular_processes]:protein[RNAP](machinery)], 11. dna[cellular_processes], 12. complex[protein[Ribo]:rna[cellular_processes](machinery)]}\n", - "Reactions (13) = [\n", - "0. dna[X] --> dna[X] + protein[X] \n", - " massaction: k_f(dna[X])=0.28125*dna[X]\n", - "1. rna[X] + protein[RNAase(machinery)] <--> complex[protein[RNAase]:rna[X](machinery)] \n", - " massaction: k_f(rna[X],protein[RNAase(machinery)])=100.0*rna[X]*protein[RNAase(machinery)]\n", - " k_r(complex[protein[RNAase]:rna[X](machinery)])=10.0*complex[protein[RNAase]:rna[X](machinery)]\n", - "2. complex[protein[RNAase]:rna[X](machinery)] --> protein[RNAase(machinery)] \n", - " massaction: k_f(complex[protein[RNAase]:rna[X](machinery)])=0.001*complex[protein[RNAase]:rna[X](machinery)]\n", - "3. dna[cellular_processes] + protein[RNAP(machinery)] <--> complex[dna[cellular_processes]:protein[RNAP](machinery)] \n", - " massaction: k_f(dna[cellular_processes],protein[RNAP(machinery)])=500*dna[cellular_processes]*protein[RNAP(machinery)]\n", - " k_r(complex[dna[cellular_processes]:protein[RNAP](machinery)])=50*complex[dna[cellular_processes]:protein[RNAP](machinery)]\n", - "4. complex[dna[cellular_processes]:protein[RNAP](machinery)] --> dna[cellular_processes] + rna[cellular_processes] + protein[RNAP(machinery)] \n", - " massaction: k_f(complex[dna[cellular_processes]:protein[RNAP](machinery)])=0.1*complex[dna[cellular_processes]:protein[RNAP](machinery)]\n", - "5. rna[cellular_processes] + protein[Ribo(machinery)] <--> complex[protein[Ribo]:rna[cellular_processes](machinery)] \n", - " massaction: k_f(rna[cellular_processes],protein[Ribo(machinery)])=500*rna[cellular_processes]*protein[Ribo(machinery)]\n", - " k_r(complex[protein[Ribo]:rna[cellular_processes](machinery)])=5*complex[protein[Ribo]:rna[cellular_processes](machinery)]\n", - "6. complex[protein[Ribo]:rna[cellular_processes](machinery)] --> rna[cellular_processes] + protein[cellular_processes] + protein[Ribo(machinery)] \n", - " massaction: k_f(complex[protein[Ribo]:rna[cellular_processes](machinery)])=0.1*complex[protein[Ribo]:rna[cellular_processes](machinery)]\n", - "7. rna[cellular_processes] + protein[RNAase(machinery)] <--> complex[protein[RNAase]:rna[cellular_processes](machinery)] \n", - " massaction: k_f(rna[cellular_processes],protein[RNAase(machinery)])=500*rna[cellular_processes]*protein[RNAase(machinery)]\n", - " k_r(complex[protein[RNAase]:rna[cellular_processes](machinery)])=50*complex[protein[RNAase]:rna[cellular_processes](machinery)]\n", - "8. complex[protein[RNAase]:rna[cellular_processes](machinery)] --> protein[RNAase(machinery)] \n", - " massaction: k_f(complex[protein[RNAase]:rna[cellular_processes](machinery)])=0.001*complex[protein[RNAase]:rna[cellular_processes](machinery)]\n", - "9. rna[X] --> \n", - " massaction: k_f(rna[X])=0.001*rna[X]\n", - "10. protein[X] --> \n", - " massaction: k_f(protein[X])=0.001*protein[X]\n", - "11. rna[cellular_processes] --> \n", - " massaction: k_f(rna[cellular_processes])=0.001*rna[cellular_processes]\n", - "12. protein[cellular_processes] --> \n", - " massaction: k_f(protein[cellular_processes])=0.001*protein[cellular_processes]\n", + " Species (15) = {0. dna[X], 1. protein[RNAP(machinery)], 2. rna[X], 3. complex[dna[X]:protein[RNAP]], 4. protein[Ribo(machinery)], 5. protein[X], 6. complex[protein[Ribo]:rna[X]], 7. protein[RNAase(machinery)], 8. complex[protein[RNAase]:rna[X]], 9. dna[cellular_processes], 10. rna[cellular_processes], 11. complex[dna[cellular_processes]:protein[RNAP]], 12. protein[cellular_processes], 13. complex[protein[Ribo]:rna[cellular_processes]], 14. complex[protein[RNAase]:rna[cellular_processes]]}\n", + "\n", + "Reactions (22) = [\n", + "0. dna[X]+protein[RNAP(machinery)] <--> complex[dna[X]:protein[RNAP]]\n", + " Kf=k_forward * dna_X * protein_RNAP_machinery\n", + " Kr=k_reverse * complex_dna_X_protein_RNAP_machinery\n", + " k_forward=100.0\n", + " found_key=(mech=None, partid=None, name=kb).\n", + " search_key=(mech=transcription_mm, partid=strong, name=kb).\n", + " k_reverse=0.5\n", + " found_key=(mech=None, partid=strong, name=ku).\n", + " search_key=(mech=transcription_mm, partid=strong, name=ku).\n", + "\n", + "1. complex[dna[X]:protein[RNAP]] --> dna[X]+rna[X]+protein[RNAP(machinery)]\n", + " Kf=k_forward * complex_dna_X_protein_RNAP_machinery\n", + " k_forward=3.926187672\n", + " found_key=(mech=None, partid=strong, name=ktx).\n", + " search_key=(mech=transcription_mm, partid=strong, name=ktx).\n", + "\n", + "2. rna[X]+protein[Ribo(machinery)] <--> complex[protein[Ribo]:rna[X]]\n", + " Kf=k_forward * rna_X * protein_Ribo_machinery\n", + " Kr=k_reverse * complex_protein_Ribo_machinery_rna_X\n", + " k_forward=100.0\n", + " found_key=(mech=None, partid=None, name=kb).\n", + " search_key=(mech=translation_mm, partid=weak, name=kb).\n", + " k_reverse=5.0\n", + " found_key=(mech=None, partid=weak, name=ku).\n", + " search_key=(mech=translation_mm, partid=weak, name=ku).\n", + "\n", + "3. complex[protein[Ribo]:rna[X]] --> rna[X]+protein[X]+protein[Ribo(machinery)]\n", + " Kf=k_forward * complex_protein_Ribo_machinery_rna_X\n", + " k_forward=0.05\n", + " found_key=(mech=None, partid=None, name=ktl).\n", + " search_key=(mech=translation_mm, partid=weak, name=ktl).\n", + "\n", + "4. rna[X]+protein[RNAase(machinery)] <--> complex[protein[RNAase]:rna[X]]\n", + " Kf=k_forward * rna_X * protein_RNAase_machinery\n", + " Kr=k_reverse * complex_protein_RNAase_machinery_rna_X\n", + " k_forward=100.0\n", + " found_key=(mech=None, partid=None, name=kb).\n", + " search_key=(mech=rna_degredation_mm, partid=X, name=kb).\n", + " k_reverse=10.0\n", + " found_key=(mech=None, partid=None, name=ku).\n", + " search_key=(mech=rna_degredation_mm, partid=X, name=ku).\n", + "\n", + "5. complex[protein[RNAase]:rna[X]] --> protein[RNAase(machinery)]\n", + " Kf=k_forward * complex_protein_RNAase_machinery_rna_X\n", + " k_forward=0.001\n", + " found_key=(mech=rna_degredation_mm, partid=None, name=kdeg).\n", + " search_key=(mech=rna_degredation_mm, partid=X, name=kdeg).\n", + "\n", + "6. dna[cellular_processes]+protein[RNAP(machinery)] <--> complex[dna[cellular_processes]:protein[RNAP]]\n", + " Kf=k_forward * dna_cellular_processes * protein_RNAP_machinery\n", + " Kr=k_reverse * complex_dna_cellular_processes_protein_RNAP_machinery\n", + " k_forward=500\n", + " found_key=(mech=transcription, partid=None, name=kb).\n", + " search_key=(mech=transcription_mm, partid=average_promoter, name=kb).\n", + " k_reverse=50\n", + " found_key=(mech=transcription, partid=None, name=ku).\n", + " search_key=(mech=transcription_mm, partid=average_promoter, name=ku).\n", + "\n", + "7. complex[dna[cellular_processes]:protein[RNAP]] --> dna[cellular_processes]+rna[cellular_processes]+protein[RNAP(machinery)]\n", + " Kf=k_forward * complex_dna_cellular_processes_protein_RNAP_machinery\n", + " k_forward=0.1\n", + " found_key=(mech=transcription, partid=None, name=ktx).\n", + " search_key=(mech=transcription_mm, partid=average_promoter, name=ktx).\n", + "\n", + "8. rna[cellular_processes]+protein[Ribo(machinery)] <--> complex[protein[Ribo]:rna[cellular_processes]]\n", + " Kf=k_forward * rna_cellular_processes * protein_Ribo_machinery\n", + " Kr=k_reverse * complex_protein_Ribo_machinery_rna_cellular_processes\n", + " k_forward=500\n", + " found_key=(mech=translation, partid=None, name=kb).\n", + " search_key=(mech=translation_mm, partid=average_rbs, name=kb).\n", + " k_reverse=5\n", + " found_key=(mech=translation, partid=None, name=ku).\n", + " search_key=(mech=translation_mm, partid=average_rbs, name=ku).\n", + "\n", + "9. complex[protein[Ribo]:rna[cellular_processes]] --> rna[cellular_processes]+protein[cellular_processes]+protein[Ribo(machinery)]\n", + " Kf=k_forward * complex_protein_Ribo_machinery_rna_cellular_processes\n", + " k_forward=0.1\n", + " found_key=(mech=translation, partid=None, name=ktl).\n", + " search_key=(mech=translation_mm, partid=average_rbs, name=ktl).\n", + "\n", + "10. rna[cellular_processes]+protein[RNAase(machinery)] <--> complex[protein[RNAase]:rna[cellular_processes]]\n", + " Kf=k_forward * rna_cellular_processes * protein_RNAase_machinery\n", + " Kr=k_reverse * complex_protein_RNAase_machinery_rna_cellular_processes\n", + " k_forward=500\n", + " found_key=(mech=rna_degredation, partid=None, name=kb).\n", + " search_key=(mech=rna_degredation_mm, partid=cellular_processes, name=kb).\n", + " k_reverse=50\n", + " found_key=(mech=rna_degredation, partid=None, name=ku).\n", + " search_key=(mech=rna_degredation_mm, partid=cellular_processes, name=ku).\n", + "\n", + "11. complex[protein[RNAase]:rna[cellular_processes]] --> protein[RNAase(machinery)]\n", + " Kf=k_forward * complex_protein_RNAase_machinery_rna_cellular_processes\n", + " k_forward=0.1\n", + " found_key=(mech=rna_degredation, partid=None, name=kdeg).\n", + " search_key=(mech=rna_degredation_mm, partid=cellular_processes, name=kdeg).\n", + "\n", + "12. rna[X] --> \n", + " Kf=k_forward * rna_X\n", + " k_forward=0.001\n", + " found_key=(mech=None, partid=None, name=kdil).\n", + " search_key=(mech=global_degredation_via_dilution, partid=rna_X, name=kdil).\n", + "\n", + "13. rna[X] --> \n", + " Kf=k_forward * rna_X\n", + " k_forward=0.001\n", + " found_key=(mech=None, partid=None, name=kdil).\n", + " search_key=(mech=global_degredation_via_dilution, partid=rna_X, name=kdil).\n", + "\n", + "14. protein[X] --> \n", + " Kf=k_forward * protein_X\n", + " k_forward=0.001\n", + " found_key=(mech=None, partid=None, name=kdil).\n", + " search_key=(mech=global_degredation_via_dilution, partid=protein_X, name=kdil).\n", + "\n", + "15. rna[X] --> \n", + " Kf=k_forward * rna_X\n", + " k_forward=0.001\n", + " found_key=(mech=None, partid=None, name=kdil).\n", + " search_key=(mech=global_degredation_via_dilution, partid=rna_X, name=kdil).\n", + "\n", + "16. rna[X] --> \n", + " Kf=k_forward * rna_X\n", + " k_forward=0.001\n", + " found_key=(mech=None, partid=None, name=kdil).\n", + " search_key=(mech=global_degredation_via_dilution, partid=rna_X, name=kdil).\n", + "\n", + "17. rna[cellular_processes] --> \n", + " Kf=k_forward * rna_cellular_processes\n", + " k_forward=0.001\n", + " found_key=(mech=None, partid=None, name=kdil).\n", + " search_key=(mech=global_degredation_via_dilution, partid=rna_cellular_processes, name=kdil).\n", + "\n", + "18. rna[cellular_processes] --> \n", + " Kf=k_forward * rna_cellular_processes\n", + " k_forward=0.001\n", + " found_key=(mech=None, partid=None, name=kdil).\n", + " search_key=(mech=global_degredation_via_dilution, partid=rna_cellular_processes, name=kdil).\n", + "\n", + "19. protein[cellular_processes] --> \n", + " Kf=k_forward * protein_cellular_processes\n", + " k_forward=0.001\n", + " found_key=(mech=None, partid=None, name=kdil).\n", + " search_key=(mech=global_degredation_via_dilution, partid=protein_cellular_processes, name=kdil).\n", + "\n", + "20. rna[cellular_processes] --> \n", + " Kf=k_forward * rna_cellular_processes\n", + " k_forward=0.001\n", + " found_key=(mech=None, partid=None, name=kdil).\n", + " search_key=(mech=global_degredation_via_dilution, partid=rna_cellular_processes, name=kdil).\n", + "\n", + "21. rna[cellular_processes] --> \n", + " Kf=k_forward * rna_cellular_processes\n", + " k_forward=0.001\n", + " found_key=(mech=None, partid=None, name=kdil).\n", + " search_key=(mech=global_degredation_via_dilution, partid=rna_cellular_processes, name=kdil).\n", + "\n", "] \n", "\n", "\n" @@ -210,17 +391,22 @@ "#Promoter Names: strong, medium, weak correspond to bicistronic RBSs: BCD2, BCD8 and BCD12\n", "#RBS Names: strong, medium, Weak correspond to Anderson Promoters: J23100, J23106, and J23103\n", "G = DNAassembly(\"X\", promoter = \"strong\", rbs = \"weak\", transcript = None, protein = None)\n", + "#Also notice that the names of transcript and protein can be changed, or set to Species.\n", "\n", "#Compare the Following Mixtures and Resulting CRNs\n", "M1 = ExpressionDilutionMixture(\"ExpressionDilution\", components = [G], parameter_file = \"default_parameters.txt\")\n", "CRN1 = M1.compile_crn()\n", "print(repr(M1),\"\\n\", CRN1.pretty_print(show_attributes = True, show_material = True, show_rates = True),\"\\n\\n\")\n", "\n", + "#Components should be reinstantiated before passing them into a new Mixture\n", + "G = DNAassembly(\"X\", promoter = \"strong\", rbs = \"weak\", transcript = None, protein = None)\n", "M2 = SimpleTxTlDilutionMixture(\"SimpleTxTl\", components = [G], parameter_file = \"default_parameters.txt\")\n", "CRN2 = M2.compile_crn()\n", "print(repr(M2),\"\\n\", CRN2.pretty_print(show_attributes = True, show_material = True, show_rates = True),\"\\n\\n\")\n", "\n", + "G = DNAassembly(\"X\", promoter = \"strong\", rbs = \"weak\", transcript = None, protein = None)\n", "M3 = TxTlDilutionMixture(\"e coli\", components = [G], parameter_file = \"default_parameters.txt\")\n", + "\n", "CRN3 = M3.compile_crn()\n", "print(repr(M3),\"\\n\", CRN3.pretty_print(show_attributes = True, show_material = True, show_rates = True),\"\\n\\n\")\n" ] @@ -250,11 +436,10 @@ }, { "cell_type": "code", - "execution_count": 7, + "execution_count": 3, "metadata": {}, "outputs": [ { - "name": "stdout", "output_type": "stream", "text": [ "ExpressionExtract: ExpressionExtract\n", @@ -264,17 +449,16 @@ "\ttranscription:gene_expression\n", "\ttranslation:dummy_translation\n", "\tcatalysis:basic_catalysis\n", - "\tbinding:one_step_binding }\n", - "Global Mechanisms = { } \n", - " Species (4) = {0. complex[protein[RNAase]:protein[X](machinery)], 1. dna[X], 2. protein[RNAase(machinery)], 3. protein[X]}\n", - "Reactions (3) = [\n", - "0. complex[protein[RNAase]:protein[X](machinery)] --> protein[RNAase(machinery)] \n", - " massaction: k_f(complex[protein[RNAase]:protein[X](machinery)])=0.001*complex[protein[RNAase]:protein[X](machinery)]\n", - "1. dna[X] --> dna[X] + protein[X] \n", - " massaction: k_f(dna[X])=0.28125*dna[X]\n", - "2. protein[X] + protein[RNAase(machinery)] <--> complex[protein[RNAase]:protein[X](machinery)] \n", - " massaction: k_f(protein[X],protein[RNAase(machinery)])=100.0*protein[X]*protein[RNAase(machinery)]\n", - " k_r(complex[protein[RNAase]:protein[X](machinery)])=10.0*complex[protein[RNAase]:protein[X](machinery)]\n", + "\tbinding:one_step_binding } \n", + " Species (2) = {0. dna[X], 1. protein[X]}\n", + "\n", + "Reactions (1) = [\n", + "0. dna[X] --> dna[X]+protein[X]\n", + " Kf=k_forward * dna_X\n", + " k_forward=0.28125\n", + " found_key=(mech=gene_expression, partid=None, name=kexpress).\n", + " search_key=(mech=gene_expression, partid=strong, name=kexpress).\n", + "\n", "] \n", "\n", "\n", @@ -283,23 +467,38 @@ "\tDNAassembly: X ]\n", "Mechanisms = {\n", "\ttranscription:simple_transcription\n", + "\ttranslation:simple_translation\n", "\tcatalysis:basic_catalysis\n", "\tbinding:one_step_binding }\n", "Global Mechanisms = {\n", "\trna_degredation:rna_degredation } \n", - " Species (5) = {0. dna[X], 1. rna[X], 2. protein[RNAase(machinery)], 3. protein[X], 4. complex[protein[RNAase]:rna[X](machinery)]}\n", - "Reactions (5) = [\n", - "0. dna[X] --> dna[X] + protein[X] \n", - " massaction: k_f(dna[X])=0.28125*dna[X]\n", - "1. rna[X] + protein[RNAase(machinery)] <--> complex[protein[RNAase]:rna[X](machinery)] \n", - " massaction: k_f(rna[X],protein[RNAase(machinery)])=100.0*rna[X]*protein[RNAase(machinery)]\n", - " k_r(complex[protein[RNAase]:rna[X](machinery)])=10.0*complex[protein[RNAase]:rna[X](machinery)]\n", - "2. complex[protein[RNAase]:rna[X](machinery)] --> protein[RNAase(machinery)] \n", - " massaction: k_f(complex[protein[RNAase]:rna[X](machinery)])=0.001*complex[protein[RNAase]:rna[X](machinery)]\n", - "3. rna[X] --> \n", - " massaction: k_f(rna[X])=0.001*rna[X]\n", - "4. complex[protein[RNAase]:rna[X](machinery)] --> \n", - " massaction: k_f(complex[protein[RNAase]:rna[X](machinery)])=0.001*complex[protein[RNAase]:rna[X](machinery)]\n", + " Species (3) = {0. dna[X], 1. rna[X], 2. protein[X]}\n", + "\n", + "Reactions (4) = [\n", + "0. dna[X] --> dna[X]+rna[X]\n", + " Kf=k_forward * dna_X\n", + " k_forward=0.4775625\n", + " found_key=(mech=simple_transcription, partid=strong, name=ktx).\n", + " search_key=(mech=simple_transcription, partid=strong, name=ktx).\n", + "\n", + "1. rna[X] --> rna[X]+protein[X]\n", + " Kf=k_forward * rna_X\n", + " k_forward=0.06\n", + " found_key=(mech=simple_translation, partid=weak, name=ktl).\n", + " search_key=(mech=simple_translation, partid=weak, name=ktl).\n", + "\n", + "2. rna[X] --> \n", + " Kf=k_forward * rna_X\n", + " k_forward=0.001\n", + " found_key=(mech=rna_degredation, partid=None, name=kdil).\n", + " search_key=(mech=rna_degredation, partid=rna_X, name=kdil).\n", + "\n", + "3. rna[X] --> \n", + " Kf=k_forward * rna_X\n", + " k_forward=0.001\n", + " found_key=(mech=rna_degredation, partid=None, name=kdil).\n", + " search_key=(mech=rna_degredation, partid=rna_X, name=kdil).\n", + "\n", "] \n", "\n", "\n", @@ -314,17 +513,58 @@ "\ttranslation:translation_mm\n", "\trna_degredation:rna_degredation_mm\n", "\tcatalysis:michalis_menten\n", - "\tbinding:one_step_binding }\n", - "Global Mechanisms = { } \n", - " Species (7) = {0. dna[X], 1. rna[X], 2. complex[protein[RNAase]:rna[X]], 3. protein[RNAase], 4. protein[X], 5. protein[RNAP], 6. protein[Ribo]}\n", - "Reactions (3) = [\n", - "0. dna[X] --> dna[X] + protein[X] \n", - " massaction: k_f(dna[X])=0.28125*dna[X]\n", - "1. rna[X] + protein[RNAase] <--> complex[protein[RNAase]:rna[X]] \n", - " massaction: k_f(rna[X],protein[RNAase])=100.0*rna[X]*protein[RNAase]\n", - " k_r(complex[protein[RNAase]:rna[X]])=10.0*complex[protein[RNAase]:rna[X]]\n", - "2. complex[protein[RNAase]:rna[X]] --> protein[RNAase] \n", - " massaction: k_f(complex[protein[RNAase]:rna[X]])=0.001*complex[protein[RNAase]:rna[X]]\n", + "\tbinding:one_step_binding } \n", + " Species (9) = {0. dna[X], 1. protein[RNAP], 2. rna[X], 3. complex[dna[X]:protein[RNAP]], 4. protein[Ribo], 5. protein[X], 6. complex[protein[Ribo]:rna[X]], 7. protein[RNAase], 8. complex[protein[RNAase]:rna[X]]}\n", + "\n", + "Reactions (6) = [\n", + "0. dna[X]+protein[RNAP] <--> complex[dna[X]:protein[RNAP]]\n", + " Kf=k_forward * dna_X * protein_RNAP\n", + " Kr=k_reverse * complex_dna_X_protein_RNAP\n", + " k_forward=100.0\n", + " found_key=(mech=None, partid=None, name=kb).\n", + " search_key=(mech=transcription_mm, partid=strong, name=kb).\n", + " k_reverse=0.5\n", + " found_key=(mech=None, partid=strong, name=ku).\n", + " search_key=(mech=transcription_mm, partid=strong, name=ku).\n", + "\n", + "1. complex[dna[X]:protein[RNAP]] --> dna[X]+rna[X]+protein[RNAP]\n", + " Kf=k_forward * complex_dna_X_protein_RNAP\n", + " k_forward=3.926187672\n", + " found_key=(mech=None, partid=strong, name=ktx).\n", + " search_key=(mech=transcription_mm, partid=strong, name=ktx).\n", + "\n", + "2. rna[X]+protein[Ribo] <--> complex[protein[Ribo]:rna[X]]\n", + " Kf=k_forward * rna_X * protein_Ribo\n", + " Kr=k_reverse * complex_protein_Ribo_rna_X\n", + " k_forward=100.0\n", + " found_key=(mech=None, partid=None, name=kb).\n", + " search_key=(mech=translation_mm, partid=weak, name=kb).\n", + " k_reverse=5.0\n", + " found_key=(mech=None, partid=weak, name=ku).\n", + " search_key=(mech=translation_mm, partid=weak, name=ku).\n", + "\n", + "3. complex[protein[Ribo]:rna[X]] --> rna[X]+protein[X]+protein[Ribo]\n", + " Kf=k_forward * complex_protein_Ribo_rna_X\n", + " k_forward=0.05\n", + " found_key=(mech=None, partid=None, name=ktl).\n", + " search_key=(mech=translation_mm, partid=weak, name=ktl).\n", + "\n", + "4. rna[X]+protein[RNAase] <--> complex[protein[RNAase]:rna[X]]\n", + " Kf=k_forward * rna_X * protein_RNAase\n", + " Kr=k_reverse * complex_protein_RNAase_rna_X\n", + " k_forward=100.0\n", + " found_key=(mech=None, partid=None, name=kb).\n", + " search_key=(mech=rna_degredation_mm, partid=X, name=kb).\n", + " k_reverse=10.0\n", + " found_key=(mech=None, partid=None, name=ku).\n", + " search_key=(mech=rna_degredation_mm, partid=X, name=ku).\n", + "\n", + "5. complex[protein[RNAase]:rna[X]] --> protein[RNAase]\n", + " Kf=k_forward * complex_protein_RNAase_rna_X\n", + " k_forward=0.001\n", + " found_key=(mech=rna_degredation_mm, partid=None, name=kdeg).\n", + " search_key=(mech=rna_degredation_mm, partid=X, name=kdeg).\n", + "\n", "] \n", "\n", "\n" @@ -333,14 +573,19 @@ ], "source": [ "#Compare the Following Mixtures and Resulting CRNs\n", + "\n", + "#Components should be reinstantiated before passing them into a new Mixture\n", + "G = DNAassembly(\"X\", promoter = \"strong\", rbs = \"weak\", transcript = None, protein = None)\n", "M1 = ExpressionExtract(\"ExpressionExtract\", components = [G], parameter_file = \"default_parameters.txt\")\n", "CRN1 = M1.compile_crn()\n", "print(repr(M1),\"\\n\", CRN1.pretty_print(show_attributes = True, show_material = True, show_rates = True),\"\\n\\n\")\n", "\n", + "G = DNAassembly(\"X\", promoter = \"strong\", rbs = \"weak\", transcript = None, protein = None)\n", "M2 = SimpleTxTlExtract(\"SimpleTxTlExtract\", components = [G], parameter_file = \"default_parameters.txt\")\n", "CRN2 = M2.compile_crn()\n", "print(repr(M2),\"\\n\", CRN2.pretty_print(show_attributes = True, show_material = True, show_rates = True),\"\\n\\n\")\n", "\n", + "G = DNAassembly(\"X\", promoter = \"strong\", rbs = \"weak\", transcript = None, protein = None)\n", "M3 = TxTlExtract(\"e coli extract\", components = [G], parameter_file = \"default_parameters.txt\")\n", "CRN3 = M3.compile_crn()\n", "print(repr(M3),\"\\n\", CRN3.pretty_print(show_attributes = True, show_material = True, show_rates = True),\"\\n\\n\")\n" @@ -372,7 +617,7 @@ }, { "cell_type": "code", - "execution_count": 8, + "execution_count": 4, "metadata": {}, "outputs": [ { @@ -381,73 +626,139 @@ "text": [ "\n", "pretty_print gives a nicely formatted repesentation of the CRNS, reactions, and species. The names of species are formatted for clarity, but are not the actual species representations. Additionally a number of printing options are available. \n", - " Species (30) = {0. complex[dna[ref]:protein[RNAP]], 1. rna[ref], 2. complex[protein[Ribo]:rna[ref]], 3. complex[protein[RNAase]:rna[ref]], 4. protein[RNAase], 5. dna[ref], 6. protein[RNAP], 7. protein[Ribo], 8. protein[ref], 9. complex[protein[RNAase]:rna[Load]], 10. complex[protein[Ribo]:rna[Load]], 11. protein[Load], 12. dna[Load], 13. rna[Load], 14. complex[dna[Load]:protein[RNAP]], 15. complex[protein[Ribo]:rna[T7Load]], 16. protein[T7Load], 17. rna[T7Load], 18. protein[T7], 19. dna[T7Load], 20. complex[protein[RNAase]:rna[T7Load]], 21. complex[dna[T7Load]:protein[T7]], 22. complex[protein[RNAase]:rna[TxLoad]], 23. complex[dna[TxLoad]:protein[RNAP]], 24. dna[TxLoad], 25. rna[TxLoad], 26. complex[dna[T7TxLoad]:protein[T7]], 27. dna[T7TxLoad], 28. complex[protein[RNAase]:rna[T7TxLoad]], 29. rna[T7TxLoad]}\n", + " Species (30) = {0. dna[ref], 1. protein[RNAP], 2. rna[ref], 3. complex[dna[ref]:protein[RNAP]], 4. protein[Ribo], 5. protein[ref], 6. complex[protein[Ribo]:rna[ref]], 7. protein[RNAase], 8. complex[protein[RNAase]:rna[ref]], 9. dna[Load], 10. rna[Load], 11. complex[dna[Load]:protein[RNAP]], 12. protein[Load], 13. complex[protein[Ribo]:rna[Load]], 14. complex[protein[RNAase]:rna[Load]], 15. dna[T7Load], 16. protein[T7], 17. rna[T7Load], 18. complex[dna[T7Load]:protein[T7]], 19. protein[T7Load], 20. complex[protein[Ribo]:rna[T7Load]], 21. complex[protein[RNAase]:rna[T7Load]], 22. dna[TxLoad], 23. rna[TxLoad], 24. complex[dna[TxLoad]:protein[RNAP]], 25. complex[protein[RNAase]:rna[TxLoad]], 26. dna[T7TxLoad], 27. rna[T7TxLoad], 28. complex[dna[T7TxLoad]:protein[T7]], 29. complex[protein[RNAase]:rna[T7TxLoad]]}\n", + "\n", "Reactions (26) = [\n", - "0. dna[ref] + protein[RNAP] <--> complex[dna[ref]:protein[RNAP]] \n", - " massaction: k_f(dna[ref],protein[RNAP])=100*dna[ref]*protein[RNAP]\n", - " k_r(complex[dna[ref]:protein[RNAP]])=10*complex[dna[ref]:protein[RNAP]]\n", - "1. complex[dna[ref]:protein[RNAP]] --> dna[ref] + rna[ref] + protein[RNAP] \n", - " massaction: k_f(complex[dna[ref]:protein[RNAP]])=3.0*complex[dna[ref]:protein[RNAP]]\n", - "2. rna[ref] + protein[Ribo] <--> complex[protein[Ribo]:rna[ref]] \n", - " massaction: k_f(rna[ref],protein[Ribo])=100*rna[ref]*protein[Ribo]\n", - " k_r(complex[protein[Ribo]:rna[ref]])=10*complex[protein[Ribo]:rna[ref]]\n", - "3. complex[protein[Ribo]:rna[ref]] --> rna[ref] + protein[ref] + protein[Ribo] \n", - " massaction: k_f(complex[protein[Ribo]:rna[ref]])=5.0*complex[protein[Ribo]:rna[ref]]\n", - "4. rna[ref] + protein[RNAase] <--> complex[protein[RNAase]:rna[ref]] \n", - " massaction: k_f(rna[ref],protein[RNAase])=100*rna[ref]*protein[RNAase]\n", - " k_r(complex[protein[RNAase]:rna[ref]])=10*complex[protein[RNAase]:rna[ref]]\n", - "5. complex[protein[RNAase]:rna[ref]] --> protein[RNAase] \n", - " massaction: k_f(complex[protein[RNAase]:rna[ref]])=2*complex[protein[RNAase]:rna[ref]]\n", - "6. dna[Load] + protein[RNAP] <--> complex[dna[Load]:protein[RNAP]] \n", - " massaction: k_f(dna[Load],protein[RNAP])=100*dna[Load]*protein[RNAP]\n", - " k_r(complex[dna[Load]:protein[RNAP]])=10*complex[dna[Load]:protein[RNAP]]\n", - "7. complex[dna[Load]:protein[RNAP]] --> dna[Load] + rna[Load] + protein[RNAP] \n", - " massaction: k_f(complex[dna[Load]:protein[RNAP]])=3.0*complex[dna[Load]:protein[RNAP]]\n", - "8. rna[Load] + protein[Ribo] <--> complex[protein[Ribo]:rna[Load]] \n", - " massaction: k_f(rna[Load],protein[Ribo])=100*rna[Load]*protein[Ribo]\n", - " k_r(complex[protein[Ribo]:rna[Load]])=10*complex[protein[Ribo]:rna[Load]]\n", - "9. complex[protein[Ribo]:rna[Load]] --> rna[Load] + protein[Load] + protein[Ribo] \n", - " massaction: k_f(complex[protein[Ribo]:rna[Load]])=5.0*complex[protein[Ribo]:rna[Load]]\n", - "10. rna[Load] + protein[RNAase] <--> complex[protein[RNAase]:rna[Load]] \n", - " massaction: k_f(rna[Load],protein[RNAase])=100*rna[Load]*protein[RNAase]\n", - " k_r(complex[protein[RNAase]:rna[Load]])=10*complex[protein[RNAase]:rna[Load]]\n", - "11. complex[protein[RNAase]:rna[Load]] --> protein[RNAase] \n", - " massaction: k_f(complex[protein[RNAase]:rna[Load]])=2*complex[protein[RNAase]:rna[Load]]\n", - "12. dna[T7Load] + protein[T7] <--> complex[dna[T7Load]:protein[T7]] \n", - " massaction: k_f(dna[T7Load],protein[T7])=100*dna[T7Load]*protein[T7]\n", - " k_r(complex[dna[T7Load]:protein[T7]])=10*complex[dna[T7Load]:protein[T7]]\n", - "13. complex[dna[T7Load]:protein[T7]] --> dna[T7Load] + rna[T7Load] + protein[T7] \n", - " massaction: k_f(complex[dna[T7Load]:protein[T7]])=3.0*complex[dna[T7Load]:protein[T7]]\n", - "14. rna[T7Load] + protein[Ribo] <--> complex[protein[Ribo]:rna[T7Load]] \n", - " massaction: k_f(rna[T7Load],protein[Ribo])=100*rna[T7Load]*protein[Ribo]\n", - " k_r(complex[protein[Ribo]:rna[T7Load]])=10*complex[protein[Ribo]:rna[T7Load]]\n", - "15. complex[protein[Ribo]:rna[T7Load]] --> rna[T7Load] + protein[T7Load] + protein[Ribo] \n", - " massaction: k_f(complex[protein[Ribo]:rna[T7Load]])=5.0*complex[protein[Ribo]:rna[T7Load]]\n", - "16. rna[T7Load] + protein[RNAase] <--> complex[protein[RNAase]:rna[T7Load]] \n", - " massaction: k_f(rna[T7Load],protein[RNAase])=100*rna[T7Load]*protein[RNAase]\n", - " k_r(complex[protein[RNAase]:rna[T7Load]])=10*complex[protein[RNAase]:rna[T7Load]]\n", - "17. complex[protein[RNAase]:rna[T7Load]] --> protein[RNAase] \n", - " massaction: k_f(complex[protein[RNAase]:rna[T7Load]])=2*complex[protein[RNAase]:rna[T7Load]]\n", - "18. dna[TxLoad] + protein[RNAP] <--> complex[dna[TxLoad]:protein[RNAP]] \n", - " massaction: k_f(dna[TxLoad],protein[RNAP])=100*dna[TxLoad]*protein[RNAP]\n", - " k_r(complex[dna[TxLoad]:protein[RNAP]])=10*complex[dna[TxLoad]:protein[RNAP]]\n", - "19. complex[dna[TxLoad]:protein[RNAP]] --> dna[TxLoad] + rna[TxLoad] + protein[RNAP] \n", - " massaction: k_f(complex[dna[TxLoad]:protein[RNAP]])=3.0*complex[dna[TxLoad]:protein[RNAP]]\n", - "20. rna[TxLoad] + protein[RNAase] <--> complex[protein[RNAase]:rna[TxLoad]] \n", - " massaction: k_f(rna[TxLoad],protein[RNAase])=100*rna[TxLoad]*protein[RNAase]\n", - " k_r(complex[protein[RNAase]:rna[TxLoad]])=10*complex[protein[RNAase]:rna[TxLoad]]\n", - "21. complex[protein[RNAase]:rna[TxLoad]] --> protein[RNAase] \n", - " massaction: k_f(complex[protein[RNAase]:rna[TxLoad]])=2*complex[protein[RNAase]:rna[TxLoad]]\n", - "22. dna[T7TxLoad] + protein[T7] <--> complex[dna[T7TxLoad]:protein[T7]] \n", - " massaction: k_f(dna[T7TxLoad],protein[T7])=100*dna[T7TxLoad]*protein[T7]\n", - " k_r(complex[dna[T7TxLoad]:protein[T7]])=10*complex[dna[T7TxLoad]:protein[T7]]\n", - "23. complex[dna[T7TxLoad]:protein[T7]] --> dna[T7TxLoad] + rna[T7TxLoad] + protein[T7] \n", - " massaction: k_f(complex[dna[T7TxLoad]:protein[T7]])=3.0*complex[dna[T7TxLoad]:protein[T7]]\n", - "24. rna[T7TxLoad] + protein[RNAase] <--> complex[protein[RNAase]:rna[T7TxLoad]] \n", - " massaction: k_f(rna[T7TxLoad],protein[RNAase])=100*rna[T7TxLoad]*protein[RNAase]\n", - " k_r(complex[protein[RNAase]:rna[T7TxLoad]])=10*complex[protein[RNAase]:rna[T7TxLoad]]\n", - "25. complex[protein[RNAase]:rna[T7TxLoad]] --> protein[RNAase] \n", - " massaction: k_f(complex[protein[RNAase]:rna[T7TxLoad]])=2*complex[protein[RNAase]:rna[T7TxLoad]]\n", + "0. dna[ref]+protein[RNAP] <--> complex[dna[ref]:protein[RNAP]]\n", + " Kf=k_forward * dna_ref * protein_RNAP\n", + " Kr=k_reverse * complex_dna_ref_protein_RNAP\n", + " k_forward=100\n", + " k_reverse=10\n", + "\n", + "1. complex[dna[ref]:protein[RNAP]] --> dna[ref]+rna[ref]+protein[RNAP]\n", + " Kf=k_forward * complex_dna_ref_protein_RNAP\n", + " k_forward=3.0\n", + "\n", + "2. rna[ref]+protein[Ribo] <--> complex[protein[Ribo]:rna[ref]]\n", + " Kf=k_forward * rna_ref * protein_Ribo\n", + " Kr=k_reverse * complex_protein_Ribo_rna_ref\n", + " k_forward=100\n", + " k_reverse=10\n", + "\n", + "3. complex[protein[Ribo]:rna[ref]] --> rna[ref]+protein[ref]+protein[Ribo]\n", + " Kf=k_forward * complex_protein_Ribo_rna_ref\n", + " k_forward=5.0\n", + "\n", + "4. rna[ref]+protein[RNAase] <--> complex[protein[RNAase]:rna[ref]]\n", + " Kf=k_forward * rna_ref * protein_RNAase\n", + " Kr=k_reverse * complex_protein_RNAase_rna_ref\n", + " k_forward=100\n", + " k_reverse=10\n", + "\n", + "5. complex[protein[RNAase]:rna[ref]] --> protein[RNAase]\n", + " Kf=k_forward * complex_protein_RNAase_rna_ref\n", + " k_forward=2\n", + "\n", + "6. dna[Load]+protein[RNAP] <--> complex[dna[Load]:protein[RNAP]]\n", + " Kf=k_forward * dna_Load * protein_RNAP\n", + " Kr=k_reverse * complex_dna_Load_protein_RNAP\n", + " k_forward=100\n", + " k_reverse=10\n", + "\n", + "7. complex[dna[Load]:protein[RNAP]] --> dna[Load]+rna[Load]+protein[RNAP]\n", + " Kf=k_forward * complex_dna_Load_protein_RNAP\n", + " k_forward=3.0\n", + "\n", + "8. rna[Load]+protein[Ribo] <--> complex[protein[Ribo]:rna[Load]]\n", + " Kf=k_forward * rna_Load * protein_Ribo\n", + " Kr=k_reverse * complex_protein_Ribo_rna_Load\n", + " k_forward=100\n", + " k_reverse=10\n", + "\n", + "9. complex[protein[Ribo]:rna[Load]] --> rna[Load]+protein[Load]+protein[Ribo]\n", + " Kf=k_forward * complex_protein_Ribo_rna_Load\n", + " k_forward=5.0\n", + "\n", + "10. rna[Load]+protein[RNAase] <--> complex[protein[RNAase]:rna[Load]]\n", + " Kf=k_forward * rna_Load * protein_RNAase\n", + " Kr=k_reverse * complex_protein_RNAase_rna_Load\n", + " k_forward=100\n", + " k_reverse=10\n", + "\n", + "11. complex[protein[RNAase]:rna[Load]] --> protein[RNAase]\n", + " Kf=k_forward * complex_protein_RNAase_rna_Load\n", + " k_forward=2\n", + "\n", + "12. dna[T7Load]+protein[T7] <--> complex[dna[T7Load]:protein[T7]]\n", + " Kf=k_forward * dna_T7Load * protein_T7\n", + " Kr=k_reverse * complex_dna_T7Load_protein_T7\n", + " k_forward=100\n", + " k_reverse=10\n", + "\n", + "13. complex[dna[T7Load]:protein[T7]] --> dna[T7Load]+rna[T7Load]+protein[T7]\n", + " Kf=k_forward * complex_dna_T7Load_protein_T7\n", + " k_forward=3.0\n", + "\n", + "14. rna[T7Load]+protein[Ribo] <--> complex[protein[Ribo]:rna[T7Load]]\n", + " Kf=k_forward * rna_T7Load * protein_Ribo\n", + " Kr=k_reverse * complex_protein_Ribo_rna_T7Load\n", + " k_forward=100\n", + " k_reverse=10\n", + "\n", + "15. complex[protein[Ribo]:rna[T7Load]] --> rna[T7Load]+protein[T7Load]+protein[Ribo]\n", + " Kf=k_forward * complex_protein_Ribo_rna_T7Load\n", + " k_forward=5.0\n", + "\n", + "16. rna[T7Load]+protein[RNAase] <--> complex[protein[RNAase]:rna[T7Load]]\n", + " Kf=k_forward * rna_T7Load * protein_RNAase\n", + " Kr=k_reverse * complex_protein_RNAase_rna_T7Load\n", + " k_forward=100\n", + " k_reverse=10\n", + "\n", + "17. complex[protein[RNAase]:rna[T7Load]] --> protein[RNAase]\n", + " Kf=k_forward * complex_protein_RNAase_rna_T7Load\n", + " k_forward=2\n", + "\n", + "18. dna[TxLoad]+protein[RNAP] <--> complex[dna[TxLoad]:protein[RNAP]]\n", + " Kf=k_forward * dna_TxLoad * protein_RNAP\n", + " Kr=k_reverse * complex_dna_TxLoad_protein_RNAP\n", + " k_forward=100\n", + " k_reverse=10\n", + "\n", + "19. complex[dna[TxLoad]:protein[RNAP]] --> dna[TxLoad]+rna[TxLoad]+protein[RNAP]\n", + " Kf=k_forward * complex_dna_TxLoad_protein_RNAP\n", + " k_forward=3.0\n", + "\n", + "20. rna[TxLoad]+protein[RNAase] <--> complex[protein[RNAase]:rna[TxLoad]]\n", + " Kf=k_forward * rna_TxLoad * protein_RNAase\n", + " Kr=k_reverse * complex_protein_RNAase_rna_TxLoad\n", + " k_forward=100\n", + " k_reverse=10\n", + "\n", + "21. complex[protein[RNAase]:rna[TxLoad]] --> protein[RNAase]\n", + " Kf=k_forward * complex_protein_RNAase_rna_TxLoad\n", + " k_forward=2\n", + "\n", + "22. dna[T7TxLoad]+protein[T7] <--> complex[dna[T7TxLoad]:protein[T7]]\n", + " Kf=k_forward * dna_T7TxLoad * protein_T7\n", + " Kr=k_reverse * complex_dna_T7TxLoad_protein_T7\n", + " k_forward=100\n", + " k_reverse=10\n", + "\n", + "23. complex[dna[T7TxLoad]:protein[T7]] --> dna[T7TxLoad]+rna[T7TxLoad]+protein[T7]\n", + " Kf=k_forward * complex_dna_T7TxLoad_protein_T7\n", + " k_forward=3.0\n", + "\n", + "24. rna[T7TxLoad]+protein[RNAase] <--> complex[protein[RNAase]:rna[T7TxLoad]]\n", + " Kf=k_forward * rna_T7TxLoad * protein_RNAase\n", + " Kr=k_reverse * complex_protein_RNAase_rna_T7TxLoad\n", + " k_forward=100\n", + " k_reverse=10\n", + "\n", + "25. complex[protein[RNAase]:rna[T7TxLoad]] --> protein[RNAase]\n", + " Kf=k_forward * complex_protein_RNAase_rna_T7TxLoad\n", + " k_forward=2\n", + "\n", "]\n", "Simulating\n" ] @@ -456,6 +767,10 @@ "name": "stderr", "output_type": "stream", "text": [ + "C:\\ProgramData\\Anaconda3\\lib\\site-packages\\html5lib\\_trie\\_base.py:3: DeprecationWarning: Using or importing the ABCs from 'collections' instead of from 'collections.abc' is deprecated, and in 3.8 it will stop working\n", + " from collections import Mapping\n", + "C:\\ProgramData\\Anaconda3\\lib\\importlib\\_bootstrap.py:219: RuntimeWarning: numpy.ufunc size changed, may indicate binary incompatibility. Expected 192 from C header, got 216 from PyObject\n", + " return f(*args, **kwds)\n", "C:\\ProgramData\\Anaconda3\\lib\\site-packages\\scipy\\integrate\\odepack.py:248: ODEintWarning: Excess work done on this call (perhaps wrong Dfun type). Run with full_output = 1 to get quantitative information.\n", " warnings.warn(warning_msg, ODEintWarning)\n", "odeint failed with mxstep=500...C:\\ProgramData\\Anaconda3\\lib\\site-packages\\scipy\\integrate\\odepack.py:248: ODEintWarning: Excess work done on this call (perhaps wrong Dfun type). Run with full_output = 1 to get quantitative information.\n", @@ -499,7 +814,7 @@ "\n", "#Create a custom promoter with a custom mechanism that uses T7 instead of RNAP\n", "#instantiate a new mechanism Transcription_MM with its own name and overwrote the default parameter rnap\n", - "mechanism_txt7 = Transcription_MM(name = \"T7_transcription_mm\", rnap=T7)\n", + "mechanism_txt7 = Transcription_MM(name = \"T7_transcription_mm\", rnap=T7.get_species())\n", "#Create an instance of a promoter with this mechanism for transcription\n", "T7P = Promoter(\"T7P\", mechanisms={\"transcription\":mechanism_txt7})\n", "#Create A load assembly with the custom T7 promoter\n", @@ -507,24 +822,25 @@ "\n", "#Each new assembly requires its own promoter instance - so here I create another here\n", "T7P = Promoter(\"T7P\", mechanisms={\n", - " \"transcription\":Transcription_MM(name = \"T7_transcription_mm\", rnap=T7)})\n", + " \"transcription\":Transcription_MM(name = \"T7_transcription_mm\", rnap=T7.get_species())})\n", "#A load assembly with the custom T7 promoter and no RBS\n", "T7RNA_load_assembly = DNAassembly(name = \"T7TxLoad\", promoter = T7P, rbs = None)\n", "\n", "#Add all the assemblies to a mixture\n", "components = [reference_assembly, full_load_assembly, T7_load_assembly, T7, RNA_load_assembly, T7RNA_load_assembly]\n", - "myMixture = TxTlExtract(name = \"txtl\", parameters = parameters, components = components, parameter_warnings = False)\n", + "myMixture = TxTlExtract(name = \"txtl\", parameters = parameters, components = components)\n", "\n", "#Print the CRN\n", "myCRN = myMixture.compile_crn()\n", "\n", "#The Species, Reaction, and CRN pretty_print functions return text which has been formated with a number of formatting options\n", "print(\"\\npretty_print gives a nicely formatted repesentation of the CRNS, reactions, and species. The names of species are formatted for clarity, but are not the actual species representations. Additionally a number of printing options are available.\",\n", - " \"\\n\", myCRN.pretty_print(show_material = True, show_rates = True, show_attributes = True))\n", + " \"\\n\", myCRN.pretty_print(show_material = True, show_rates = True, show_attributes = True, show_keys = False))\n", "\n", "#Simulate with BioSCRAPE if installed\n", + "\n", + "print(\"Simulating\")\n", "try:\n", - " print(\"Simulating\")\n", " import numpy as np\n", " import pylab as plt\n", " timepoints = np.arange(0, 3, .01)\n", @@ -538,8 +854,9 @@ " x0_dict = {\"protein_T7\": 10., \"protein_RNAP\":10., \"protein_RNAase\":5.0, \"protein_Ribo\":50.,\n", " 'dna_ref':5., 'dna_Load':dna_Load}\n", "\n", - " results = myCRN.simulate_with_bioscrape(timepoints, x0_dict, stochastic = stochastic)\n", - " plt.plot(timepoints, results[\"protein_ref\"], label = \"Load = \"+str(dna_Load))\n", + " results = myCRN.simulate_with_bioscrape_via_sbml(timepoints, initial_condition_dict = x0_dict, stochastic = stochastic)\n", + " if results is not None:\n", + " plt.plot(timepoints, results[\"protein_ref\"], label = \"Load = \"+str(dna_Load))\n", "\n", " plt.xlim(0, 5)\n", " #plt.xlabel(\"time\")\n", @@ -552,8 +869,9 @@ " #print(\"Simulating for dna_T7Load=\", dna_Load)\n", " x0_dict = {\"protein_T7\": 10., \"protein_RNAP\":10., \"protein_RNAase\":5.0, \"protein_Ribo\":50.,\n", " 'dna_ref':5., 'dna_T7Load':dna_Load}\n", - " results = myCRN.simulate_with_bioscrape(timepoints, x0_dict, stochastic = stochastic)\n", - " plt.plot(timepoints, results[\"protein_ref\"], label=\"Load = \" + str(dna_Load))\n", + " results = myCRN.simulate_with_bioscrape_via_sbml(timepoints, initial_condition_dict = x0_dict, stochastic = stochastic)\n", + " if results is not None:\n", + " plt.plot(timepoints, results[\"protein_ref\"], label=\"Load = \" + str(dna_Load))\n", " plt.xlim(0, 5)\n", " #plt.xlabel(\"time\")\n", " plt.ylabel(\"Reference Protein\")\n", @@ -565,8 +883,9 @@ " #print(\"Simulating for dna_TxLoad=\", dna_Load)\n", " x0_dict = {\"protein_T7\": 10., \"protein_RNAP\":10., \"protein_RNAase\":5.0, \"protein_Ribo\":50.,\n", " 'dna_ref':5., 'dna_TxLoad':dna_Load}\n", - " results = myCRN.simulate_with_bioscrape(timepoints, x0_dict, stochastic = stochastic)\n", - " plt.plot(timepoints, results[\"protein_ref\"], label=\"Load = \" + str(dna_Load))\n", + " results = myCRN.simulate_with_bioscrape_via_sbml(timepoints, initial_condition_dict = x0_dict, stochastic = stochastic)\n", + " if results is not None:\n", + " plt.plot(timepoints, results[\"protein_ref\"], label=\"Load = \" + str(dna_Load))\n", " plt.xlim(0, 5)\n", " plt.xlabel(\"time\")\n", " plt.ylabel(\"Reference Protein\")\n", @@ -578,23 +897,17 @@ " #print(\"Simulating for dna_T7TxLoad=\", dna_Load)\n", " x0_dict = {\"protein_T7\": 10., \"protein_RNAP\":10., \"protein_RNAase\":5.0, \"protein_Ribo\":50.,\n", " 'dna_ref':5., 'dna_T7TxLoad':dna_Load}\n", - " results = myCRN.simulate_with_bioscrape(timepoints, x0_dict, stochastic = stochastic)\n", - " plt.plot(timepoints, results[\"protein_ref\"], label=\"Load = \" + str(dna_Load))\n", + " results = myCRN.simulate_with_bioscrape_via_sbml(timepoints, initial_condition_dict = x0_dict, stochastic = stochastic)\n", + " if results is not None:\n", + " plt.plot(timepoints, results[\"protein_ref\"], label=\"Load = \" + str(dna_Load))\n", " plt.xlim(0, 5)\n", " plt.xlabel(\"time\")\n", " plt.ylabel(\"Reference Protein\")\n", " plt.legend()\n", " plt.show()\n", "except ModuleNotFoundError:\n", - " pass" + " print('please install the plotting libraries: pip install biocrnpyler[all]')\n" ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] } ], "metadata": { @@ -613,9 +926,9 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.7.4" + "version": "3.7.6-final" } }, "nbformat": 4, "nbformat_minor": 4 -} +} \ No newline at end of file diff --git a/examples/4. Promoters, Transcriptional Regulation, and Gene Regulatory Networks.ipynb b/examples/4. Promoters, Transcriptional Regulation, and Gene Regulatory Networks.ipynb index e38697b5..b2105eff 100644 --- a/examples/4. Promoters, Transcriptional Regulation, and Gene Regulatory Networks.ipynb +++ b/examples/4. Promoters, Transcriptional Regulation, and Gene Regulatory Networks.ipynb @@ -47,23 +47,50 @@ }, { "cell_type": "code", - "execution_count": 190, + "execution_count": 15, "metadata": { "slideshow": { "slide_type": "skip" - } + }, + "tags": [] }, "outputs": [ { - "name": "stdout", "output_type": "stream", "text": [ - "Species = dna_activatable_assembly, small_molecule_activator, protein_A, rna_activatable_assembly\n", - "Reactions = [\n", - "\tdna_activatable_assembly --> dna_activatable_assembly + rna_activatable_assembly proportionalhillpositive: k(small_molecule_activator, dna_activatable_assembly)=1.0*dna_activatable_assembly*small_molecule_activator^4/(20+small_molecule_activator^4)\n", - "\tdna_activatable_assembly --> dna_activatable_assembly + rna_activatable_assembly massaction: k_f(dna_activatable_assembly)=0.01*dna_activatable_assembly\n", - "\trna_activatable_assembly --> rna_activatable_assembly + protein_A massaction: k_f(rna_activatable_assembly)=0.25*rna_activatable_assembly\n", - "\trna_activatable_assembly --> massaction: k_f(rna_activatable_assembly)=0.001*rna_activatable_assembly\n", + "Species (4) = {0. dna[activatable_assembly], 1. small_molecule[activator], 2. rna[activatable_assembly], 3. A}\n", + "\n", + "Reactions (5) = [\n", + "0. dna[activatable_assembly] --> dna[activatable_assembly]+rna[activatable_assembly]\n", + " Kf = k dna[activatable_assembly] small_molecule[activator]^n/(small_molecule[activator]^n + K)\n", + " k=1.0\n", + " K=20\n", + " n=4\n", + "\n", + "1. dna[activatable_assembly] --> dna[activatable_assembly]+rna[activatable_assembly]\n", + " Kf=k_forward * dna_activatable_assembly\n", + " k_forward=0.01\n", + " found_key=(mech=None, partid=None, name=kleak).\n", + " search_key=(mech=positivehill_transcription, partid=P_activtable_activator, name=kleak).\n", + "\n", + "2. rna[activatable_assembly] --> rna[activatable_assembly]+A\n", + " Kf=k_forward * rna_activatable_assembly\n", + " k_forward=0.25\n", + " found_key=(mech=simple_translation, partid=None, name=ktl).\n", + " search_key=(mech=simple_translation, partid=Strong, name=ktl).\n", + "\n", + "3. rna[activatable_assembly] --> \n", + " Kf=k_forward * rna_activatable_assembly\n", + " k_forward=0.001\n", + " found_key=(mech=rna_degredation, partid=None, name=kdil).\n", + " search_key=(mech=rna_degredation, partid=rna_activatable_assembly, name=kdil).\n", + "\n", + "4. rna[activatable_assembly] --> \n", + " Kf=k_forward * rna_activatable_assembly\n", + " k_forward=0.001\n", + " found_key=(mech=rna_degredation, partid=None, name=kdil).\n", + " search_key=(mech=rna_degredation, partid=rna_activatable_assembly, name=kdil).\n", + "\n", "]\n" ] } @@ -73,46 +100,50 @@ "\n", "#ActivatedPromoter Example\n", "activator = Species(\"activator\", material_type = \"small_molecule\")\n", + "S_A = Species(\"A\")\n", "\n", "#Create a custom set of parameters\n", "hill_parameters = {\"k\":1.0, \"n\":4, \"K\":20, \"kleak\":.01}\n", "#By Loading custom parameters into the promoter, we override the default parameters of the Mixture\n", - "P_activatable = ActivatablePromotor(\"P_activtable\", activator = activator, leak = True, parameters = hill_parameters)\n", + "P_activatable = ActivatablePromoter(\"P_activtable\", activator = activator, leak = True, parameters = hill_parameters)\n", "\n", "#Create a DNA assembly \"reporter\" with P_activatable for its promoter\n", - "activatable_assembly = DNAassembly(name=\"activatable_assembly\", promoter=P_activatable, rbs=\"Strong\", protein = \"A\")\n", + "activatable_assembly = DNAassembly(name=\"activatable_assembly\", promoter=P_activatable, rbs=\"Strong\", protein = S_A)\n", "\n", "M = SimpleTxTlExtract(name=\"SimpleTxTl\", parameter_file = \"default_parameters.txt\", components=[activatable_assembly])\n", "\n", - "CRN = M.compile_crn(); print(CRN)" + "CRN = M.compile_crn();\n", + "\n", + "print(CRN.pretty_print(show_rates = True, show_keys = True))" ] }, { "cell_type": "code", - "execution_count": 191, + "execution_count": 16, "metadata": { "slideshow": { "slide_type": "skip" - } + }, + "tags": [] }, "outputs": [ { "data": { - "image/png": "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\n", + "image/png": "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\n", "text/plain": [ "
" ] }, "metadata": { "needs_background": "light" - }, - "output_type": "display_data" + } } ], "source": [ "#Titrate the activator and plot the result\n", "try:\n", - " import biocrnpyler\n", + " %matplotlib inline\n", + " from biocrnpyler import *\n", " import numpy as np\n", " import pylab as plt\n", " import pandas as pd\n", @@ -120,13 +151,13 @@ " for a_c in np.linspace(0, 50, 5):\n", " x0 = {str(activatable_assembly.dna):1, str(activator):a_c}\n", " timepoints = np.linspace(0, 100, 100)\n", - " R = CRN.simulate_with_bioscrape(timepoints, initial_condition_dict = x0)\n", - " plt.plot(R[\"time\"], R[\"protein_A\"], label = \"[activator]=\"+str(a_c))\n", + " R = CRN.simulate_with_bioscrape_via_sbml(timepoints, initial_condition_dict = x0)\n", + " plt.plot(R[\"time\"], R[str(S_A)], label = \"[activator]=\"+str(a_c))\n", "\n", - " plt.ylabel(\"[A]\")\n", + " plt.ylabel(f\"[{S_A}]\")\n", " plt.legend()\n", "except ModuleNotFoundError:\n", - " print(\"Libraries needed for plotting and simulation not found.\")" + " print('please install the plotting libraries: pip install biocrnpyler[all]')" ] }, { @@ -143,47 +174,77 @@ }, { "cell_type": "code", - "execution_count": 192, + "execution_count": 17, "metadata": { "slideshow": { "slide_type": "subslide" - } + }, + "tags": [] }, "outputs": [ { - "name": "stdout", "output_type": "stream", "text": [ - "Species = dna_reporter, protein_reporter, protein_A, rna_reporter\n", - "Reactions = [\n", - "\tdna_reporter --> dna_reporter + rna_reporter proportionalhillnegative: k(protein_A, dna_reporter)=0.01875*dna_reporter/(20.0+protein_A^2.0)\n", - "\tdna_reporter --> dna_reporter + rna_reporter massaction: k_f(dna_reporter)=1e-06*dna_reporter\n", - "\trna_reporter --> rna_reporter + protein_reporter massaction: k_f(rna_reporter)=0.25*rna_reporter\n", - "\trna_reporter --> massaction: k_f(rna_reporter)=0.001*rna_reporter\n", + "Species (4) = {0. dna[reporter], 1. A, 2. rna[reporter], 3. protein[reporter]}\n", + "\n", + "Reactions (5) = [\n", + "0. dna[reporter] --> dna[reporter]+rna[reporter]\n", + " Kf = k dna[reporter] /(A^4 + K)\n", + " k=1.0\n", + " K=20\n", + " n=4\n", + "\n", + "1. dna[reporter] --> dna[reporter]+rna[reporter]\n", + " Kf=k_forward * dna_reporter\n", + " k_forward=0.01\n", + " found_key=(mech=None, partid=None, name=kleak).\n", + " search_key=(mech=negativehill_transcription, partid=P_repressible_A, name=kleak).\n", + "\n", + "2. rna[reporter] --> rna[reporter]+protein[reporter]\n", + " Kf=k_forward * rna_reporter\n", + " k_forward=0.25\n", + " found_key=(mech=simple_translation, partid=None, name=ktl).\n", + " search_key=(mech=simple_translation, partid=Strong, name=ktl).\n", + "\n", + "3. rna[reporter] --> \n", + " Kf=k_forward * rna_reporter\n", + " k_forward=0.001\n", + " found_key=(mech=rna_degredation, partid=None, name=kdil).\n", + " search_key=(mech=rna_degredation, partid=rna_reporter, name=kdil).\n", + "\n", + "4. rna[reporter] --> \n", + " Kf=k_forward * rna_reporter\n", + " k_forward=0.001\n", + " found_key=(mech=rna_degredation, partid=None, name=kdil).\n", + " search_key=(mech=rna_degredation, partid=rna_reporter, name=kdil).\n", + "\n", "]\n" ] } ], "source": [ "#ActivatedPromoter Example\n", - "repressor = Species(\"A\", material_type = \"protein\")\n", + "repressor = S_A #defined in the previous example\n", + "reporter = Species(\"reporter\", material_type = \"protein\")\n", "\n", "#Create a custom set of parameters\n", "hill_parameters = {\"k\":1.0, \"n\":4, \"K\":20, \"kleak\":.01}\n", "#By Loading custom parameters into the promoter, we override the default parameters of the Mixture\n", - "P_repressible = RepressablePromotor(\"P_repressible\", repressor = repressor, leak = True, parameters = hill_parameters)\n", + "P_repressible = RepressiblePromoter(\"P_repressible\", repressor = repressor, leak = True, parameters = hill_parameters)\n", "\n", "#Create a DNA assembly \"reporter\" with P_activatable for its promoter\n", - "repressible_assembly = DNAassembly(name=\"reporter\", promoter=P_repressible, rbs=\"Strong\", protein = \"reporter\")\n", + "repressible_assembly = DNAassembly(name=\"reporter\", promoter=P_repressible, rbs=\"Strong\", protein = reporter)\n", "\n", "M = SimpleTxTlExtract(name=\"SimpleTxTl\", parameter_file = \"default_parameters.txt\", components=[repressible_assembly])\n", "\n", - "CRN = M.compile_crn();print(CRN)" + "CRN = M.compile_crn()\n", + "\n", + "print(CRN.pretty_print(show_rates = True, show_keys = True))" ] }, { "cell_type": "code", - "execution_count": 193, + "execution_count": 18, "metadata": { "slideshow": { "slide_type": "skip" @@ -191,16 +252,16 @@ }, "outputs": [ { + "output_type": "display_data", "data": { - "image/png": "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\n", + "image/png": "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\n", "text/plain": [ "
" ] }, "metadata": { "needs_background": "light" - }, - "output_type": "display_data" + } } ], "source": [ @@ -214,13 +275,13 @@ " for r_c in np.linspace(0, 50, 5):\n", " x0 = {str(repressible_assembly.dna):1, str(repressor):r_c}\n", " timepoints = np.linspace(0, 100, 100)\n", - " R = CRN.simulate_with_bioscrape(timepoints, initial_condition_dict = x0)\n", - " plt.plot(R[\"time\"], R[\"protein_reporter\"], label = \"[repressor]=\"+str(r_c))\n", + " R = CRN.simulate_with_bioscrape_via_sbml(timepoints, initial_condition_dict = x0)\n", + " plt.plot(R[\"time\"], R[str(reporter)], label = f\"[{str(S_A)}]={r_c}\")\n", "\n", " plt.ylabel(\"[B]\")\n", " plt.legend()\n", "except ModuleNotFoundError:\n", - " print(\"Libraries needed for plotting and simulation not found.\")" + " print('please install the plotting libraries: pip install biocrnpyler[all]')" ] }, { @@ -237,55 +298,84 @@ }, { "cell_type": "code", - "execution_count": 194, + "execution_count": 19, "metadata": { "slideshow": { "slide_type": "fragment" - } + }, + "tags": [] }, "outputs": [ { - "name": "stdout", "output_type": "stream", "text": [ - "Species (7) = {0. dna[reporter], 1. protein[reporter], 2. protein[A], 3. rna[reporter], 4. dna[activatable_assembly], 5. small_molecule[activator], 6. rna[activatable_assembly]}\n", - "Reactions (8) = [\n", - "0. dna[reporter] --> dna[reporter] + rna[reporter] \n", - " proportionalhillnegative: k(protein[A], dna[reporter])=0.01875*dna[reporter]/(20.0+protein[A]^2.0)\n", - "1. dna[reporter] --> dna[reporter] + rna[reporter] \n", - " massaction: k_f(dna[reporter])=1e-06*dna[reporter]\n", - "2. rna[reporter] --> rna[reporter] + protein[reporter] \n", - " massaction: k_f(rna[reporter])=0.25*rna[reporter]\n", - "3. dna[activatable_assembly] --> dna[activatable_assembly] + rna[activatable_assembly] \n", - " proportionalhillpositive: k(small_molecule[activator], dna[activatable_assembly])=1.0*dna[activatable_assembly]*small_molecule[activator]^4/(20+small_molecule[activator]^4)\n", - "4. dna[activatable_assembly] --> dna[activatable_assembly] + rna[activatable_assembly] \n", - " massaction: k_f(dna[activatable_assembly])=0.01*dna[activatable_assembly]\n", - "5. rna[activatable_assembly] --> rna[activatable_assembly] + protein[A] \n", - " massaction: k_f(rna[activatable_assembly])=0.25*rna[activatable_assembly]\n", - "6. rna[reporter] --> \n", - " massaction: k_f(rna[reporter])=0.001*rna[reporter]\n", - "7. rna[activatable_assembly] --> \n", - " massaction: k_f(rna[activatable_assembly])=0.001*rna[activatable_assembly]\n", + "Species (7) = {0. dna[reporter], 1. A, 2. rna[reporter], 3. protein[reporter], 4. dna[activatable_assembly], 5. small_molecule[activator], 6. rna[activatable_assembly]}\n", + "\n", + "Reactions (10) = [\n", + "0. dna[reporter] --> dna[reporter]+rna[reporter]\n", + " Kf = k dna[reporter] /(A^4 + K)\n", + " k=1.0\n", + " K=20\n", + " n=4\n", + "\n", + "1. dna[reporter] --> dna[reporter]+rna[reporter]\n", + " Kf=k_forward * dna_reporter\n", + " k_forward=0.01\n", + "\n", + "2. rna[reporter] --> rna[reporter]+protein[reporter]\n", + " Kf=k_forward * rna_reporter\n", + " k_forward=0.25\n", + "\n", + "3. dna[activatable_assembly] --> dna[activatable_assembly]+rna[activatable_assembly]\n", + " Kf = k dna[activatable_assembly] small_molecule[activator]^n/(small_molecule[activator]^n + K)\n", + " k=1.0\n", + " K=20\n", + " n=4\n", + "\n", + "4. dna[activatable_assembly] --> dna[activatable_assembly]+rna[activatable_assembly]\n", + " Kf=k_forward * dna_activatable_assembly\n", + " k_forward=0.01\n", + "\n", + "5. rna[activatable_assembly] --> rna[activatable_assembly]+A\n", + " Kf=k_forward * rna_activatable_assembly\n", + " k_forward=0.25\n", + "\n", + "6. rna[reporter] --> \n", + " Kf=k_forward * rna_reporter\n", + " k_forward=0.001\n", + "\n", + "7. rna[reporter] --> \n", + " Kf=k_forward * rna_reporter\n", + " k_forward=0.001\n", + "\n", + "8. rna[activatable_assembly] --> \n", + " Kf=k_forward * rna_activatable_assembly\n", + " k_forward=0.001\n", + "\n", + "9. rna[activatable_assembly] --> \n", + " Kf=k_forward * rna_activatable_assembly\n", + " k_forward=0.001\n", + "\n", "]\n" ] }, { + "output_type": "display_data", "data": { - "image/png": "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\n", + "image/png": "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\n", "text/plain": [ "
" ] }, "metadata": { "needs_background": "light" - }, - "output_type": "display_data" + } } ], "source": [ "M = SimpleTxTlExtract(name=\"SimpleTxTl\", parameter_file = \"default_parameters.txt\", components=[repressible_assembly, activatable_assembly])\n", "CRN = M.compile_crn()\n", - "print(CRN.pretty_print())\n", + "print(CRN.pretty_print(show_rates = True, show_keys = False))\n", "\n", "#Titrate the activator, which in turn will automatically produce the repressor\n", "try:\n", @@ -298,11 +388,11 @@ " for a_c in np.linspace(0, 50, 5):\n", " x0 = {str(activatable_assembly.dna):1, str(repressible_assembly.dna):1, str(activator):a_c}\n", " timepoints = np.linspace(0, 100, 100)\n", - " R = CRN.simulate_with_bioscrape(timepoints, initial_condition_dict = x0)\n", + " R = CRN.simulate_with_bioscrape_via_sbml(timepoints, initial_condition_dict = x0)\n", " plt.sca(ax1)\n", - " plt.plot(R[\"time\"], R[\"protein_A\"], label = \"[activator]=\"+str(a_c))\n", + " plt.plot(R[\"time\"], R[str(S_A)], label = \"[activator]=\"+str(a_c))\n", " plt.sca(ax2)\n", - " plt.plot(R[\"time\"], R[\"protein_reporter\"], label = \"[activator]=\"+str(a_c))\n", + " plt.plot(R[\"time\"], R[str(reporter)], label = \"[activator]=\"+str(a_c))\n", "\n", " plt.sca(ax1)\n", " plt.ylabel(\"activatable assembly output: [A]\")\n", @@ -311,7 +401,7 @@ " plt.ylabel(\"repressable assembly output: [B]\")\n", " plt.legend()\n", "except ModuleNotFoundError:\n", - " print(\"Libraries needed for plotting and simulation not found.\")" + " print('please install the plotting libraries: pip install biocrnpyler[all]')" ] }, { @@ -328,50 +418,82 @@ }, { "cell_type": "code", - "execution_count": 195, + "execution_count": 20, "metadata": { "slideshow": { "slide_type": "subslide" - } + }, + "tags": [] }, "outputs": [ { - "name": "stdout", "output_type": "stream", "text": [ - "Species (15) = {0. dna[reporter], 1. complex[protein[RNAase]:rna[reporter]], 2. complex[dna[reporter]:protein[RNAP]], 3. rna[reporter], 4. [dna[reporter]:2x_protein[A]], 5. [dna[reporter]:2x_protein[R]], 6. protein[reporter], 7. protein[R], 8. complex[[dna[reporter]:2x_protein[R]]:protein[RNAP]], 9. complex[[dna[reporter]:2x_protein[A]]:protein[RNAP]], 10. protein[A], 11. protein[RNAP], 12. complex[protein[Ribo]:rna[reporter]], 13. protein[Ribo], 14. protein[RNAase]}\n", + "Species (15) = {0. dna[reporter], 1. protein[RNAP], 2. rna[reporter], 3. complex[dna[reporter]:protein[RNAP]], 4. protein[A], 5. [dna[reporter]:2x_protein[A]], 6. complex[[dna[reporter]:2x_protein[A]]:protein[RNAP]], 7. protein[R], 8. [dna[reporter]:2x_protein[R]], 9. complex[[dna[reporter]:2x_protein[R]]:protein[RNAP]], 10. protein[Ribo], 11. protein[reporter], 12. complex[protein[Ribo]:rna[reporter]], 13. protein[RNAase], 14. complex[protein[RNAase]:rna[reporter]]}\n", + "\n", "Reactions (12) = [\n", - "0. dna[reporter] + protein[RNAP] <--> complex[dna[reporter]:protein[RNAP]] \n", - " massaction: k_f(dna[reporter],protein[RNAP])=100.0*dna[reporter]*protein[RNAP]\n", - " k_r(complex[dna[reporter]:protein[RNAP]])=10.0*complex[dna[reporter]:protein[RNAP]]\n", - "1. complex[dna[reporter]:protein[RNAP]] --> dna[reporter] + rna[reporter] + protein[RNAP] \n", - " massaction: k_f(complex[dna[reporter]:protein[RNAP]])=0.05*complex[dna[reporter]:protein[RNAP]]\n", - "2. 2.0 protein[A] + dna[reporter] <--> [dna[reporter]:2x_protein[A]] \n", - " massaction: k_f(protein[A],dna[reporter])=100.0*protein[A]^2.0*dna[reporter]\n", - " k_r([dna[reporter]:2x_protein[A]])=10.0*[dna[reporter]:2x_protein[A]]\n", - "3. [dna[reporter]:2x_protein[A]] + protein[RNAP] <--> complex[[dna[reporter]:2x_protein[A]]:protein[RNAP]] \n", - " massaction: k_f([dna[reporter]:2x_protein[A]],protein[RNAP])=100*[dna[reporter]:2x_protein[A]]*protein[RNAP]\n", - " k_r(complex[[dna[reporter]:2x_protein[A]]:protein[RNAP]])=1.0*complex[[dna[reporter]:2x_protein[A]]:protein[RNAP]]\n", - "4. complex[[dna[reporter]:2x_protein[A]]:protein[RNAP]] --> [dna[reporter]:2x_protein[A]] + rna[reporter] + protein[RNAP] \n", - " massaction: k_f(complex[[dna[reporter]:2x_protein[A]]:protein[RNAP]])=1.0*complex[[dna[reporter]:2x_protein[A]]:protein[RNAP]]\n", - "5. 2.0 protein[R] + dna[reporter] <--> [dna[reporter]:2x_protein[R]] \n", - " massaction: k_f(protein[R],dna[reporter])=100.0*protein[R]^2.0*dna[reporter]\n", - " k_r([dna[reporter]:2x_protein[R]])=10.0*[dna[reporter]:2x_protein[R]]\n", - "6. [dna[reporter]:2x_protein[R]] + protein[RNAP] <--> complex[[dna[reporter]:2x_protein[R]]:protein[RNAP]] \n", - " massaction: k_f([dna[reporter]:2x_protein[R]],protein[RNAP])=1*[dna[reporter]:2x_protein[R]]*protein[RNAP]\n", - " k_r(complex[[dna[reporter]:2x_protein[R]]:protein[RNAP]])=100.0*complex[[dna[reporter]:2x_protein[R]]:protein[RNAP]]\n", - "7. complex[[dna[reporter]:2x_protein[R]]:protein[RNAP]] --> [dna[reporter]:2x_protein[R]] + rna[reporter] + protein[RNAP] \n", - " massaction: k_f(complex[[dna[reporter]:2x_protein[R]]:protein[RNAP]])=1.0*complex[[dna[reporter]:2x_protein[R]]:protein[RNAP]]\n", - "8. rna[reporter] + protein[Ribo] <--> complex[protein[Ribo]:rna[reporter]] \n", - " massaction: k_f(rna[reporter],protein[Ribo])=100.0*rna[reporter]*protein[Ribo]\n", - " k_r(complex[protein[Ribo]:rna[reporter]])=10.0*complex[protein[Ribo]:rna[reporter]]\n", - "9. complex[protein[Ribo]:rna[reporter]] --> rna[reporter] + protein[reporter] + protein[Ribo] \n", - " massaction: k_f(complex[protein[Ribo]:rna[reporter]])=0.05*complex[protein[Ribo]:rna[reporter]]\n", - "10. rna[reporter] + protein[RNAase] <--> complex[protein[RNAase]:rna[reporter]] \n", - " massaction: k_f(rna[reporter],protein[RNAase])=100.0*rna[reporter]*protein[RNAase]\n", - " k_r(complex[protein[RNAase]:rna[reporter]])=10.0*complex[protein[RNAase]:rna[reporter]]\n", - "11. complex[protein[RNAase]:rna[reporter]] --> protein[RNAase] \n", - " massaction: k_f(complex[protein[RNAase]:rna[reporter]])=0.001*complex[protein[RNAase]:rna[reporter]]\n", + "0. dna[reporter]+protein[RNAP] <--> complex[dna[reporter]:protein[RNAP]]\n", + " Kf=k_forward * dna_reporter * protein_RNAP\n", + " Kr=k_reverse * complex_dna_reporter_protein_RNAP\n", + " k_forward=5.0\n", + " k_reverse=100\n", + "\n", + "1. complex[dna[reporter]:protein[RNAP]] --> dna[reporter]+rna[reporter]+protein[RNAP]\n", + " Kf=k_forward * complex_dna_reporter_protein_RNAP\n", + " k_forward=1.0\n", + "\n", + "2. 2protein[A]+dna[reporter] <--> [dna[reporter]:2x_protein[A]]\n", + " Kf=k_forward * protein_A^2 * dna_reporter\n", + " Kr=k_reverse * dna_reporter_protein_A_2x\n", + " k_forward=100.0\n", + " k_reverse=10.0\n", + "\n", + "3. [dna[reporter]:2x_protein[A]]+protein[RNAP] <--> complex[[dna[reporter]:2x_protein[A]]:protein[RNAP]]\n", + " Kf=k_forward * dna_reporter_protein_A_2x * protein_RNAP\n", + " Kr=k_reverse * complex_dna_reporter_protein_A_2x_protein_RNAP\n", + " k_forward=100\n", + " k_reverse=1.0\n", + "\n", + "4. complex[[dna[reporter]:2x_protein[A]]:protein[RNAP]] --> [dna[reporter]:2x_protein[A]]+rna[reporter]+protein[RNAP]\n", + " Kf=k_forward * complex_dna_reporter_protein_A_2x_protein_RNAP\n", + " k_forward=1.0\n", + "\n", + "5. 2protein[R]+dna[reporter] <--> [dna[reporter]:2x_protein[R]]\n", + " Kf=k_forward * protein_R^2 * dna_reporter\n", + " Kr=k_reverse * dna_reporter_protein_R_2x\n", + " k_forward=100.0\n", + " k_reverse=10.0\n", + "\n", + "6. [dna[reporter]:2x_protein[R]]+protein[RNAP] <--> complex[[dna[reporter]:2x_protein[R]]:protein[RNAP]]\n", + " Kf=k_forward * dna_reporter_protein_R_2x * protein_RNAP\n", + " Kr=k_reverse * complex_dna_reporter_protein_R_2x_protein_RNAP\n", + " k_forward=1\n", + " k_reverse=100.0\n", + "\n", + "7. complex[[dna[reporter]:2x_protein[R]]:protein[RNAP]] --> [dna[reporter]:2x_protein[R]]+rna[reporter]+protein[RNAP]\n", + " Kf=k_forward * complex_dna_reporter_protein_R_2x_protein_RNAP\n", + " k_forward=1.0\n", + "\n", + "8. rna[reporter]+protein[Ribo] <--> complex[protein[Ribo]:rna[reporter]]\n", + " Kf=k_forward * rna_reporter * protein_Ribo\n", + " Kr=k_reverse * complex_protein_Ribo_rna_reporter\n", + " k_forward=100.0\n", + " k_reverse=10.0\n", + "\n", + "9. complex[protein[Ribo]:rna[reporter]] --> rna[reporter]+protein[reporter]+protein[Ribo]\n", + " Kf=k_forward * complex_protein_Ribo_rna_reporter\n", + " k_forward=0.05\n", + "\n", + "10. rna[reporter]+protein[RNAase] <--> complex[protein[RNAase]:rna[reporter]]\n", + " Kf=k_forward * rna_reporter * protein_RNAase\n", + " Kr=k_reverse * complex_protein_RNAase_rna_reporter\n", + " k_forward=100.0\n", + " k_reverse=10.0\n", + "\n", + "11. complex[protein[RNAase]:rna[reporter]] --> protein[RNAase]\n", + " Kf=k_forward * complex_protein_RNAase_rna_reporter\n", + " k_forward=0.001\n", + "\n", "]\n" ] } @@ -380,72 +502,73 @@ "#1 Regulated Promoter Needs lots of parameters!\n", "component_parameters = {\n", " #Promoter Activator Binding Parameters. Note the part_id = [promoter_name]_[regulator_name]\n", - " ('binding', 'regulated_promoter_A', 'kb'):1000, #Promoter - Activator Binding\n", - " ('binding', \"regulated_promoter_A\", 'ku'):5.0, #Unbinding\n", - " ('binding',\"regulated_promoter_A\", 'cooperativity'):4.0, #Cooperativity\n", + " ParameterKey(mechanism = 'binding', part_id = 'regulated_promoter_A', name = 'kb'):1000, #Promoter - Activator Binding\n", + " ParameterKey(mechanism = 'binding', part_id = \"regulated_promoter_A\", name = 'ku'):5.0, #Unbinding\n", + " ParameterKey(mechanism = 'binding', part_id = \"regulated_promoter_A\", name = 'cooperativity'):4.0, #Cooperativity\n", " \n", " #Activated Promoter Transcription. Note the part_id = [promoter_name]_[regulator_name]\n", " #These regulate RNAP binding to an activated promoter and transcription\n", - " ('transcription', 'regulated_promoter_A', 'kb'):100, #Promoter - Activator Binding\n", - " ('transcription', \"regulated_promoter_A\", 'ku'):1.0, #Unbinding\n", - " ('transcription', 'regulated_promoter_A', \"ktx\"): 1., #Transcription Rate\n", + " ParameterKey(mechanism = 'transcription', part_id = 'regulated_promoter_A', name = 'kb'):100, #Promoter - Activator Binding\n", + " ParameterKey(mechanism = 'transcription', part_id = \"regulated_promoter_A\", name = 'ku'):1.0, #Unbinding\n", + " ParameterKey(mechanism = 'transcription', part_id = 'regulated_promoter_A', name = \"ktx\"): 1., #Transcription Rate\n", " \n", " #Promoter Repressor Binding Parameters. Note the part_id = [promoter_name]_[regulator_name]\n", - " ('binding', 'regulated_promoter_R', 'kb'):1000,\n", - " ('binding',\"regulated_promoter_R\", 'ku'):5.0,\n", - " ('binding',\"regulated_promoter_R\", 'cooperativity'):4.0,\n", + " ParameterKey(mechanism = 'binding', part_id = 'regulated_promoter_R', name = 'kb'):1000,\n", + " ParameterKey(mechanism = 'binding', part_id = \"regulated_promoter_R\", name = 'ku'):5.0,\n", + " ParameterKey(mechanism = 'binding', part_id = \"regulated_promoter_R\", name = 'cooperativity'):4.0,\n", " \n", " #Repressed Promoter Transcription. Note the part_id = [promoter_name]_[regulator_name]\n", " #These regulate RNAP binding to a repressed promoter and transcription\n", - " ('transcription', 'regulated_promoter_R', 'kb'):1,\n", - " ('transcription',\"regulated_promoter_R\", 'ku'):100.0,\n", - " ('transcription', 'regulated_promoter_R', \"ktx\"): 1.0, #Transcription Rate\n", + " ParameterKey(mechanism = 'transcription', part_id = 'regulated_promoter_R', name = 'kb'):1,\n", + " ParameterKey(mechanism = 'transcription', part_id = \"regulated_promoter_R\", name = 'ku'):100.0,\n", + " ParameterKey(mechanism = 'transcription', part_id = 'regulated_promoter_R', name = \"ktx\"): 1.0, #Transcription Rate\n", " \n", " #Leak Parameters for transcription\n", " #These regulate expression of an unbound promoter\n", - " ('transcription', 'regulated_promoter_leak', \"kb\"): 5.,\n", - " ('transcription', 'regulated_promoter_leak', \"ku\"): 100,\n", - " ('transcription', 'regulated_promoter_leak', \"ktx\"): 1.0, #Transcription Rate\n", + " ParameterKey(mechanism = 'transcription', part_id = 'regulated_promoter_leak', name = \"kb\"): 5.,\n", + " ParameterKey(mechanism = 'transcription', part_id = 'regulated_promoter_leak', name = \"ku\"): 100,\n", + " ParameterKey(mechanism = 'transcription', part_id = 'regulated_promoter_leak', name = \"ktx\"): 1.0, #Transcription Rate\n", "}\n", "\n", "repressor = Species(\"R\", material_type = \"protein\")\n", "activator = Species(\"A\", material_type = \"protein\")\n", + "reporter = Species(\"reporter\", material_type = \"protein\")\n", "\n", "#Create a RegulatedPromoter Object named \"P_reg\" with regulators \"activator\" and \"repressor\"\n", "#By Loading custom parameters into the promoter, we override the default parameters of the Mixture\n", "P_reg = RegulatedPromoter(\"regulated_promoter\", regulators=[activator, repressor], leak=True, parameters = component_parameters)\n", "\n", "#Create a DNA assembly \"reporter\" with P_reg for its promoter\n", - "reg_reporter = DNAassembly(name=\"reporter\", promoter=P_reg, rbs=\"Strong\", protein = \"reporter\")\n", + "reg_reporter = DNAassembly(name=\"reporter\", promoter=P_reg, rbs=\"Strong\", protein = reporter)\n", "\n", "#Use a simple TxTl model with dilution\n", "#M = SimpleTxTlDilutionMixture(name=\"e coli\", parameter_file = \"default_parameters.txt\", components=[reg_reporter])\n", "M = TxTlExtract(name=\"e coli extract\", parameter_file = \"default_parameters.txt\", components=[reg_reporter])\n", "\n", "CRN = M.compile_crn()\n", - "print(CRN.pretty_print())" + "print(CRN.pretty_print(show_rates = True, show_keys = False))" ] }, { "cell_type": "code", - "execution_count": 196, + "execution_count": 21, "metadata": { "slideshow": { "slide_type": "skip" - } + }, + "tags": [] }, "outputs": [ { "data": { - "image/png": "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rbXri/p5RETEM6mfEBERERGPYC24tKpacVyqhrV2GjCtOB5bREQ8n/oJERERERHPUCyFIxERERERERERj6c5jopljiMREREREREREfECGnEkIiIiIiIiIlIIqzmONOJIREREREREREQKpxFHIiIiIiIiIiK/YzXHERpxJCIiIiIiIiIiZ6HCkYiIiIiIiIiIFEqXqomIiIiIiIiInMkCLl2qphFHIiIiIiIiIiJSKI04EhEREREREREpjHU5HYHjNOJIREREREREREQKpRFHIiIiIiIiIiJnsIDVHEcacSQiIiIiIiIiIoXTiCMRERERERERkTNZqzmO0IgjERERERERERE5C404EhEREREREREphOY40ogjERERERERERE5C404EhEREREREREpjOY40ogjEREREREREREpnLHW+ev1jDFJwO7z/PNKwJEiDKe0K0v5lqVcQfl6swvJtaa1tnJRBuOJ1E/8JWUp37KUKyhfb6Z+4gJdYD/xV3jjeeltOXlbPuB9OZVUPhf8/miMmUF+vCXhiLW2Zwk9119SKgpHF8IYs9xa29bpOEpKWcq3LOUKyteblaVcS6Oy9vqXpXzLUq6gfL1ZWcrV03njsfK2nLwtH/C+nLwtn7JAl6qJiIiIiIiIiEihVDgSEREREREREZFCeUPhaJzTAZSwspRvWcoVlK83K0u5lkZl7fUvS/mWpVxB+XqzspSrp/PGY+VtOXlbPuB9OXlbPl7P4+c4EhERERERERGR4uENI45ERERERERERKQYqHAkIiIiIiIiIiKF8tjCkTGmpzFmszFmmzFmpNPxFAVjTKwxZr4xZqMxZr0x5n53e6QxZrYxZqv7Z4S73RhjXne/BmuMMa2dzeCvM8b4GmNWGmOmuu/XMsYscef6pTEmwN0e6L6/zb09zsm4z4cxJtwY87UxZpP7GHfw8mP7N/d5vM4YM9EYE+RNx9cYM94Yc9gYs65A218+nsaYQe79txpjBjmRi7dSP+E17yXqJ7z32KqfUD9Rav1ZH+Jp52Rh5+MZ2z3qPeVs/eEZ+3haTkHGmKXGmNXunEYVso9HnXfw+378jG0el09Z5ZGFI2OML/AW0AtoDPQzxjR2NqoikQv83VrbCGgP3O3OayQw11pbD5jrvg/5+ddz34YCY0s+5At2P7CxwP0XgVfcuSYDQ9ztQ4Bka21d4BX3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\n", + "image/png": "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\n", "text/plain": [ "
" ] }, "metadata": { "needs_background": "light" - }, - "output_type": "display_data" + } } ], "source": [ @@ -458,20 +581,20 @@ " plt.figure(figsize = (20, 10))\n", " ax1, ax2, ax3 = plt.subplot(131), plt.subplot(132), plt.subplot(133)\n", " N = 5 #Number of titrations\n", - " max_titration = 4\n", + " max_titration = 10\n", " HM = np.zeros((N, N))\n", " for a_ind, a_c in enumerate(np.linspace(0, max_titration, N)):\n", " for r_ind, r_c in enumerate(np.linspace(0, max_titration, N)):\n", " x0 = {str(reg_reporter.dna):1, str(repressor):r_c, str(activator):a_c}\n", " timepoints = np.linspace(0, 1000, 1000)\n", - " R = CRN.simulate_with_bioscrape(timepoints, initial_condition_dict = x0)\n", + " R = CRN.simulate_with_bioscrape_via_sbml(timepoints, initial_condition_dict = x0)\n", " if a_ind == 0:\n", " plt.sca(ax1)\n", - " plt.plot(R[\"time\"], R[\"protein_reporter\"], label = \"[A]=\"+str(a_c) +\" [R]=\"+str(r_c))\n", + " plt.plot(R[\"time\"], R[str(reporter)], label = \"[A]=\"+str(a_c) +\" [R]=\"+str(r_c))\n", " if r_ind == 0:\n", " plt.sca(ax2)\n", - " plt.plot(R[\"time\"], R[\"protein_reporter\"], label = \"[A]=\"+str(a_c) +\" [R]=\"+str(r_c))\n", - " HM[a_ind, r_ind] = R[\"protein_reporter\"][len(timepoints)-1]\n", + " plt.plot(R[\"time\"], R[str(reporter)], label = \"[A]=\"+str(a_c) +\" [R]=\"+str(r_c))\n", + " HM[a_ind, r_ind] = R[str(reporter)][len(timepoints)-1]\n", "\n", " plt.sca(ax1)\n", " plt.title(\"Repressor Titration\")\n", @@ -488,7 +611,7 @@ " plt.xticks(np.arange(.5, N+.5, 1), [str(i) for i in np.linspace(0, max_titration, N)])\n", " plt.yticks(np.arange(.5, N+.5, 1), [str(i) for i in np.linspace(0, max_titration, N)])\n", "except ModuleNotFoundError:\n", - " print(\"Libraries needed for plotting and simulation not found.\")" + " print('please install the plotting libraries: pip install biocrnpyler[all]')" ] }, { @@ -509,39 +632,63 @@ }, { "cell_type": "code", - "execution_count": 197, + "execution_count": 22, "metadata": { "slideshow": { "slide_type": "subslide" - } + }, + "tags": [] }, "outputs": [ { - "name": "stdout", "output_type": "stream", "text": [ - "Species (5) = {0. complex[ligand[L]:protein[A]], 1. dna[reporter], 2. ligand[L], 3. protein[A], 4. protein[reporter]}\n", - "Reactions (7) = [\n", - "0. complex[ligand[L]:protein[A]] --> \n", - " massaction: k_f(complex[ligand[L]:protein[A]])=0.001*complex[ligand[L]:protein[A]]\n", - "1. dna[reporter] --> dna[reporter] + protein[reporter] \n", - " massaction: k_f(dna[reporter])=1e-06*dna[reporter]\n", - "2. dna[reporter] --> dna[reporter] + protein[reporter] \n", - " proportionalhillnegative: k(complex[ligand[L]:protein[A]], dna[reporter])=0.01875*dna[reporter]/(20.0+complex[ligand[L]:protein[A]]^2.0)\n", - "3. ligand[L] --> \n", - " massaction: k_f(ligand[L])=0.001*ligand[L]\n", - "4. protein[A] + ligand[L] <--> complex[ligand[L]:protein[A]] \n", - " massaction: k_f(protein[A],ligand[L])=100.0*protein[A]*ligand[L]\n", - " k_r(complex[ligand[L]:protein[A]])=10.0*complex[ligand[L]:protein[A]]\n", - "5. protein[A] --> \n", - " massaction: k_f(protein[A])=0.001*protein[A]\n", - "6. protein[reporter] --> \n", - " massaction: k_f(protein[reporter])=0.001*protein[reporter]\n", + "Species (5) = {0. dna[reporter], 1. complex[ligand[L]:protein[A]], 2. protein[reporter], 3. ligand[L], 4. protein[A]}\n", + "\n", + "Reactions (8) = [\n", + "0. dna[reporter] --> dna[reporter]+protein[reporter]\n", + " Kf = k dna[reporter] /(complex[ligand[L]:protein[A]]^4 + K)\n", + " k=1.0\n", + " K=20\n", + " n=4\n", + "\n", + "1. dna[reporter] --> dna[reporter]+protein[reporter]\n", + " Kf=k_forward * dna_reporter\n", + " k_forward=0.01\n", + "\n", + "2. ligand[L]+protein[A] <--> complex[ligand[L]:protein[A]]\n", + " Kf=k_forward * ligand_L * protein_A\n", + " Kr=k_reverse * complex_ligand_L_protein_A\n", + " k_forward=100.0\n", + " k_reverse=10.0\n", + "\n", + "3. complex[ligand[L]:protein[A]] --> \n", + " Kf=k_forward * complex_ligand_L_protein_A\n", + " k_forward=0.001\n", + "\n", + "4. protein[reporter] --> \n", + " Kf=k_forward * protein_reporter\n", + " k_forward=0.001\n", + "\n", + "5. ligand[L] --> \n", + " Kf=k_forward * ligand_L\n", + " k_forward=0.001\n", + "\n", + "6. protein[A] --> \n", + " Kf=k_forward * protein_A\n", + " k_forward=0.001\n", + "\n", + "7. complex[ligand[L]:protein[A]] --> \n", + " Kf=k_forward * complex_ligand_L_protein_A\n", + " k_forward=0.001\n", + "\n", "]\n" ] } ], "source": [ + "\n", + "\n", "inactive_repressor = Species(\"A\", material_type = \"protein\")\n", "ligand = Species(\"L\", material_type = \"ligand\")\n", "\n", @@ -549,35 +696,41 @@ "activatable_repressor = ChemicalComplex([inactive_repressor, ligand])\n", "\n", "#Other Promoters could also be used\n", - "P_repressible = RepressablePromotor(\"P_repressible\", repressor = activatable_repressor.get_species(), leak = True, parameters = hill_parameters)\n", + "P_repressible = RepressiblePromoter(\"P_repressible\", repressor = activatable_repressor.get_species(), leak = True, parameters = hill_parameters)\n", "\n", "#Create a DNA assembly \"reporter\" with P_activatable for its promoter\n", "repressible_assembly = DNAassembly(name=\"reporter\", promoter=P_repressible, rbs=\"Strong\", protein = \"reporter\")\n", "\n", "M = ExpressionDilutionMixture(name=\"ExpressionDilutionMixture\", parameter_file = \"default_parameters.txt\", components=[repressible_assembly, activatable_repressor])\n", - "CRN = M.compile_crn();print(CRN.pretty_print())" + "CRN = M.compile_crn();print(CRN.pretty_print(show_rates = True, show_keys = False))" ] }, { "cell_type": "code", - "execution_count": 198, + "execution_count": 23, "metadata": { "slideshow": { "slide_type": "skip" - } + }, + "tags": [] }, "outputs": [ { + "output_type": "stream", + "name": "stderr", + "text": "d:\\documents\\github\\biocrnpyler\\biocrnpyler\\chemical_reaction_network.py:1557: UserWarning: Trying to set species that is not in model: ligand_L\n m.set_species(initial_condition_dict)\n" + }, + { + "output_type": "display_data", "data": { - "image/png": "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\n", + "image/png": "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\n", "text/plain": [ "
" ] }, "metadata": { "needs_background": "light" - }, - "output_type": "display_data" + } } ], "source": [ @@ -595,7 +748,7 @@ " for l_ind, L_c in enumerate(np.linspace(0, max_titration, N)):\n", " x0 = {str(repressible_assembly.dna):1, str(inactive_repressor):R_c, str(ligand):L_c}\n", " timepoints = np.linspace(0, 1000, 1000)\n", - " R = CRN.simulate_with_bioscrape(timepoints, initial_condition_dict = x0)\n", + " R = CRN.simulate_with_bioscrape_via_sbml(timepoints, initial_condition_dict = x0)\n", " HM[r_ind, l_ind] = R[\"protein_reporter\"][len(timepoints)-1]\n", "\n", " plt.title(\"Activatable Repressor vs Ligand Endpoint Heatmap\\n Exhibits NOT AND Logic\")\n", @@ -608,7 +761,7 @@ " plt.yticks(np.arange(.5, N+.5, 1), [str(i) for i in np.linspace(0, max_titration, N)])\n", " \n", "except ModuleNotFoundError:\n", - " print(\"Libraries needed for plotting and simulation not found.\")" + " print('please install the plotting libraries: pip install biocrnpyler[all]')" ] }, { @@ -625,34 +778,56 @@ }, { "cell_type": "code", - "execution_count": 199, + "execution_count": 24, "metadata": { "slideshow": { "slide_type": "subslide" - } + }, + "tags": [] }, "outputs": [ { - "name": "stdout", "output_type": "stream", "text": [ - "Species (5) = {0. complex[ligand[L]:protein[A]], 1. dna[reporter], 2. ligand[L], 3. protein[A], 4. protein[reporter]}\n", - "Reactions (7) = [\n", - "0. complex[ligand[L]:protein[A]] --> \n", - " massaction: k_f(complex[ligand[L]:protein[A]])=0.001*complex[ligand[L]:protein[A]]\n", - "1. dna[reporter] --> dna[reporter] + protein[reporter] \n", - " massaction: k_f(dna[reporter])=1e-06*dna[reporter]\n", - "2. dna[reporter] --> dna[reporter] + protein[reporter] \n", - " proportionalhillnegative: k(protein[A], dna[reporter])=0.01875*dna[reporter]/(20.0+protein[A]^2.0)\n", - "3. ligand[L] --> \n", - " massaction: k_f(ligand[L])=0.001*ligand[L]\n", - "4. protein[A] + ligand[L] <--> complex[ligand[L]:protein[A]] \n", - " massaction: k_f(protein[A],ligand[L])=100.0*protein[A]*ligand[L]\n", - " k_r(complex[ligand[L]:protein[A]])=10.0*complex[ligand[L]:protein[A]]\n", - "5. protein[A] --> \n", - " massaction: k_f(protein[A])=0.001*protein[A]\n", - "6. protein[reporter] --> \n", - " massaction: k_f(protein[reporter])=0.001*protein[reporter]\n", + "Species (5) = {0. dna[reporter], 1. protein[A], 2. protein[reporter], 3. ligand[L], 4. complex[ligand[L]:protein[A]]}\n", + "\n", + "Reactions (8) = [\n", + "0. dna[reporter] --> dna[reporter]+protein[reporter]\n", + " Kf = k dna[reporter] /(protein[A]^4 + K)\n", + " k=1.0\n", + " K=20\n", + " n=4\n", + "\n", + "1. dna[reporter] --> dna[reporter]+protein[reporter]\n", + " Kf=k_forward * dna_reporter\n", + " k_forward=0.01\n", + "\n", + "2. ligand[L]+protein[A] <--> complex[ligand[L]:protein[A]]\n", + " Kf=k_forward * ligand_L * protein_A\n", + " Kr=k_reverse * complex_ligand_L_protein_A\n", + " k_forward=100.0\n", + " k_reverse=10.0\n", + "\n", + "3. protein[A] --> \n", + " Kf=k_forward * protein_A\n", + " k_forward=0.001\n", + "\n", + "4. protein[reporter] --> \n", + " Kf=k_forward * protein_reporter\n", + " k_forward=0.001\n", + "\n", + "5. ligand[L] --> \n", + " Kf=k_forward * ligand_L\n", + " k_forward=0.001\n", + "\n", + "6. protein[A] --> \n", + " Kf=k_forward * protein_A\n", + " k_forward=0.001\n", + "\n", + "7. complex[ligand[L]:protein[A]] --> \n", + " Kf=k_forward * complex_ligand_L_protein_A\n", + " k_forward=0.001\n", + "\n", "]\n" ] } @@ -665,35 +840,41 @@ "inactive_repressor = ChemicalComplex([repressor, ligand])\n", "\n", "#Other Promoters could also be Used\n", - "P_repressible = RepressablePromotor(\"P_repressible\", repressor = repressor, leak = True, parameters = hill_parameters)\n", + "P_repressible = RepressiblePromoter(\"P_repressible\", repressor = repressor, leak = True, parameters = hill_parameters)\n", "\n", "#Create a DNA assembly \"reporter\" with P_activatable for its promoter\n", "repressible_assembly = DNAassembly(name=\"reporter\", promoter=P_repressible, rbs=\"Strong\", protein = \"reporter\")\n", "\n", "M = ExpressionDilutionMixture(name=\"ExpressionDilutionMixture\", parameter_file = \"default_parameters.txt\", components=[repressible_assembly, activatable_repressor])\n", - "CRN = M.compile_crn();print(CRN.pretty_print())" + "CRN = M.compile_crn();print(CRN.pretty_print(show_rates = True, show_keys = False))" ] }, { "cell_type": "code", - "execution_count": 200, + "execution_count": 25, "metadata": { "slideshow": { "slide_type": "skip" - } + }, + "tags": [] }, "outputs": [ { + "output_type": "stream", + "name": "stderr", + "text": "d:\\documents\\github\\biocrnpyler\\biocrnpyler\\chemical_reaction_network.py:1557: UserWarning: Trying to set species that is not in model: ligand_L\n m.set_species(initial_condition_dict)\n" + }, + { + "output_type": "display_data", "data": { - "image/png": "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\n", + "image/png": "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\n", "text/plain": [ "
" ] }, "metadata": { "needs_background": "light" - }, - "output_type": "display_data" + } } ], "source": [ @@ -712,7 +893,7 @@ " for l_ind, L_c in enumerate(np.linspace(0, max_titration, N)):\n", " x0 = {str(repressible_assembly.dna):1, str(repressor):R_c, str(ligand):L_c}\n", " timepoints = np.linspace(0, 1000, 1000)\n", - " R = CRN.simulate_with_bioscrape(timepoints, initial_condition_dict = x0)\n", + " R = CRN.simulate_with_bioscrape_via_sbml(timepoints, initial_condition_dict = x0)\n", " HM[r_ind, l_ind] = R[\"protein_reporter\"][len(timepoints)-1]\n", "\n", " plt.title(\"Deactivatable Repressor vs Ligand Endpoint Heatmap\\nAllows for Tunable Induction\")\n", @@ -724,7 +905,7 @@ " plt.yticks(np.arange(.5, N+.5, 1), [str(i) for i in np.linspace(0, max_titration, N)])\n", " \n", "except ModuleNotFoundError:\n", - " print(\"Libraries needed for plotting and simulation not found.\")" + " print('please install the plotting libraries: pip install biocrnpyler[all]')" ] }, { @@ -749,60 +930,73 @@ }, { "cell_type": "code", - "execution_count": 201, + "execution_count": 26, "metadata": { "slideshow": { "slide_type": "subslide" - } + }, + "tags": [] }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "Species (5) = {0. complex[2x_A:2x_B:dna[AND]], 1. complex[2x_A:dna[AND]], 2. complex[2x_B:dna[AND]], 3. dna[AND], 4. protein[GFP]}\n", + "Species (7) = {0. dna[AND], 1. protein[GFP], 2. complex[2x_A:dna[AND]], 3. complex[2x_B:dna[AND]], 4. complex[2x_A:2x_B:dna[AND]], 5. A, 6. B}\n", + "\n", "Reactions (8) = [\n", - "0. 2.0 A + complex[2x_B:dna[AND]] <--> complex[2x_A:2x_B:dna[AND]] \n", - " massaction: k_f(A,complex[2x_B:dna[AND]])=100.0*A^2.0*complex[2x_B:dna[AND]]\n", - " k_r(complex[2x_A:2x_B:dna[AND]])=10.0*complex[2x_A:2x_B:dna[AND]]\n", - "1. 2.0 A + dna[AND] <--> complex[2x_A:dna[AND]] \n", - " massaction: k_f(A,dna[AND])=100.0*A^2.0*dna[AND]\n", - " k_r(complex[2x_A:dna[AND]])=10.0*complex[2x_A:dna[AND]]\n", - "2. 2.0 B + complex[2x_A:dna[AND]] <--> complex[2x_A:2x_B:dna[AND]] \n", - " massaction: k_f(B,complex[2x_A:dna[AND]])=100.0*B^2.0*complex[2x_A:dna[AND]]\n", - " k_r(complex[2x_A:2x_B:dna[AND]])=10.0*complex[2x_A:2x_B:dna[AND]]\n", - "3. 2.0 B + dna[AND] <--> complex[2x_B:dna[AND]] \n", - " massaction: k_f(B,dna[AND])=100.0*B^2.0*dna[AND]\n", - " k_r(complex[2x_B:dna[AND]])=10.0*complex[2x_B:dna[AND]]\n", - "4. complex[2x_A:2x_B:dna[AND]] --> complex[2x_A:2x_B:dna[AND]] + protein[GFP] \n", - " massaction: k_f(complex[2x_A:2x_B:dna[AND]])=0.28125*complex[2x_A:2x_B:dna[AND]]\n", - "5. complex[2x_A:dna[AND]] --> complex[2x_A:dna[AND]] + protein[GFP] \n", - " massaction: k_f(complex[2x_A:dna[AND]])=0.0028125*complex[2x_A:dna[AND]]\n", - "6. complex[2x_B:dna[AND]] --> complex[2x_B:dna[AND]] + protein[GFP] \n", - " massaction: k_f(complex[2x_B:dna[AND]])=0.0028125*complex[2x_B:dna[AND]]\n", - "7. dna[AND] --> dna[AND] + protein[GFP] \n", - " massaction: k_f(dna[AND])=0.0028125*dna[AND]\n", + "0. dna[AND] --> dna[AND]+protein[GFP]\n", + " Kf=k_forward * dna_AND\n", + " k_forward=0.0028125\n", + "\n", + "1. 2A+dna[AND] <--> complex[2x_A:dna[AND]]\n", + " Kf=k_forward * A^2 * dna_AND\n", + " Kr=k_reverse * complex_A_2x_dna_AND\n", + " k_forward=100.0\n", + " k_reverse=10.0\n", + "\n", + "2. 2B+dna[AND] <--> complex[2x_B:dna[AND]]\n", + " Kf=k_forward * B^2 * dna_AND\n", + " Kr=k_reverse * complex_B_2x_dna_AND\n", + " k_forward=100.0\n", + " k_reverse=10.0\n", + "\n", + "3. 2A+complex[2x_B:dna[AND]] <--> complex[2x_A:2x_B:dna[AND]]\n", + " Kf=k_forward * A^2 * complex_B_2x_dna_AND\n", + " Kr=k_reverse * complex_A_2x_B_2x_dna_AND\n", + " k_forward=100.0\n", + " k_reverse=10.0\n", + "\n", + "4. 2B+complex[2x_A:dna[AND]] <--> complex[2x_A:2x_B:dna[AND]]\n", + " Kf=k_forward * B^2 * complex_A_2x_dna_AND\n", + " Kr=k_reverse * complex_A_2x_B_2x_dna_AND\n", + " k_forward=100.0\n", + " k_reverse=10.0\n", + "\n", + "5. complex[2x_A:2x_B:dna[AND]] --> complex[2x_A:2x_B:dna[AND]]+protein[GFP]\n", + " Kf=k_forward * complex_A_2x_B_2x_dna_AND\n", + " k_forward=0.28125\n", + "\n", + "6. complex[2x_A:dna[AND]] --> complex[2x_A:dna[AND]]+protein[GFP]\n", + " Kf=k_forward * complex_A_2x_dna_AND\n", + " k_forward=0.0028125\n", + "\n", + "7. complex[2x_B:dna[AND]] --> complex[2x_B:dna[AND]]+protein[GFP]\n", + " Kf=k_forward * complex_B_2x_dna_AND\n", + " k_forward=0.0028125\n", + "\n", "]\n" ] }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - "C:\\ProgramData\\Anaconda3\\lib\\site-packages\\biocrnpyler-0.2.1-py3.7.egg\\biocrnpyler\\chemical_reaction_network.py:1089: UserWarning: The following species are uninitialized and their value has been defaulted to 0: A, B, \n" - ] - }, { "data": { - "image/png": "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\n", - "text/plain": [ - "
" - ] + "text/plain": "
", + "image/svg+xml": "\r\n\r\n\r\n\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n\r\n", + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAd8AAAGDCAYAAABqTBrUAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADh0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uMy4xLjMsIGh0dHA6Ly9tYXRwbG90bGliLm9yZy+AADFEAAAgAElEQVR4nO3df7RkZX3n+/eHpm0EheaHOAgYNBJH4xqR6SsYEmPsRIHk2urVBCaRDiHTui7O1VxnJejM9dfETMxKNHGSgekIigYRRRl7HEYhqONkjaANAoKtoVUCLQhiI2KISHd/7x+1DxZFne4+dU7tXbv7/Vprr1O193P28z1V55xvPc9+9vOkqpAkSe3Zp+sAJEna25h8JUlqmclXkqSWmXwlSWqZyVeSpJaZfCVJapnJV5pQkhck2bJE5/phkqcuxbkkzT6TrzqV5HNJ7k2yYmT/+5NUkucO7Xtakhr53h8luT/JD5Jcm+Sc0XONOe+Pm2Q3t90wnZ9u91XV46rqm7tTtnldnraT47+d5O/G7L81yS8vJs7mPG9N8jeLPY+0NzP5qjNJjgF+ASjgJWOKbAX+cBeneW1VPR44AngDcBpweZLs5Hv+pEl2c9uzFxy8JC2CyVddOgO4Gng/sHbM8QuBf5HkF3d1oqr6x6r6HIMk/jzgVxcaTJJjmlbl2iS3Jbknyb8bOv7YpuV8b5KvAv/HyPffmuSNSb7alHlfkv2Gjv/rJJuTbE2yIcmTho493Jpt6virJP+9adVfk+Snm2Ofb77lhqbV/hsL/TmH6vydJJuaWD+d5KeGjv1FktuHehR+odl/MvAm4DeGew2aXog/TPK/m/3/LcmhSS5qzvGl5sPWTs/fHHtrkkuTXNL8/Ncl8QOS9igmX3XpDOCiZntxkieOHH8A+CPgHbt7wqq6DdjIoEU9qZ8Hng6sBt6c5BnN/rcAP91sL2b8B4bfbI79NPAzwL8HSPJC4D8Cv86glf4PwId3EsPpwNuAg4HNNK9BVT2/Of7sptV+ySQ/YJKXMkiiLweeAPwv4OKhIl8CjgMOAT4EfDTJflX1KQbvySVjeg1OA14FHNn8/F8A3tecYxOD12+n5x86vgb46NDx/5pk+SQ/qzSLTL7qRJKfB34K+EhVXQt8A/hXY4r+F+DJSU5ZwOnvYPBPez7/Nsn3h7YLR46/rar+qapuAG4A5hLMrwPvqKqtVXU78J4x5/7Lqrq9qrYySJinN/t/E7igqq6rqgeBNwLPG24Njvh4VX2xqrYx+HBy3M5/5Ec5ceRn/D7w5KHjrwb+Y1Vtaur4I+C4udZvVf1NVX2vqrZV1Z8BKxh8INmZ91XVN6rqPuB/AN+oqr9tzv9R4DlzBXfj/NdW1aVV9RDwLmA/4MQFvgbSzDL5qitrgSuq6p7m+YcY05JsEtV/aLadXccddiSD68Xz+dOqWjm0jdb7naHHDwCPax4/Cbh96Ng/jDn36PG5ruUnDZevqh8C32tiHWe+GHbX1SM/40rgtqHjPwX8xVBi3srg9T0SIMkbmi7p+5rjBwGH7aLOu4Ye/9OY5w//DLtx/odfx6raAWzhJ6+l1HsmX7UuyWMZtCJ/Mcl3knwH+D3g2fNc23sfg3/OL9uNcx8N/EsG3ahL7U7g6KHnTx5TZvT4Hc3jOxgkPACSHAAcCnx7iWPcXbcDrx5J0I+tqv/dXH/9Awbv0cFN4r6Pn3z4WdRSaLtxfhh6HZPsAxzFT15LqfdMvurCS4HtwDMZdKceBzyDQcI8Y7Rw0235Vgb/sMdKsn8zMOsTwBeBy5c8avgI8MYkByc5Cvg3Y8qcneSoJIcwuKY6d032Q8CZSY7L4FaoPwKuqapbJ4jjLmCx9wSfx+Bn+VmAJAcleWVz7PHANuC7wL5J3gwcOFL/MU1SnMSuzg/wL5O8PMm+wOuBBxkMzpP2CCZfdWEtg+uDt1XVd+Y24C+B32z+4Y66mEHLc9RfJrmfQUL4c+BjwMlNV+V8fj+PvM/3np2UHfY2Bl3H3wKuAD44psyHmmPfbLY/BKiqq4D/r4nvTgYDkk7bzXpHvRW4sOky/vVJTlBVlwHvBD6c5AfATcDcdfVPM7hm+/cMft4f8cju9I82X7+X5LoJqt/V+WHwIeo3gHsZDOJ6eXP9V9ojpGpRPUiSGkluBX63qv6261j6LMlbgadV1W91HYs0LbZ8JUlqmclXkqSW2e0sSVLLbPlKktQyk68kSS0bd0tHLz0mK2o/Duis/h8f2V3dcw496P5O61+57IFO6wdYvrtzYE1Jx9UDkI6j6Lr+WeArANfe+OA9VfWEaZz7xb90QH1v6/aJv//aGx/8dFWdvIQhLdgek3z34wBOyOrO6r/1tT/XWd1zXvVrn+20/pcdNMktn0vrny3rdgzDCpZ1Wj/A8nQbQ9f1z4J97FRk2RG3jJt+dUncs3U713z6qIm/f/kR39jVVKlT52+IJEkt22NavpKkvUWxfaeT2M0+k68kqVcK2LG49T06Z/KVJPXODvrd8vWaryRJLbPlK0nqlaLY3vPZGU2+kqTe8ZqvJEktKmC7yVeSpHb1veU7tQFXSS5IcneSm4b2HZLkyiS3NF8Pnud71zZlbkmydloxSpLUhWmOdn4/MDp35jnAVVV1LHBV8/wRkhwCvAU4AXgu8Jb5krQkae9TwPaqibdZMLXkW1WfB7aO7F4DXNg8vhB46ZhvfTFwZVVtrap7gSt5dBKXJO3FdiximwVtX/N9YlXdCVBVdyY5fEyZI4Hbh55vafY9SpJ1wDqA/dh/iUOVJM2iohxwNQXjVuMa+ypX1XpgPcCBOaTf74QkafcUbO/5f/y2Z7i6K8kRAM3Xu8eU2QIcPfT8KOCOFmKTJKkVbSffDcDc6OW1wCfGlPk08KIkBzcDrV7U7JMkqVlYod/XfKd5q9HFwBeApyfZkuQs4I+BX0lyC/ArzXOSrEryXoCq2gr8B+BLzfb2Zp8kSUDYvohtFkztmm9VnT7PodVjym4Efnfo+QXABVMKTZLUYwXs8JqvJElaiFkc7SxJ0k7NSvfxpEy+kqReGSysYPKVJKlVO8rkK0lSa/aElq8DriRJapnJV5LUK0XYzj4Tb7uS5Ogkn02yKcnNSV7X7H9rkm8nub7ZTh36njcm2Zzk60levKs67HaWJPXOlK/5bgPeUFXXJXk8cG2SK5tj766qPx0unOSZwGnAzwJPAv42yc9U1fb5KjD5SpJ6ZdrXfJvV9+ZW4Ls/ySbmWV2vsQb4cFU9CHwryWYG69F/Yb5vsNtZktQzYXvtM/EGHJZk49C2bt6akmOA5wDXNLtem+TGJBc06w/AApbCnWPLdw+yo+ej/5bC9up4zjnfArZX91PXL4vtCu3UPVW1aleFkjwO+Bjw+qr6QZJzGaw9UM3XPwN+hwUshTvH5CtJ6pXBqkbT/YCVZDmDxHtRVX0coKruGjr+18Anm6cLXgrXj4eSpN6Z5qpGSQKcD2yqqncN7T9iqNjLgJuaxxuA05KsSPIU4Fjgizurw5avJKlXqjJ37XZaTgJeBXwlyfXNvjcBpyc5jkHj+1bg1YN46uYkHwG+ymCk9Nk7G+kMJl9Jkh6hqv6O8ddxL9/J97wDeMfu1mHylST1Tt8HmJp8JUm9MrjPt99Dlky+kqSemfo136kz+UqSeqWNW42mrd/RS5LUQ7Z8JUm9s326CytMXSct3ySvS3JTs1TT68ccT5L3NMsz3Zjk+C7ilCTNnmkvKdiG1lu+SZ4F/GsGKz78GPhUkv9eVbcMFTuFwQwhxwInAOc2XyVJYkfPB1x1Ef0zgKur6oGq2gb8TwbTdA1bA3ygBq4GVo5M6yVJ2kvN3WrU55ZvF1HcBDw/yaFJ9gdO5ZETUsNuLs+UZN3cklAP8eDUApYkaSm13u1cVZuSvBO4EvghcAODuTCH7dbyTFW1HlgPcGAO6XgtOUlSG4o44GoSVXV+VR1fVc8HtgK3jBRZ8PJMkqS9xw72mXibBV2Ndj68+fpk4OXAxSNFNgBnNKOeTwTuq6o7Ww5TkjSDqmB77TPxNgu6us/3Y0kOBR5isPTSvUleA1BV5zFYOeJUYDPwAHBmR3FKkrTkOkm+VfULY/adN/S4gLNbDUqS1BNxVSNJktpUMDPdx5My+UqSemdW7tedlMlXktQrRdjhrUaSJGkhbPlKknrHbmdJklpU9H9hBZOvJKlnwnZvNZIkqT17Qsu339FLktRDtny1ZPo+9H8p7Hj04lsdxLCj0/r3YVmn9QNsr25fg573iPaC3c6SJLWoKr3vdjb5SpJ6p+/TS/Y7ekmSesiWrySpVwpc1UiSpHal993OJl9JUq8M7vO15StJUqv6Prdzv6OXJKmHbPlKknplT1jP1+QrSeqdHT3vuO0k+iS/l+TmJDcluTjJfiPHVyS5JMnmJNckOaaLOCVJs6cKtlcm3mZB68k3yZHA/wOsqqpnAcuA00aKnQXcW1VPA94NvLPdKCVJs2xHZeJtFnTVbt8XeGySfYH9gTtGjq8BLmweXwqsTjIbr5gkSYvU+jXfqvp2kj8FbgP+Cbiiqq4YKXYkcHtTfluS+4BDgXtaDVaSNHMGA6685rsgSQ5m0LJ9CvAk4IAkvzVabMy3PmqttiTrkmxMsvEhHlz6YCVJM2k7mXibBV18dPhl4FtV9d2qegj4OPBzI2W2AEcDNF3TBwFbR09UVeuralVVrVrOiimHLUmaBXMzXHnNd2FuA05Msn9zHXc1sGmkzAZgbfP4FcBnqqr7VcolSVoCXVzzvSbJpcB1wDbgy8D6JG8HNlbVBuB84INJNjNo8Y6OhpYk7bX6f823k0k2quotwFtGdr956PiPgFe2GpQkqTdcUlCSpBbNTbLRZyZfSVLv9L3bud/RS5LUQ7Z8JUm94qpGkiR1wAFXkiS1aG6SjT7zmq8kSS0z+UqSemdH7TPxtitJjk7y2SSbmrXnX9fsPyTJlUluab4e3OxPkvc0a9DfmOT4XdVh8pUk9csi5nXeze7qbcAbquoZwInA2UmeCZwDXFVVxwJXNc8BTgGObbZ1wLm7qsDkK0nqlWIw4GrSbZfnr7qzqq5rHt/PYP2BI3nkWvMXAi9tHq8BPlADVwMrkxyxszoccLVUZmDZh+0d33Q+C0t17eg6ALFjBv4Y9un4d3F7dfubuCx7frtqkQOuDkuycej5+qpaP65gkmOA5wDXAE+sqjthkKCTHN4Ue3gN+saWZt+d8wVg8pUk7W3uqapVuyqU5HHAx4DXV9UPBgvxjS86Zt9OP4WafCVJvdLGrUZJljNIvBdV1ceb3XclOaJp9R4B3N3sf3gN+sZRwB07O/+e3zchSdrjTHPAVbPW/PnApqp619Ch4bXm1wKfGNp/RjPq+UTgvrnu6fnY8pUk9UoL00ueBLwK+EqS65t9bwL+GPhIkrOA2/jJ0reXA6cCm4EHgDN3VYHJV5LUO9OcXrKq/o7x13EBVo8pX8DZC6nDbmdJklpmy1eS1C/V/7mdTb6SpF7ZExZWMPlKknqn78nXa76SJLWs9eSb5OlJrh/afpDk9SNlFrxChCRp7zB3q9EUF1aYuta7navq68BxAEmWAd8GLhspNrxCxAkMVog4ocUwJUkzrGYkiU6q62u+q4FvVNU/jOx/eIUI4OokK+em9Go/REnSrJnmfb5t6Dr5ngZcPGb/bq0QkWQdg7UT2Y/9pxSiJGmW1B5wq1FnA66SPAZ4CfDRcYfH7HvUChFVtb6qVlXVquWsWOoQJUmaii5bvqcA11XVXWOOLXiFCEnS3qPv13y7vNXodMZ3OcMEK0RIkvYWjnaeSJL9gV8BXj207zUAVXUeE6wQIUnae/S95dtJ8q2qB4BDR/adN/R4wStESJL2DnvC9JLOcCVJUsu6vtVIkqSFqcHtRn1m8pUk9Y6TbEiS1KKi/wOuvOYrSVLLbPlKknpmdu7XnZTJV5LUOw64kiSpZX2/5mvylST1SlX/k68DriRJapkt3z1I1wMQts/AZ7ntj155slUPsaPT+oExi2+2a/kMNEi6fhf26fhvYUdt77T+NnT9/26xTL6SpN5xwJUkSS3r+zVfk68kqVeK9D75dn+RTpKkvYwtX0lS7/T8kq/JV5LUM3vAfb4mX0lS//S86es1X0mSWmbLV5LUO3Y7S5LUsr5PstFJt3OSlUkuTfK1JJuSPG/keJK8J8nmJDcmOb6LOCVJs6cYtHwn3WZBVy3fvwA+VVWvSPIYYP+R46cAxzbbCcC5zVdJ0t6ugBlJopNqveWb5EDg+cD5AFX146r6/kixNcAHauBqYGWSI1oOVZKkqeii2/mpwHeB9yX5cpL3JjlgpMyRwO1Dz7c0+x4hybokG5NsfIgHpxexJGmmDNb0nWybBV0k332B44Fzq+o5wD8C54yUGdef8KiXrKrWV9Wqqlq1nBVLH6kkaTbVIrYZ0EXy3QJsqaprmueXMkjGo2WOHnp+FHBHC7FJkmbe5IOtZmXAVevJt6q+A9ye5OnNrtXAV0eKbQDOaEY9nwjcV1V3thmnJGmG9bzl29Vo538DXNSMdP4mcGaS1wBU1XnA5cCpwGbgAeDMjuKUJGnJdZJ8q+p6YNXI7vOGjhdwdqtBSZL6wYUVJEnqwIx0H0/K5CtJ6qF+t3xd1UiSpJbZ8pUk9Y/dzpIktczkK0lSi/aAhRVMvpKk3pmVOZon5YArSZKGJLkgyd1Jbhra99Yk305yfbOdOnTsjc36819P8uLdqcPkK0nqn+lOL/l+4OQx+99dVcc12+UASZ4JnAb8bPM9/znJsl1VYLfzEskMdIFs7/iz1EPV/We5hzp+H5bPwiiQ7Oi2/hl4Cbq2jy/C9E3xmm9VfT7JMbtZfA3w4ap6EPhWks3Ac4Ev7Oybuv9vKUnSAqUm34DD5taCb7Z1u1nta5Pc2HRLH9zs263150eZfCVJ/bKYLudB8r1nbi34Zlu/G7WeC/w0cBxwJ/Bnzf7dWn9+lMlXkqRdqKq7qmp7Ve0A/ppB1zJMuP68yVeS1DMZXPOddJukxuSIoacvA+ZGQm8ATkuyIslTgGOBL+7qfA64kiT1zxTHtCW5GHgBg2vDW4C3AC9IclxT863AqwGq6uYkHwG+CmwDzq6q7buqw+QrSeqfKSbfqjp9zO7zd1L+HcA7FlKH3c6SJLXMlq8kqX96fiu1yVeS1C8urCBJUvtmYVbBxegk+Sa5Fbgf2A5sq6pVI8cD/AVwKvAA8NtVdV3bcUqSZpTJd2K/VFX3zHPsFAb3Sh0LnMBgZpET2gpMkqRpWvBo5yQnJfmraQQzZA3wgRq4Glg5coOzJEm9tVvJN8lxSf6k6S7+Q+Bri6y3gCuSXDvPhNYTTVQtSdo7LHJhhc7N2+2c5GcYrFF4OvA94BIgVfVLS1DvSVV1R5LDgSuTfK2qPj9c/ZjvedRL1iTudQD7sf8ShCVJ6oWej3beWcv3a8Bq4P+sqp+vqv/EYIDUolXVHc3Xu4HL+MkE1XN2a6Lqqlo/tyrFclYsRWiSpFm3+FWNOrez5Pt/Ad8BPpvkr5OsZnyLdEGSHJDk8XOPgRfxkwmq52wAzsjAicB9VXXnYuuWJGkWzNvtXFWXAZc1CfKlwO8BT0xyLnBZVV0xYZ1PbM47V/+HqupTSV7T1HsecDmD24w2M7jV6MwJ65Ik7YlmpAU7qV3ealRV/whcBFyU5BDglcA5wETJt6q+CTx7zP7zhh4XcPYk55ck7flmZeDUpBZ0q1FVba2q/1JVL5xWQJIk7dIefM1XkiRNgXM7S5L6Z0ZasJMy+UqSemWWJsuYlMlXktQ/PZ9kw+QrSeqfnrd8HXAlSVLLbPlKknrHa76SJLXN5CtJUosc7ayH7eg6AHhwR7dv549qeaf1D2J4sOMIuv9FWN5xk+ChGWiS7O2DWZal3yOB9wYmX0lS/3T/GW9RTL6SpP4x+UqS1K6+X/Pd2y+NSJLUOpOvJEkts9tZktQ/Pe92NvlKkvrF+3wlSeqAyVeSpJb1PPk64EqSpJZ1lnyTLEvy5SSfHHNsRZJLkmxOck2SY9qPUJI0i8Lgmu+k2yzosuX7OmDTPMfOAu6tqqcB7wbe2VpUkqTZV4vYZkAnyTfJUcCvAu+dp8ga4MLm8aXA6sSZwiVJPDza2Zbvwv058PvMvwTMkcDtAFW1DbgPOHS0UJJ1STYm2fgQXa9mI0nS7mk9+Sb5NeDuqrp2Z8XG7HvU55WqWl9Vq6pq1XJWLFmMkqQZZ7fzgp0EvCTJrcCHgRcm+ZuRMluAowGS7AscBGxtM0hJ0gwz+S5MVb2xqo6qqmOA04DPVNVvjRTbAKxtHr+iKTMjL5kkqWt9v+Y7M5NsJHk7sLGqNgDnAx9MsplBi/e0ToOTJM2WGUmik+o0+VbV54DPNY/fPLT/R8Aru4lKkqTpmpmWryRJu2WGrt1OyuQrSeqdWbl2OymTrySpf0y+kiS1q+8tX1c1kiSpZbZ8JUn90/OWr8lXktQvjnaWJKldYfwCAH3iNV9JkoYkuSDJ3UluGtp3SJIrk9zSfD242Z8k70myOcmNSY7fnTpMvpKk/pnuwgrvB04e2XcOcFVVHQtc1TwHOAU4ttnWAefuTgV2Oy+RfbZ3HQF8/6HHdlr/d7cd2Gn9s2C/PNR1CCzPfMtkt2PZvMt0txlDtxcE9+n7fTA9MM2XuKo+n+SYkd1rgBc0jy9kMDXyHzT7P9As/nN1kpVJjqiqO3dWhy1fSVL/LK7le1iSjUPbut2o8YlzCbX5eniz/0jg9qFyW5p9O2XLV5LUP4tr+d5TVauWKJJxY792GZ0tX0mSdu2uJEcANF/vbvZvAY4eKncUcMeuTmbylST1Sw2u+U66TWgDsLZ5vBb4xND+M5pRzycC9+3qei/Y7SxJ6qMpDrhKcjGDwVWHJdkCvAX4Y+AjSc4CbuMna85fDpwKbAYeAM7cnTpMvpKk3pnyaOfT5zm0ekzZAs5eaB0mX0lS//T8bi6v+UqS1DJbvpKk3un7PCYmX0lSv+wBqxq13u2cZL8kX0xyQ5Kbk7xtTJkVSS5pJqq+Zsw0X5Kkvdl053aeui6u+T4IvLCqng0cB5zc3Bs17Czg3qp6GvBu4J0txyhJ0tS0nnxr4IfN0+XNNvpZZA2DiasBLgVWJ+n78o2SpCUQOplkY0l1Mto5ybIk1zOYnuvKqrpmpMjDE1VX1TbgPuDQMedZNzcx9kM8OO2wJUmzwm7nhauq7VV1HIM5MJ+b5FkjRXZrouqqWl9Vq6pq1XJWTCNUSdIMStXE2yzo9D7fqvo+gzURRxctfnii6iT7AgcBW1sNTpI0mxbT6p2N3NvJaOcnJFnZPH4s8MvA10aKDU9g/QrgM80UXpIk9V4X9/keAVyYZBmD5P+RqvpkkrcDG6tqA3A+8MEkmxm0eE/rIE5J0oyalYFTk2o9+VbVjcBzxux/89DjH/GTFSMkSXokk68kSe2y5StJUtt6nnxd1UiSpJbZ8pUk9csMzVQ1KZOvJKl/TL6SJLVnbm7nPvOaryRJLbPlK0nqn55PemjylST1Tt+7nU2+S2T5D7qOAG747pFdh9C5lcv/qdP6V+yzrdP6AZaxo9P695mB/4rL0u1r0LV9ZmI00rend+oZWiBhUiZfSVLv9P3zlQOuJElqmS1fSVL/2O0sSVK7ZmBowaKYfCVJ/VJ4q5EkSW3re8vXAVeSJLXMlq8kqX963vI1+UqSemVPWFjB5CtJ6peq3g+4av2ab5Kjk3w2yaYkNyd53ZgySfKeJJuT3Jjk+LbjlCRpWrpo+W4D3lBV1yV5PHBtkiur6qtDZU4Bjm22E4Bzm6+SJPW+27n1lm9V3VlV1zWP7wc2AaMrAqwBPlADVwMrkxzRcqiSpFlVi9hmQKfXfJMcAzwHuGbk0JHA7UPPtzT77mwlMEnSTOt7y7ez5JvkccDHgNdX1eiCfBnzLY96qZOsA9YB7Mf+Sx6jJGkGFbCj39m3k0k2kixnkHgvqqqPjymyBTh66PlRwB2jhapqfVWtqqpVy1kxnWAlSVpiXYx2DnA+sKmq3jVPsQ3AGc2o5xOB+6rKLmdJ0oDXfBfsJOBVwFeSXN/sexPwZICqOg+4HDgV2Aw8AJzZQZySpBnlNd8Fqqq/Y/w13eEyBZzdTkSSpN7p+SQbznAlSeqdvrd8XdVIkqSW2fKVJPXLDA2cmpTJV5LUK4NVjfqdfU2+kqT+2dF1AIvjNV9Jklpmy1eS1Dt2O0uS1CYHXEmS1LZykg1Jkto27Uk2ktwK3A9sB7ZV1aokhwCXAMcAtwK/XlX3TnJ+k+8SOfTmH3cdAt/j0E7r/8KB3dYPsGNZxwHMwBDG2unkrXsJX4MZ8N+6DmAp/FJV3TP0/Bzgqqr64yTnNM//YJITz8C/CkmSFqhq8m1ya4ALm8cXAi+d9EQmX0lSvxRkx+QbcFiSjUPbuvG1cEWSa4eOP3Fuedvm6+GT/gh2O0uS+mdxLdh7qmrVLsqcVFV3JDkcuDLJ1xZT4ShbvpIkjaiqO5qvdwOXAc8F7kpyBEDz9e5Jz2/ylST1Ty1i24UkByR5/Nxj4EXATcAGYG1TbC3wiUnDt9tZktQ7U57h6onAZUlgkCc/VFWfSvIl4CNJzgJuA145aQUmX0lS/0wx+VbVN4Fnj9n/PWD1UtRh8pUk9UvhqkaSJGlhbPlKknolVO9XNeqk5ZvkgiR3J7lpnuNJ8p4km5PcmOT4tmOUJM2wbma4WjJddTu/Hzh5J8dPAY5ttnXAuS3EJEnqC5PvwlXV54GtOymyBvhADVwNrJy7sVmStJebG3A16TYDZnXA1ZHA7UPPtzT7HiHJurm5OR/iwdaCkyRpMWZ1wNW4BcEe1VdQVeuB9QAH5pDZ6EuQJE1d3wdczWry3QIcPfT8KOCOjmKRJM2aniffWe123gCc0Yx6PhG4b24ZJ0nS3m4Rg61mJGl30vJNcjHwAgZrKm4B3gIsB6iq84DLgVOBzcADwJldxClJ0jR0knyr6vRdHC/g7JbCkST1STEzLdhJzeo1X0mS5jcjtwxNyuQrSeodRztLktS2niffWR3tLEnSHsuWrySpXwrY0e+Wr8lXktQzs3O/7qRMvpKk/jH5SpLUsp4nXz3jqIkAAAj2SURBVAdcSZLUMlu+kqR+ccCV5iy/YmPXIfDPrug6Akka2DzVsxdUv6e4MvlKkvrHa76SJGkhbPlKkvrFa76SJHWg593OJl9JUv+YfCVJalP/p5d0wJUkSS2z5StJ6pcCdnifryRJ7ep5t7PJV5LUPz1Pvp1c801ycpKvJ9mc5Jwxx1ckuaQ5fk2SY9qPUpI0m2pwn++k2wxoPfkmWQb8FXAK8Ezg9CTPHCl2FnBvVT0NeDfwznajlCRperpo+T4X2FxV36yqHwMfBtaMlFkDXNg8vhRYnSQtxihJmlUFVTsm3mZBF8n3SOD2oedbmn1jy1TVNuA+4NDREyVZl2Rjko0P8eCUwpUkzZyedzt3MeBqXAt29NXYnTJU1XpgPcCBOWQ2XlFJ0vQ54GrBtgBHDz0/CrhjvjJJ9gUOAra2Ep0kSVPWRfL9EnBskqckeQxwGrBhpMwGYG3z+BXAZ6p6/jFHkrQ0qgaTbEy6zYDWu52raluS1wKfBpYBF1TVzUneDmysqg3A+cAHk2xm0OI9re04JUkzrOftsU4m2aiqy4HLR/a9eejxj4BXth2XJKkfakZasJNyhitJUs+4qpEkSVogW76SpH4pZuZ+3UmZfCVJ/TMjM1VNyuQrSeqVAsqWryRJLarqfcvXAVeSJLXMlq8kqXfsdpYkqW0973bOnjJlcpLvAv+wyNMcBtyzBOFYf39j6Lr+WYih6/pnIYau65+FGBZb/09V1ROWKphhST7FIL5J3VNVJy9VPJPYY5LvUkiysapWWX93uo6h6/pnIYau65+FGLqufxZi6Lr+PZ0DriRJapnJV5Kklpl8H2m99Xeu6xi6rh+6j6Hr+qH7GLquH7qPoev692he85UkqWW2fCVJatlel3yTnJzk60k2JzlnzPEVSS5pjl+T5Jglrv+CJHcnuWme40nynqb+G5Mcv8T1H53ks0k2Jbk5yes6iGG/JF9MckMTw9vGlJnq+9DUsSzJl5N8sqP6b03ylSTXJ9k45vi034eVSS5N8rXm9+F5Ldf/9OZnn9t+kOT1Lcfwe83v4E1JLk6y38jxaf8/eF1T982jP3tzfMl//nH/g5IckuTKJLc0Xw+e53vXNmVuSbJ2sbHs1apqr9mAZcA3gKcCjwFuAJ45Uub/Bs5rHp8GXLLEMTwfOB64aZ7jpwL/AwhwInDNEtd/BHB88/jxwN+PeQ2mHUOAxzWPlwPXACe2+T405/1/gQ8BnxxzrI36bwUO28nxab8PFwK/2zx+DLCyzfpH6loGfIfBvaGtxAAcCXwLeGzz/CPAb7f1ewA8C7gJ2J/BhEd/Cxw77Z9/3P8g4E+Ac5rH5wDvHPN9hwDfbL4e3Dw+eFq/E3v6tre1fJ8LbK6qb1bVj4EPA2tGyqxh8E8J4FJgdZIsVQBV9Xlg606KrAE+UANXAyuTHLGE9d9ZVdc1j+8HNjH4J9RmDFVVP2yeLm+20cEHU30fkhwF/Crw3nmKTLX+3TS19yHJgQz+CZ8PUFU/rqrvt1X/GKuBb1TV6EQ5045hX+CxSfZlkATvGFP/tH4PngFcXVUPVNU24H8CLxtT/5L+/PP8Dxr+OS8EXjrmW18MXFlVW6vqXuBKoNOJKvpsb0u+RwK3Dz3fwqMTz8Nlmj+I+4BDW4lupP7GuBiXRNOF9hwGLc9WY2i6fK8H7mbwBz1vDFN6H/4c+H1gvjnq2vg9KOCKJNcmWbezGBpL+T48Ffgu8L6m6/29SQ5osf5RpwEXj9k/tRiq6tvAnwK3AXcC91XVFfPVP4Xfg5uA5yc5NMn+DFq5R89Xf2Na78ETq+pOGHxABw4fU6bN34c93t6WfMd9Yh1tce1OmWlqpf4kjwM+Bry+qn7QdgxVtb2qjgOOAp6b5FltxZDk14C7q+ranRWbVv1DTqqq44FTgLOTPL/FGPZl0PV4blU9B/hHBt2NbdX/k0qSxwAvAT467vC0Ymiua64BngI8CTggyW+1VX9VbQLeyaAF+SkGl8G2tVX/BGYplt7b25LvFh75yfIoHt3N9HCZpivqIHbeTbzUdifGRUmynEHivaiqPt5FDHOars7P8ejuq2m+DycBL0lyK4NLDy9M8jct1g9AVd3RfL0buIzBZZGxMTSW8n3YAmwZ6nG4lEEybqv+YacA11XVXWOOTTOGXwa+VVXfraqHgI8DPzdf/dP4Paiq86vq+Kp6fnPeW+arvzGt9+Cuue7s5uvdY8q09n9hb7C3Jd8vAccmeUrzafs0YMNImQ3A3Ci+VwCfqao2P91tAM5oRjmeyKAr7M6lOnlzvep8YFNVvaujGJ6QZGXz+LEM/gl+bUwMU3kfquqNVXVUVR3D4HfgM1U12uKZ6u9BkgOSPH7uMfAiBt2QozFM5X2oqu8Atyd5erNrNfDVtuofcTrju5ynHcNtwIlJ9m/+LlYzGAMxWv80fw8Ob74+GXg5j34d2noPhn/OtcAnxpT5NPCiJAc3vQYvavZpEl2O9upiY3Bd5e8ZjHr+d82+twMvaR7vx6D7azPwReCpS1z/xQyuLz3E4JPkWcBrgNc0xwP8VRPfV4BVS1z/zzPoKroRuL7ZTm05hn8BfLmJ4SbgzW2/D0OxvIBmtHPLvwdPZdDNeANw89DvYpvvw3HAxuZ9+K8MRrC2Vn9Tx/7A94CDhva1+Rq8jcEHv5uADwIrWv49+F8MPvTcAKxu4+ef53/QocBVDFreVwGHNGVXAe8d+t7faV6LzcCZS/37sDdtznAlSVLL9rZuZ0mSOmfylSSpZSZfSZJaZvKVJKllJl9Jklpm8pVmQJLtGazsc0OS65KMTvYgaQ/irUbSDEjyw6p6XPP4xcCbquoXOw5L0pTY8pVmz4HAvV0HIWl69u06AEnAYFm76xnMqHQE8MKO45E0RXY7SzNgpNv5eQzWGX5W+Qcq7ZHsdpZmTFV9ATgMeELXsUiaDpOvNGOS/HNgGYMFByTtgbzmK82GuWu+MFjJZm1Vbe8yIEnT4zVfSZJaZrezJEktM/lKktQyk68kSS0z+UqS1DKTryRJLTP5SpLUMpOvJEktM/lKktSy/x8jLl0oJAC/IwAAAABJRU5ErkJggg==\n" }, "metadata": { "needs_background": "light" - }, - "output_type": "display_data" + } } ], "source": [ @@ -811,12 +1005,11 @@ "\n", "#Create the Combinatorial Promoter\n", "Prom_AND = CombinatorialPromoter(\"combinatorial_promoter\",[A,B], tx_capable_list = [[A,B]], leak = True) #the Combination A and B can be transcribed\n", - "\n", "ANDAssembly = DNAassembly(\"AND\",promoter=Prom_AND,rbs=\"medium\",protein=\"GFP\")\n", - "\n", "#Use an Expression Mixture to focus on Logic, not Transcription & Translation\n", + "\n", "M = ExpressionExtract(name=\"expression\", parameter_file = \"default_parameters.txt\", components=[ANDAssembly])\n", - "CRN = M.compile_crn(); print(CRN.pretty_print())\n", + "CRN = M.compile_crn(); print(CRN.pretty_print(show_rates = True, show_keys = False))\n", "\n", "#Lets titrate A and B\n", "try:\n", @@ -833,7 +1026,7 @@ " for b_ind, B_c in enumerate(np.linspace(0, max_titration, N)):\n", " x0 = {str(ANDAssembly.dna):1, str(A):A_c, str(B):B_c}\n", " timepoints = np.linspace(0, 1000, 1000)\n", - " R = CRN.simulate_with_bioscrape(timepoints, initial_condition_dict = x0)\n", + " R = CRN.simulate_with_bioscrape_via_sbml(timepoints, initial_condition_dict = x0)\n", " HM[a_ind, b_ind] = R[\"protein_GFP\"][len(timepoints)-1]\n", "\n", " plt.title(\"AND Endpoint Heatmap\")\n", @@ -844,63 +1037,74 @@ " plt.xticks(np.arange(.5, N+.5, 1), [str(i) for i in np.linspace(0, max_titration, N)])\n", " plt.yticks(np.arange(.5, N+.5, 1), [str(i) for i in np.linspace(0, max_titration, N)])\n", "except ModuleNotFoundError:\n", - " print(\"Libraries needed for plotting and simulation not found.\")" + " print('please install the plotting libraries: pip install biocrnpyler[all]')" ] }, { "cell_type": "code", - "execution_count": 202, + "execution_count": 27, "metadata": { "slideshow": { "slide_type": "subslide" - } + }, + "tags": [] }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "Species (5) = {0. complex[2x_A:2x_B:dna[OR]], 1. complex[2x_A:dna[OR]], 2. complex[2x_B:dna[OR]], 3. dna[OR], 4. protein[GFP]}\n", + "Species (7) = {0. dna[OR], 1. complex[2x_A:dna[OR]], 2. protein[GFP], 3. complex[2x_B:dna[OR]], 4. complex[2x_A:2x_B:dna[OR]], 5. A, 6. B}\n", + "\n", "Reactions (7) = [\n", - "0. 2.0 A + complex[2x_B:dna[OR]] <--> complex[2x_A:2x_B:dna[OR]] \n", - " massaction: k_f(A,complex[2x_B:dna[OR]])=100.0*A^2.0*complex[2x_B:dna[OR]]\n", - " k_r(complex[2x_A:2x_B:dna[OR]])=10.0*complex[2x_A:2x_B:dna[OR]]\n", - "1. 2.0 A + dna[OR] <--> complex[2x_A:dna[OR]] \n", - " massaction: k_f(A,dna[OR])=100.0*A^2.0*dna[OR]\n", - " k_r(complex[2x_A:dna[OR]])=10.0*complex[2x_A:dna[OR]]\n", - "2. 2.0 B + complex[2x_A:dna[OR]] <--> complex[2x_A:2x_B:dna[OR]] \n", - " massaction: k_f(B,complex[2x_A:dna[OR]])=100.0*B^2.0*complex[2x_A:dna[OR]]\n", - " k_r(complex[2x_A:2x_B:dna[OR]])=10.0*complex[2x_A:2x_B:dna[OR]]\n", - "3. 2.0 B + dna[OR] <--> complex[2x_B:dna[OR]] \n", - " massaction: k_f(B,dna[OR])=100.0*B^2.0*dna[OR]\n", - " k_r(complex[2x_B:dna[OR]])=10.0*complex[2x_B:dna[OR]]\n", - "4. complex[2x_A:2x_B:dna[OR]] --> complex[2x_A:2x_B:dna[OR]] + protein[GFP] \n", - " massaction: k_f(complex[2x_A:2x_B:dna[OR]])=0.28125*complex[2x_A:2x_B:dna[OR]]\n", - "5. complex[2x_A:dna[OR]] --> complex[2x_A:dna[OR]] + protein[GFP] \n", - " massaction: k_f(complex[2x_A:dna[OR]])=0.28125*complex[2x_A:dna[OR]]\n", - "6. complex[2x_B:dna[OR]] --> complex[2x_B:dna[OR]] + protein[GFP] \n", - " massaction: k_f(complex[2x_B:dna[OR]])=0.28125*complex[2x_B:dna[OR]]\n", + "0. 2A+dna[OR] <--> complex[2x_A:dna[OR]]\n", + " Kf=k_forward * A^2 * dna_OR\n", + " Kr=k_reverse * complex_A_2x_dna_OR\n", + " k_forward=100.0\n", + " k_reverse=10.0\n", + "\n", + "1. 2B+dna[OR] <--> complex[2x_B:dna[OR]]\n", + " Kf=k_forward * B^2 * dna_OR\n", + " Kr=k_reverse * complex_B_2x_dna_OR\n", + " k_forward=100.0\n", + " k_reverse=10.0\n", + "\n", + "2. 2A+complex[2x_B:dna[OR]] <--> complex[2x_A:2x_B:dna[OR]]\n", + " Kf=k_forward * A^2 * complex_B_2x_dna_OR\n", + " Kr=k_reverse * complex_A_2x_B_2x_dna_OR\n", + " k_forward=100.0\n", + " k_reverse=10.0\n", + "\n", + "3. 2B+complex[2x_A:dna[OR]] <--> complex[2x_A:2x_B:dna[OR]]\n", + " Kf=k_forward * B^2 * complex_A_2x_dna_OR\n", + " Kr=k_reverse * complex_A_2x_B_2x_dna_OR\n", + " k_forward=100.0\n", + " k_reverse=10.0\n", + "\n", + "4. complex[2x_A:dna[OR]] --> complex[2x_A:dna[OR]]+protein[GFP]\n", + " Kf=k_forward * complex_A_2x_dna_OR\n", + " k_forward=0.28125\n", + "\n", + "5. complex[2x_B:dna[OR]] --> complex[2x_B:dna[OR]]+protein[GFP]\n", + " Kf=k_forward * complex_B_2x_dna_OR\n", + " k_forward=0.28125\n", + "\n", + "6. complex[2x_A:2x_B:dna[OR]] --> complex[2x_A:2x_B:dna[OR]]+protein[GFP]\n", + " Kf=k_forward * complex_A_2x_B_2x_dna_OR\n", + " k_forward=0.28125\n", + "\n", "]\n" ] }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - "C:\\ProgramData\\Anaconda3\\lib\\site-packages\\biocrnpyler-0.2.1-py3.7.egg\\biocrnpyler\\chemical_reaction_network.py:1089: UserWarning: The following species are uninitialized and their value has been defaulted to 0: A, B, \n" - ] - }, { "data": { - "image/png": "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\n", - "text/plain": [ - "
" - ] + "text/plain": "
", + "image/svg+xml": "\r\n\r\n\r\n\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n\r\n", + "image/png": "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\n" }, "metadata": { "needs_background": "light" - }, - "output_type": "display_data" + } } ], "source": [ @@ -909,11 +1113,11 @@ " tx_capable_list = [[A,B], [A], [B]]) #the Combinations A and B or just A or just B be transcribed\n", "\n", "ORassembly = DNAassembly(\"OR\",promoter=Prom_OR,rbs=\"medium\",protein=\"GFP\")\n", - "\n", + "print(ORassembly)\n", "#Use an Expression Mixture to focus on Logic, not Transcription & Translation\n", "M = ExpressionExtract(name=\"expression\", parameter_file = \"default_parameters.txt\", components=[ORassembly])\n", "CRN = M.compile_crn()\n", - "print(CRN.pretty_print())\n", + "print(CRN.pretty_print(show_rates = True, show_keys = False))\n", "\n", "#Lets titrate A and B\n", "try:\n", @@ -929,7 +1133,7 @@ " for b_ind, B_c in enumerate(np.linspace(0, max_titration, N)):\n", " x0 = {str(ORassembly.dna):1, str(A):A_c, str(B):B_c}\n", " timepoints = np.linspace(0, 1000, 1000)\n", - " R = CRN.simulate_with_bioscrape(timepoints, initial_condition_dict = x0)\n", + " R = CRN.simulate_with_bioscrape_via_sbml(timepoints, initial_condition_dict = x0)\n", " HM[a_ind, b_ind] = R[\"protein_GFP\"][len(timepoints)-1]\n", " plt.title(\"OR Endpoint Heatmap\")\n", " cb = plt.pcolor(HM)\n", @@ -940,61 +1144,70 @@ " plt.yticks(np.arange(.5, N+.5, 1), [str(i) for i in np.linspace(0, max_titration, N)])\n", " \n", "except ModuleNotFoundError:\n", - " print(\"Libraries needed for plotting and simulation not found.\")" + " print('please install the plotting libraries: pip install biocrnpyler[all]')" ] }, { "cell_type": "code", - "execution_count": 203, + "execution_count": 28, "metadata": { "slideshow": { "slide_type": "subslide" - } + }, + "tags": [] }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "Species (5) = {0. complex[2x_A:2x_B:dna[XOR]], 1. complex[2x_A:dna[XOR]], 2. complex[2x_B:dna[XOR]], 3. dna[XOR], 4. protein[GFP]}\n", + "Species (7) = {0. dna[XOR], 1. complex[2x_A:dna[XOR]], 2. protein[GFP], 3. complex[2x_B:dna[XOR]], 4. complex[2x_A:2x_B:dna[XOR]], 5. A, 6. B}\n", + "\n", "Reactions (6) = [\n", - "0. 2.0 A + complex[2x_B:dna[XOR]] <--> complex[2x_A:2x_B:dna[XOR]] \n", - " massaction: k_f(A,complex[2x_B:dna[XOR]])=100.0*A^2.0*complex[2x_B:dna[XOR]]\n", - " k_r(complex[2x_A:2x_B:dna[XOR]])=10.0*complex[2x_A:2x_B:dna[XOR]]\n", - "1. 2.0 A + dna[XOR] <--> complex[2x_A:dna[XOR]] \n", - " massaction: k_f(A,dna[XOR])=100.0*A^2.0*dna[XOR]\n", - " k_r(complex[2x_A:dna[XOR]])=10.0*complex[2x_A:dna[XOR]]\n", - "2. 2.0 B + complex[2x_A:dna[XOR]] <--> complex[2x_A:2x_B:dna[XOR]] \n", - " massaction: k_f(B,complex[2x_A:dna[XOR]])=100.0*B^2.0*complex[2x_A:dna[XOR]]\n", - " k_r(complex[2x_A:2x_B:dna[XOR]])=10.0*complex[2x_A:2x_B:dna[XOR]]\n", - "3. 2.0 B + dna[XOR] <--> complex[2x_B:dna[XOR]] \n", - " massaction: k_f(B,dna[XOR])=100.0*B^2.0*dna[XOR]\n", - " k_r(complex[2x_B:dna[XOR]])=10.0*complex[2x_B:dna[XOR]]\n", - "4. complex[2x_A:dna[XOR]] --> complex[2x_A:dna[XOR]] + protein[GFP] \n", - " massaction: k_f(complex[2x_A:dna[XOR]])=0.28125*complex[2x_A:dna[XOR]]\n", - "5. complex[2x_B:dna[XOR]] --> complex[2x_B:dna[XOR]] + protein[GFP] \n", - " massaction: k_f(complex[2x_B:dna[XOR]])=0.28125*complex[2x_B:dna[XOR]]\n", + "0. 2A+dna[XOR] <--> complex[2x_A:dna[XOR]]\n", + " Kf=k_forward * A^2 * dna_XOR\n", + " Kr=k_reverse * complex_A_2x_dna_XOR\n", + " k_forward=100.0\n", + " k_reverse=10.0\n", + "\n", + "1. 2B+dna[XOR] <--> complex[2x_B:dna[XOR]]\n", + " Kf=k_forward * B^2 * dna_XOR\n", + " Kr=k_reverse * complex_B_2x_dna_XOR\n", + " k_forward=100.0\n", + " k_reverse=10.0\n", + "\n", + "2. 2A+complex[2x_B:dna[XOR]] <--> complex[2x_A:2x_B:dna[XOR]]\n", + " Kf=k_forward * A^2 * complex_B_2x_dna_XOR\n", + " Kr=k_reverse * complex_A_2x_B_2x_dna_XOR\n", + " k_forward=100.0\n", + " k_reverse=10.0\n", + "\n", + "3. 2B+complex[2x_A:dna[XOR]] <--> complex[2x_A:2x_B:dna[XOR]]\n", + " Kf=k_forward * B^2 * complex_A_2x_dna_XOR\n", + " Kr=k_reverse * complex_A_2x_B_2x_dna_XOR\n", + " k_forward=100.0\n", + " k_reverse=10.0\n", + "\n", + "4. complex[2x_A:dna[XOR]] --> complex[2x_A:dna[XOR]]+protein[GFP]\n", + " Kf=k_forward * complex_A_2x_dna_XOR\n", + " k_forward=0.28125\n", + "\n", + "5. complex[2x_B:dna[XOR]] --> complex[2x_B:dna[XOR]]+protein[GFP]\n", + " Kf=k_forward * complex_B_2x_dna_XOR\n", + " k_forward=0.28125\n", + "\n", "]\n" ] }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - "C:\\ProgramData\\Anaconda3\\lib\\site-packages\\biocrnpyler-0.2.1-py3.7.egg\\biocrnpyler\\chemical_reaction_network.py:1089: UserWarning: The following species are uninitialized and their value has been defaulted to 0: A, B, \n" - ] - }, { "data": { - "image/png": "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\n", - "text/plain": [ - "
" - ] + "text/plain": "
", + "image/svg+xml": "\r\n\r\n\r\n\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n\r\n", + "image/png": "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\n" }, "metadata": { "needs_background": "light" - }, - "output_type": "display_data" + } } ], "source": [ @@ -1007,7 +1220,7 @@ "#Use an Expression Mixture to focus on Logic, not Transcription & Translation\n", "M = ExpressionExtract(name=\"expression\", parameter_file = \"default_parameters.txt\", components=[XORassembly])\n", "CRN = M.compile_crn()\n", - "print(CRN.pretty_print())\n", + "print(CRN.pretty_print(show_rates = True, show_keys = False))\n", "\n", "#Lets titrate A and B\n", "try:\n", @@ -1024,7 +1237,7 @@ " for b_ind, B_c in enumerate(np.linspace(0, max_titration, N)):\n", " x0 = {str(XORassembly.dna):1, str(A):A_c, str(B):B_c}\n", " timepoints = np.linspace(0, 1000, 1000)\n", - " R = CRN.simulate_with_bioscrape(timepoints, initial_condition_dict = x0)\n", + " R = CRN.simulate_with_bioscrape_via_sbml(timepoints, initial_condition_dict = x0)\n", " HM[a_ind, b_ind] = R[\"protein_GFP\"][len(timepoints)-1]\n", " plt.title(\"XOR Endpoint Heatmap\")\n", " cb = plt.pcolor(HM)\n", @@ -1036,7 +1249,7 @@ " plt.yticks(np.arange(.5, N+.5, 1), [str(i) for i in np.linspace(0, max_titration, N)])\n", " \n", "except ModuleNotFoundError:\n", - " print(\"Libraries needed for plotting and simulation not found.\")" + " print('please install the plotting libraries: pip install biocrnpyler[all]')" ] }, { @@ -1064,9 +1277,9 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.7.4" + "version": "3.7.6-final" } }, "nbformat": 4, "nbformat_minor": 4 -} +} \ No newline at end of file diff --git a/examples/5. Parameters.ipynb b/examples/5. Parameters.ipynb index 211f31fb..46d21d6c 100644 --- a/examples/5. Parameters.ipynb +++ b/examples/5. Parameters.ipynb @@ -4,22 +4,65 @@ "cell_type": "markdown", "metadata": {}, "source": [ + "## Parameters in BioCRNpyler\n", + "BioCRNpyler has a flexible parameter system allowing for models to be rapidly produced using very few parameters common across many reactions and then refined so that each mechanisms and components have unique reaction parameters derived from the literature or experiments. This parameter system is designed to work automatically, so all users have to do is specify a parameter file of the proper format or a parameter dictionary which can be loaded into Mixtures and Components using the parameter_file and/or parameters (for dictionaries) keywords. Parameters from multiple sources can be used together.\n", + "\n", + "Parameters passed into a Component supercede mixture level parameters in reactions produced by that Component.\n", + "\n", "#### Parameter File Overview:\n", - "Parameter files can be TSVs or CSVs. The first line of the file should contain column headings. The following headings are required (in any order): mechanism_id, part_id, param_name, param_val (spaces can be substituted for underscores and headings are not case sensitive). mechanism_id is the name of the Mechanism or the kind of mechanism that will use this parameter, for example \"transcription\" or \"transcription_mm\" for Mechalis-Menten transcription would go in this column. part_id refers to the name supplied by the Component that will use this mechanism, for example \"ptet\" for a tet repressed promoter and \"ptet_leak\" for leak reactions of that promoter. param_name refers to the name of the model parameter, for example \"ktx\", \"kb\", or \"ku\". The value of these columns is case sensitive and underscores are different from spaces.\n", + "Parameter files can be .tsv (or .txt) or .csv. The first line of the file should contain column headings. The following headings are required (in any order): mechanism_id, part_id, param_name, param_val (spaces can be substituted for underscores and headings are not case sensitive). mechanism_id is the name of the Mechanism or the kind of mechanism that will use this parameter, for example \"transcription\" or \"transcription_mm\" for Mechalis-Menten transcription would go in this column. part_id refers to the name supplied by the Component that will use this mechanism, for example \"ptet\" for a tet repressed promoter and \"ptet_leak\" for leak reactions of that promoter. param_name refers to the name of the model parameter, for example \"ktx\", \"kb\", or \"ku\". The value of these columns is case sensitive and underscores are different from spaces. All these parameter headings (if they are not empty) are required to be alpha-numeric (plus single internal underscores) and start with a letter.\n", + "\n", + "\n", + "#### Viewing Parameters Used in a Model\n", + "The easiest way to examine which parameter values are used in a Model and where BioCRNpyler found them is with the prett_print function of a ChemicalReactionNetwork or a Reaction with show_rates and show_keys both set to True.\n", + " \n", + " CRN.prett_print(show_rates = True, show_keys = True)\n", + "\n", + "show_rates toggles whether reaction rates are shown. The parameter values used in the rates will be shown below the rate function. show_keys toggles whether the ParameterKey used to search and find these rates is displayed. search_key is the key the Mechanism and component searched for in order to find the rate. found_key is the key the parameter was found in after defaulting.\n", + "\n", + "\n", + "\n", + "#### Parameter Dictionary Overview:\n", + "A parameter dictionary should have the following forms (note that part_id and mechanism can be None):\n", + "\n", + "Using ParameterKeys (named tuples):\n", + "\n", + " parameters = {ParameterKey(mechanism = \"mechanism_name\", part_id = \"part_id\", name = \"parameter_name\"):param_val ...} #using ParameterKeys\n", + " \n", + "Using tuples or even just strings (for default parameters) shorthand is also valid:\n", + "\n", + " parameters = {(\"mechanism_name\", \"part_id\", \"parameter_name\"):val1, \"k\":default_val ...} \n", "\n", "#### Parameter Value Defaulting:\n", - "Not all parameters need to have the required headings. The only two required columns are \"param_val\" and \"param_name\". BioCRNpyler uses a form of parameter name defaulting discussed below to find default parameters if no exact match is in the config file. This makes it easy to set default parameters for things like \"ku\" and \"ktx\" to quickly build models.\n", + "Parameters can be passed into Components and Mixtures as both files and/or dictionaries. Parameters into Components will be used by reactions created by that Component:\n", + "\n", + " Component(... parameters = parameters, parameter_file = \"file_name\" ...)\n", + "\n", + "If a Component cannot find its own parameters, it will use parameters passed into the Mixture:\n", + "\n", + " Mixture(... parameters = parameters, parameter_file = \"file_name\" ...)\n", + "\n", + "At both the Mixture and Component levels, BioCRNpyler does nto require an exact keyword match. When Mechanisms are called by Components to produce reactions, they will initially look for\n", "\n", - "#### Parameters inside BioCRNpyler:\n", - "Inside of bioCRNpyler, parameters are stored as a dictionary key value pair: (mechanism_name, part_id, param_name) --> param_val. If that particular parameter key cannot be found, the software will default to the following keys: (mechanism_type, part_id, param_name) >> (part_id, param_name) >> (mechanism_name, param_name) >> (mechanism_type, param_name) >>(param_name) and give a warning. As a note, mechanism_name refers to the .name variable of a Mechanism. mechanism_type refers to the .type variable of a Mechanism. Either of these can be used as a mechanism_id. This allows for models to be constructed easily using default parameter values and for parameters to be shared between different Mechanisms and/or Components.\n", + " ParameterKey(mechanism = \"mechanism_name\", part_id = \"part_id\", name = \"parameter_name\") --> param_val. \n", + "\n", + "If that particular parameter key cannot be found, the software will default to the following keys in this order: \n", + "\n", + " ParameterKey(mechanism = \"mechanism_type\", part_id = \"part_id\" , name = \"parameter_name\")\n", + " ParameterKey(mechanism = None, part_id = \"part_id\" , name = \"parameter_name\")\n", + " ParameterKey(mechanism = \"mechanism_name\", part_id = None , name = \"parameter_name\")\n", + " ParameterKey(mechanism = \"mechanism_type\", part_id = None , name = \"parameter_name\")\n", + " ParameterKey(mechanism = None, part_id = None , name = \"parameter_name\")\n", + " \n", + "As a note, mechanism_name refers to the .name variable of a Mechanism. mechanism_type refers to the .type variable of a Mechanism. Either of these can be used as a mechanism_id. This allows for models to be constructed easily using default parameter values and for parameters to be shared between different Mechanisms and/or Components.\n", + "\n", + "#### The ParameterDatabase and ParameterEntries\n", + "Each Component and Mixture has its own ParameterDatabase full of ParameterEntries. In general, users are not expected to make these objects by hand. Instead, ParameterDatabases will be automatically populated with ParameterEntries using either a parameter_file or parameter_dictionary. However, they can be accessed and view by looking at Component.parameter_database and Mixture.parameter_database\n", "\n", "#### Multiple Parameter Files:\n", "Components and Mixtures can both have one more multiple parameter files by passing in a list of filenames instead of a single filename to the parameter_file keyword. Components use parameters loaded from their file(s) before defaulting to the file(s) supplied to a Mixture. The last file in any list will take precedent and overwrite parameter files which were written earlier.\n", "\n", - "#### Suppressing warnings\n", - "To suppress parameter warnings, use the keyword parameter_warnings = False inside a Mixture or Component constructor.\n", - "\n", - "Below is an example csv with all the parameters for a tetR promoter undergoing Michalis Menten transcription and translation." + "Below is an example csv with all the parameters for a tetR promoter undergoing Michaelis Menten transcription and translation." ] }, { @@ -32,7 +75,7 @@ }, { "cell_type": "code", - "execution_count": 1, + "execution_count": 2, "metadata": {}, "outputs": [ { @@ -44,9 +87,9 @@ "transcription_mm\tptet_tetR\tkb\t10.\textra columns are okay!\n", "transcription_mm\tptet_tetR\tku\t.1\tThese are the parameters for transcription\n", "transcription_mm\tptet_tetR\tktx\t1.\t\t\n", - "transcription_mm\tptet\tktx\t.1\tThese are the parameters for transcription leak\n", - "transcription_mm\tptet\tku\t.1\t\t\n", - "transcription_mm\tptet\tkb\t.1\t\t\n", + "transcription_mm\tptet_leak\tktx\t.1\tThese are the parameters for transcription leak\n", + "transcription_mm\tptet_leak\tku\t.1\t\t\n", + "transcription_mm\tptet_leak\tkb\t.1\t\t\n", "one_step_cooperative_binding\tptet_tetR\tku\t.1\tThese are parameters for tetR dimerization and binding with the promoter\t\n", "one_step_cooperative_binding\tptet_tetR\tkb\t.1\n", "one_step_cooperative_binding\tptet_tetR\tcooperativity\t2\n", @@ -55,43 +98,7 @@ "translation_mm\tBCD\tkb\t10\n", "rna_degredation_mm\t\tkb\t10\tThese are parameters for RNA degredation. \n", "rna_degredation_mm\t\tku\t.5\tThey will be the same for all RNAs because of parameter defaulting.\n", - "rna_degredation_mm\t\tkdeg\t1.5\t\t\n", - "\n", - "****Loaded Parameters****\n", - "param_dict[('transcription_mm', 'ptet_tetR', 'kb')] = 10.0\n", - "param_dict[('transcription_mm', 'ptet_tetR', 'ku')] = 0.1\n", - "param_dict[('transcription_mm', 'ptet_tetR', 'ktx')] = 1.0\n", - "param_dict[('transcription_mm', 'ptet', 'ktx')] = 0.1\n", - "param_dict[('transcription_mm', 'ptet', 'ku')] = 0.1\n", - "param_dict[('transcription_mm', 'ptet', 'kb')] = 0.1\n", - "param_dict[('one_step_cooperative_binding', 'ptet_tetR', 'ku')] = 0.1\n", - "param_dict[('one_step_cooperative_binding', 'ptet_tetR', 'kb')] = 0.1\n", - "param_dict[('one_step_cooperative_binding', 'ptet_tetR', 'cooperativity')] = 2.0\n", - "param_dict[('translation_mm', 'BCD', 'ktl')] = 2.0\n", - "param_dict[('translation_mm', 'BCD', 'ku')] = 0.25\n", - "param_dict[('translation_mm', 'BCD', 'kb')] = 10.0\n", - "param_dict[('rna_degredation_mm', 'kb')] = 10.0\n", - "param_dict[('rna_degredation_mm', 'ku')] = 0.5\n", - "param_dict[('rna_degredation_mm', 'kdeg')] = 1.5\n", - "\n", - "****Resulting CRN****\n" - ] - }, - { - "ename": "ValueError", - "evalue": "No parameters can be found that match the (mechanism, part_id, param_name)=(transcription_mm, ptet_leak, ktx)", - "output_type": "error", - "traceback": [ - "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", - "\u001b[1;31mValueError\u001b[0m Traceback (most recent call last)", - "\u001b[1;32m\u001b[0m in \u001b[0;36m\u001b[1;34m\u001b[0m\n\u001b[0;32m 23\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 24\u001b[0m \u001b[0mprint\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;34m\"\\n****Resulting CRN****\"\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m---> 25\u001b[1;33m \u001b[0mprint\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mmyMixture\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mcompile_crn\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m", - "\u001b[1;32mC:\\ProgramData\\Anaconda3\\lib\\site-packages\\biocrnpyler-0.2.1-py3.7.egg\\biocrnpyler\\mixture.py\u001b[0m in \u001b[0;36mcompile_crn\u001b[1;34m(self)\u001b[0m\n\u001b[0;32m 268\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 269\u001b[0m \u001b[0mspecies\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mupdate_species\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m--> 270\u001b[1;33m \u001b[0mreactions\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mupdate_reactions\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 271\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 272\u001b[0m \u001b[1;31m#global mechanisms are applied last and only to all the species\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n", - "\u001b[1;32mC:\\ProgramData\\Anaconda3\\lib\\site-packages\\biocrnpyler-0.2.1-py3.7.egg\\biocrnpyler\\mixture.py\u001b[0m in \u001b[0;36mupdate_reactions\u001b[1;34m(self)\u001b[0m\n\u001b[0;32m 236\u001b[0m \u001b[1;32mif\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mparameter_warnings\u001b[0m \u001b[1;32mis\u001b[0m \u001b[1;32mnot\u001b[0m \u001b[1;32mNone\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 237\u001b[0m \u001b[0mcomponent\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mset_parameter_warnings\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mparameter_warnings\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m--> 238\u001b[1;33m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mcrn_reactions\u001b[0m \u001b[1;33m+=\u001b[0m \u001b[0mcomponent\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mupdate_reactions\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 239\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 240\u001b[0m \u001b[1;32mreturn\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mcrn_reactions\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n", - "\u001b[1;32mC:\\ProgramData\\Anaconda3\\lib\\site-packages\\biocrnpyler-0.2.1-py3.7.egg\\biocrnpyler\\dna_assembly.py\u001b[0m in \u001b[0;36mupdate_reactions\u001b[1;34m(self)\u001b[0m\n\u001b[0;32m 151\u001b[0m \u001b[1;32mif\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mpromoter\u001b[0m \u001b[1;32mis\u001b[0m \u001b[1;32mnot\u001b[0m \u001b[1;32mNone\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 152\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mpromoter\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mparameter_warnings\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mparameter_warnings\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m--> 153\u001b[1;33m \u001b[0mreactions\u001b[0m \u001b[1;33m+=\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mpromoter\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mupdate_reactions\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 154\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 155\u001b[0m \u001b[1;32mif\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mrbs\u001b[0m \u001b[1;32mis\u001b[0m \u001b[1;32mnot\u001b[0m \u001b[1;32mNone\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n", - "\u001b[1;32mC:\\ProgramData\\Anaconda3\\lib\\site-packages\\biocrnpyler-0.2.1-py3.7.egg\\biocrnpyler\\dna_assembly_promoter.py\u001b[0m in \u001b[0;36mupdate_reactions\u001b[1;34m(self)\u001b[0m\n\u001b[0;32m 93\u001b[0m \u001b[1;32mif\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mleak\u001b[0m \u001b[1;33m!=\u001b[0m \u001b[1;32mFalse\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 94\u001b[0m reactions += mech_tx.update_reactions(dna = self.assembly.dna, component = self, part_id = self.name+\"_leak\", \\\n\u001b[1;32m---> 95\u001b[1;33m transcript = self.transcript, protein = self.assembly.protein)\n\u001b[0m\u001b[0;32m 96\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 97\u001b[0m \u001b[1;32mfor\u001b[0m \u001b[0mi\u001b[0m \u001b[1;32min\u001b[0m \u001b[0mrange\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mlen\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mregulators\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n", - "\u001b[1;32mC:\\ProgramData\\Anaconda3\\lib\\site-packages\\biocrnpyler-0.2.1-py3.7.egg\\biocrnpyler\\mechanisms_txtl.py\u001b[0m in \u001b[0;36mupdate_reactions\u001b[1;34m(self, dna, component, part_id, complex, transcript, **keywords)\u001b[0m\n\u001b[0;32m 45\u001b[0m \u001b[0mpart_id\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mcomponent\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mname\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 46\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m---> 47\u001b[1;33m \u001b[0mktx\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mcomponent\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mget_parameter\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;34m\"ktx\"\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mpart_id\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mpart_id\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mmechanism\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 48\u001b[0m \u001b[0mkb\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mcomponent\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mget_parameter\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;34m\"kb\"\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mpart_id\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mpart_id\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mmechanism\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 49\u001b[0m \u001b[0mku\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mcomponent\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mget_parameter\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;34m\"ku\"\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mpart_id\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mpart_id\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mmechanism\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n", - "\u001b[1;32mC:\\ProgramData\\Anaconda3\\lib\\site-packages\\biocrnpyler-0.2.1-py3.7.egg\\biocrnpyler\\component.py\u001b[0m in \u001b[0;36mget_parameter\u001b[1;34m(self, param_name, part_id, mechanism)\u001b[0m\n\u001b[0;32m 235\u001b[0m f\"found under the key param_name={param_name}\")\n\u001b[0;32m 236\u001b[0m \u001b[1;32mif\u001b[0m \u001b[0mreturn_val\u001b[0m \u001b[1;32mis\u001b[0m \u001b[1;32mNone\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m--> 237\u001b[1;33m raise ValueError(\"No parameters can be found that match the \"\n\u001b[0m\u001b[0;32m 238\u001b[0m \u001b[1;34m\"(mechanism, part_id, \"\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 239\u001b[0m \u001b[1;34mf\"param_name)=({repr(mechanism)}, {part_id}, \"\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n", - "\u001b[1;31mValueError\u001b[0m: No parameters can be found that match the (mechanism, part_id, param_name)=(transcription_mm, ptet_leak, ktx)" + "rna_degredation_mm\t\tkdeg\t1.5\t\t\n" ] } ], @@ -103,24 +110,146 @@ "param_file = open(perfect_param_file_name)\n", "print(\"****Parameter File****\")\n", "print(param_file.read())\n", - "param_file.close()\n", - "\n", - "\n", + "param_file.close()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Use this parameter file to create a CRN" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "****Loaded Parameters****\n", + "ParameterKey(mechanism='transcription_mm', part_id='ptet_tetR', name='kb') ==> 10.0\n", + "ParameterKey(mechanism='transcription_mm', part_id='ptet_tetR', name='ku') ==> 0.1\n", + "ParameterKey(mechanism='transcription_mm', part_id='ptet_tetR', name='ktx') ==> 1.0\n", + "ParameterKey(mechanism='transcription_mm', part_id='ptet_leak', name='ktx') ==> 0.1\n", + "ParameterKey(mechanism='transcription_mm', part_id='ptet_leak', name='ku') ==> 0.1\n", + "ParameterKey(mechanism='transcription_mm', part_id='ptet_leak', name='kb') ==> 0.1\n", + "ParameterKey(mechanism='one_step_cooperative_binding', part_id='ptet_tetR', name='ku') ==> 0.1\n", + "ParameterKey(mechanism='one_step_cooperative_binding', part_id='ptet_tetR', name='kb') ==> 0.1\n", + "ParameterKey(mechanism='one_step_cooperative_binding', part_id='ptet_tetR', name='cooperativity') ==> 2.0\n", + "ParameterKey(mechanism='translation_mm', part_id='BCD', name='ktl') ==> 2.0\n", + "ParameterKey(mechanism='translation_mm', part_id='BCD', name='ku') ==> 0.25\n", + "ParameterKey(mechanism='translation_mm', part_id='BCD', name='kb') ==> 10.0\n", + "ParameterKey(mechanism='rna_degredation_mm', part_id=None, name='kb') ==> 10.0\n", + "ParameterKey(mechanism='rna_degredation_mm', part_id=None, name='ku') ==> 0.5\n", + "ParameterKey(mechanism='rna_degredation_mm', part_id=None, name='kdeg') ==> 1.5\n", + "\n", + "****Resulting CRN****\n", + "Notice that the found_key perfectly matches the search_key.\n", + "\n", + "Species (12) = {0. [dna[reporter]:2x_protein[tetR]], 1. complex[[dna[reporter]:2x_protein[tetR]]:protein[RNAP]], 2. protein[tetR], 3. protein[RNAP], 4. protein[reporter], 5. complex[protein[RNAase]:rna[reporter]], 6. complex[dna[reporter]:protein[RNAP]], 7. protein[RNAase], 8. rna[reporter], 9. complex[protein[Ribo]:rna[reporter]], 10. dna[reporter], 11. protein[Ribo]}\n", + "Reactions (9) = [\n", + "0. dna[reporter]+protein[RNAP] <--> complex[dna[reporter]:protein[RNAP]]\n", + " Kf=k_forward * dna_reporter * protein_RNAP\n", + " Kr=k_reverse * complex_dna_reporter_protein_RNAP\n", + " k_forward=0.1\n", + " found_key=(mech=transcription_mm, partid=ptet_leak, name=kb).\n", + " search_key=(mech=transcription_mm, partid=ptet_leak, name=kb.\n", + " k_reverse=0.1\n", + " found_key=(mech=transcription_mm, partid=ptet_leak, name=ku).\n", + " search_key=(mech=transcription_mm, partid=ptet_leak, name=ku.\n", + "\n", + "1. complex[dna[reporter]:protein[RNAP]] --> dna[reporter]+rna[reporter]+protein[RNAP]\n", + " Kf=k_forward * complex_dna_reporter_protein_RNAP\n", + " k_forward=0.1\n", + " found_key=(mech=transcription_mm, partid=ptet_leak, name=ktx).\n", + " search_key=(mech=transcription_mm, partid=ptet_leak, name=ktx.\n", + " k_reverse=None\n", + "\n", + "2. 2protein[tetR]+dna[reporter] <--> [dna[reporter]:2x_protein[tetR]]\n", + " Kf=k_forward * protein_tetR^2 * dna_reporter\n", + " Kr=k_reverse * dna_reporter_2x_protein_tetR\n", + " k_forward=0.1\n", + " found_key=(mech=one_step_cooperative_binding, partid=ptet_tetR, name=kb).\n", + " search_key=(mech=one_step_cooperative_binding, partid=ptet_tetR, name=kb.\n", + " k_reverse=0.1\n", + " found_key=(mech=one_step_cooperative_binding, partid=ptet_tetR, name=ku).\n", + " search_key=(mech=one_step_cooperative_binding, partid=ptet_tetR, name=ku.\n", + "\n", + "3. [dna[reporter]:2x_protein[tetR]]+protein[RNAP] <--> complex[[dna[reporter]:2x_protein[tetR]]:protein[RNAP]]\n", + " Kf=k_forward * dna_reporter_2x_protein_tetR * protein_RNAP\n", + " Kr=k_reverse * complex_dna_reporter_2x_protein_tetR_protein_RNAP\n", + " k_forward=10.0\n", + " found_key=(mech=transcription_mm, partid=ptet_tetR, name=kb).\n", + " search_key=(mech=transcription_mm, partid=ptet_tetR, name=kb.\n", + " k_reverse=0.1\n", + " found_key=(mech=transcription_mm, partid=ptet_tetR, name=ku).\n", + " search_key=(mech=transcription_mm, partid=ptet_tetR, name=ku.\n", + "\n", + "4. complex[[dna[reporter]:2x_protein[tetR]]:protein[RNAP]] --> [dna[reporter]:2x_protein[tetR]]+rna[reporter]+protein[RNAP]\n", + " Kf=k_forward * complex_dna_reporter_2x_protein_tetR_protein_RNAP\n", + " k_forward=1.0\n", + " found_key=(mech=transcription_mm, partid=ptet_tetR, name=ktx).\n", + " search_key=(mech=transcription_mm, partid=ptet_tetR, name=ktx.\n", + " k_reverse=None\n", + "\n", + "5. rna[reporter]+protein[Ribo] <--> complex[protein[Ribo]:rna[reporter]]\n", + " Kf=k_forward * rna_reporter * protein_Ribo\n", + " Kr=k_reverse * complex_protein_Ribo_rna_reporter\n", + " k_forward=10.0\n", + " found_key=(mech=translation_mm, partid=BCD, name=kb).\n", + " search_key=(mech=translation_mm, partid=BCD, name=kb.\n", + " k_reverse=0.25\n", + " found_key=(mech=translation_mm, partid=BCD, name=ku).\n", + " search_key=(mech=translation_mm, partid=BCD, name=ku.\n", + "\n", + "6. complex[protein[Ribo]:rna[reporter]] --> rna[reporter]+protein[reporter]+protein[Ribo]\n", + " Kf=k_forward * complex_protein_Ribo_rna_reporter\n", + " k_forward=2.0\n", + " found_key=(mech=translation_mm, partid=BCD, name=ktl).\n", + " search_key=(mech=translation_mm, partid=BCD, name=ktl.\n", + " k_reverse=None\n", + "\n", + "7. rna[reporter]+protein[RNAase] <--> complex[protein[RNAase]:rna[reporter]]\n", + " Kf=k_forward * rna_reporter * protein_RNAase\n", + " Kr=k_reverse * complex_protein_RNAase_rna_reporter\n", + " k_forward=10.0\n", + " found_key=(mech=rna_degredation_mm, partid=None, name=kb).\n", + " search_key=(mech=rna_degredation_mm, partid=reporter, name=kb.\n", + " k_reverse=0.5\n", + " found_key=(mech=rna_degredation_mm, partid=None, name=ku).\n", + " search_key=(mech=rna_degredation_mm, partid=reporter, name=ku.\n", + "\n", + "8. complex[protein[RNAase]:rna[reporter]] --> protein[RNAase]\n", + " Kf=k_forward * complex_protein_RNAase_rna_reporter\n", + " k_forward=1.5\n", + " found_key=(mech=rna_degredation_mm, partid=None, name=kdeg).\n", + " search_key=(mech=rna_degredation_mm, partid=reporter, name=kdeg.\n", + " k_reverse=None\n", + "\n", + "]\n" + ] + } + ], + "source": [ "#Create a Regulated Promoter\n", "Ptet = RegulatedPromoter(\"ptet\", regulators=[\"tetR\"], leak=True)\n", "reg_rep_assembly = DNAassembly(name=\"reporter\", promoter=Ptet, rbs=\"BCD\")\n", "tet = Protein(\"tetR\")\n", "components = [reg_rep_assembly, tet]\n", - "myMixture = TxTlExtract(name=\"txtl\", parameter_file = perfect_param_file_name, components=components, parameter_warnings=True)\n", + "myMixture = TxTlExtract(name=\"txtl\", parameter_file = perfect_param_file_name, components=components)\n", "\n", "\n", - "#Print the parameter dictionary created from the file\n", + "#Print the parameter database created from the file\n", "print(\"\\n****Loaded Parameters****\")\n", - "for k in myMixture.parameters:\n", - " print(\"param_dict[\"+repr(k)+\"] = \", myMixture.parameters[k])\n", + "for param in myMixture.parameter_database:\n", + " print(param.parameter_key, \"==>\", param.value)\n", " \n", - "print(\"\\n****Resulting CRN****\")\n", - "print(myMixture.compile_crn())\n" + "print(\"\\n****Resulting CRN****\\nNotice that the found_key perfectly matches the search_key.\\n\")\n", + "print(myMixture.compile_crn().pretty_print(show_rates = True, show_keys = True))" ] }, { @@ -142,9 +271,24 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 8, "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "****Parameter File****\n", + "param_name\tparam_val\tcomments\tmechanism_id\tpart_id\n", + "ku\t1.0\tAny parameter called ku will default to this\t\t\n", + "kb\t1.0\tDefault kb\t\t\n", + "ktx\t2.0\tDefault ktx\t\t\n", + "ktl\t3.0\tDefault ktl\t\t\n", + "cooperativity\t2.0\tDefault cooperativity\t\t\n", + "kdeg\t.5\tDefault degredation\t\t\n" + ] + } + ], "source": [ "from biocrnpyler import *\n", "default_param_file_name = \"Default Param File Example.tsv\"\n", @@ -153,28 +297,137 @@ "param_file = open(default_param_file_name)\n", "print(\"****Parameter File****\")\n", "print(param_file.read())\n", - "param_file.close()\n", - "\n", - "\n", + "param_file.close()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### And use these parameters in a CRN - not all reactions of the same name share the same parameters!" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "****Loaded Parameters****\n", + "ParameterKey(mechanism=None, part_id=None, name='ku') ==> 1.0\n", + "ParameterKey(mechanism=None, part_id=None, name='kb') ==> 1.0\n", + "ParameterKey(mechanism=None, part_id=None, name='ktx') ==> 2.0\n", + "ParameterKey(mechanism=None, part_id=None, name='ktl') ==> 3.0\n", + "ParameterKey(mechanism=None, part_id=None, name='cooperativity') ==> 2.0\n", + "ParameterKey(mechanism=None, part_id=None, name='kdeg') ==> 0.5\n", + "\n", + "****Resulting CRN****\n", + "Notice that only the name portion of parameter keys match.\n", + "\n", + "Species (12) = {0. [dna[reporter]:2x_protein[tetR]], 1. complex[[dna[reporter]:2x_protein[tetR]]:protein[RNAP]], 2. protein[tetR], 3. protein[RNAP], 4. protein[reporter], 5. complex[protein[RNAase]:rna[reporter]], 6. complex[dna[reporter]:protein[RNAP]], 7. protein[RNAase], 8. rna[reporter], 9. complex[protein[Ribo]:rna[reporter]], 10. dna[reporter], 11. protein[Ribo]}\n", + "Reactions (9) = [\n", + "0. dna[reporter]+protein[RNAP] <--> complex[dna[reporter]:protein[RNAP]]\n", + " Kf=k_forward * dna_reporter * protein_RNAP\n", + " Kr=k_reverse * complex_dna_reporter_protein_RNAP\n", + " k_forward=1.0\n", + " found_key=(mech=None, partid=None, name=kb).\n", + " search_key=(mech=transcription_mm, partid=ptet_leak, name=kb.\n", + " k_reverse=1.0\n", + " found_key=(mech=None, partid=None, name=ku).\n", + " search_key=(mech=transcription_mm, partid=ptet_leak, name=ku.\n", + "\n", + "1. complex[dna[reporter]:protein[RNAP]] --> dna[reporter]+rna[reporter]+protein[RNAP]\n", + " Kf=k_forward * complex_dna_reporter_protein_RNAP\n", + " k_forward=2.0\n", + " found_key=(mech=None, partid=None, name=ktx).\n", + " search_key=(mech=transcription_mm, partid=ptet_leak, name=ktx.\n", + " k_reverse=None\n", + "\n", + "2. 2protein[tetR]+dna[reporter] <--> [dna[reporter]:2x_protein[tetR]]\n", + " Kf=k_forward * protein_tetR^2 * dna_reporter\n", + " Kr=k_reverse * dna_reporter_2x_protein_tetR\n", + " k_forward=1.0\n", + " found_key=(mech=None, partid=None, name=kb).\n", + " search_key=(mech=one_step_cooperative_binding, partid=ptet_tetR, name=kb.\n", + " k_reverse=1.0\n", + " found_key=(mech=None, partid=None, name=ku).\n", + " search_key=(mech=one_step_cooperative_binding, partid=ptet_tetR, name=ku.\n", + "\n", + "3. [dna[reporter]:2x_protein[tetR]]+protein[RNAP] <--> complex[[dna[reporter]:2x_protein[tetR]]:protein[RNAP]]\n", + " Kf=k_forward * dna_reporter_2x_protein_tetR * protein_RNAP\n", + " Kr=k_reverse * complex_dna_reporter_2x_protein_tetR_protein_RNAP\n", + " k_forward=1.0\n", + " found_key=(mech=None, partid=None, name=kb).\n", + " search_key=(mech=transcription_mm, partid=ptet_tetR, name=kb.\n", + " k_reverse=1.0\n", + " found_key=(mech=None, partid=None, name=ku).\n", + " search_key=(mech=transcription_mm, partid=ptet_tetR, name=ku.\n", + "\n", + "4. complex[[dna[reporter]:2x_protein[tetR]]:protein[RNAP]] --> [dna[reporter]:2x_protein[tetR]]+rna[reporter]+protein[RNAP]\n", + " Kf=k_forward * complex_dna_reporter_2x_protein_tetR_protein_RNAP\n", + " k_forward=2.0\n", + " found_key=(mech=None, partid=None, name=ktx).\n", + " search_key=(mech=transcription_mm, partid=ptet_tetR, name=ktx.\n", + " k_reverse=None\n", + "\n", + "5. rna[reporter]+protein[Ribo] <--> complex[protein[Ribo]:rna[reporter]]\n", + " Kf=k_forward * rna_reporter * protein_Ribo\n", + " Kr=k_reverse * complex_protein_Ribo_rna_reporter\n", + " k_forward=1.0\n", + " found_key=(mech=None, partid=None, name=kb).\n", + " search_key=(mech=translation_mm, partid=BCD, name=kb.\n", + " k_reverse=1.0\n", + " found_key=(mech=None, partid=None, name=ku).\n", + " search_key=(mech=translation_mm, partid=BCD, name=ku.\n", + "\n", + "6. complex[protein[Ribo]:rna[reporter]] --> rna[reporter]+protein[reporter]+protein[Ribo]\n", + " Kf=k_forward * complex_protein_Ribo_rna_reporter\n", + " k_forward=3.0\n", + " found_key=(mech=None, partid=None, name=ktl).\n", + " search_key=(mech=translation_mm, partid=BCD, name=ktl.\n", + " k_reverse=None\n", + "\n", + "7. rna[reporter]+protein[RNAase] <--> complex[protein[RNAase]:rna[reporter]]\n", + " Kf=k_forward * rna_reporter * protein_RNAase\n", + " Kr=k_reverse * complex_protein_RNAase_rna_reporter\n", + " k_forward=1.0\n", + " found_key=(mech=None, partid=None, name=kb).\n", + " search_key=(mech=rna_degredation_mm, partid=reporter, name=kb.\n", + " k_reverse=1.0\n", + " found_key=(mech=None, partid=None, name=ku).\n", + " search_key=(mech=rna_degredation_mm, partid=reporter, name=ku.\n", + "\n", + "8. complex[protein[RNAase]:rna[reporter]] --> protein[RNAase]\n", + " Kf=k_forward * complex_protein_RNAase_rna_reporter\n", + " k_forward=0.5\n", + " found_key=(mech=None, partid=None, name=kdeg).\n", + " search_key=(mech=rna_degredation_mm, partid=reporter, name=kdeg.\n", + " k_reverse=None\n", + "\n", + "]\n" + ] + } + ], + "source": [ "#Create a Regulated Promoter\n", "Ptet = RegulatedPromoter(\"ptet\", regulators=[\"tetR\"], leak=True)\n", "reg_rep_assembly = DNAassembly(name=\"reporter\", promoter=Ptet, rbs=\"BCD\")\n", "tet = Protein(\"tetR\")\n", "components = [reg_rep_assembly, tet]\n", "\n", - "myMixture = TxTlExtract(name=\"txtl\", parameter_file = default_param_file_name, components=components, parameter_warnings=False)\n", - "\n", - "#To Run With Parameter Warnings, change the keyword parameter_warnings = True\n", - "#myMixture = TxTlExtract(name=\"txtl\", parameter_file = default_param_file_name, components=components, parameter_warnings=True)\n", - "\n", + "myMixture = TxTlExtract(name=\"txtl\", parameter_file = default_param_file_name, components=components)\n", "\n", "#Print the parameter dictionary created from the file\n", "print(\"\\n****Loaded Parameters****\")\n", - "for k in myMixture.parameters:\n", - " print(\"param_dict[\"+repr(k)+\"] = \", myMixture.parameters[k])\n", + "for param in myMixture.parameter_database:\n", + " print(param.parameter_key, \"==>\", param.value)\n", " \n", - "print(\"\\n****Resulting CRN****\")\n", - "print(myMixture.compile_crn())" + "print(\"\\n****Resulting CRN****\\nNotice that only the name portion of parameter keys match.\\n\")\n", + "print(myMixture.compile_crn().pretty_print(show_rates = True, show_keys = True))" ] }, { @@ -182,22 +435,22 @@ "metadata": {}, "source": [ "### Setting Parameters at the component level\n", - "Components can have their own parameter files instead of relying on the parameter files passed into a mixture. Components can also have the mixtures default parameters overwritten with a parameter dictionary. Below, we will create a DNAassembly which has custom parameters loaded in as a dictionary (this works the same as loading them with a file). We will put this in a Mixture with the default parameters from the above example. There are now many fewer parameter warnings as well. This example also helps illustrate how the parameter loading heirarchy works if you examine the final CRNs." + "Components can have their own parameter files instead of relying on the parameter files passed into a mixture. Components can also have the mixtures default parameters overwritten with a parameter dictionary. Below, we will create a DNAassembly which has custom parameters loaded in as a dictionary (this works the same as loading them with a file). We will put this in a Mixture with the default parameters from the above example. This example also helps illustrate how the parameter loading heirarchy works if you examine the final CRNs." ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 5, "metadata": {}, "outputs": [], "source": [ "#Create custom parameter dictionary for the ptet promoter. In this case, we will add specific leak parameters and\n", "ra_param_dict = {\n", - " (\"transcription_mm\", \"ku\"):33.33, #These parameters will take priority over single key parameters\n", - " (\"transcription_mm\", \"kb\"):.3333, \n", - " (\"transcription_mm\", \"ktx\"):3.333, \n", - " (\"transcription_mm\", \"ptet_leak\", \"ku\"):111.1, #these parameters will take priority over the ones above\n", - " (\"transcription_mm\", \"ptet_leak\", \"kb\"):.1111, \n", + " ParameterKey(mechanism = \"transcription_mm\", part_id = None, name = \"ku\"):33.33, #These parameters will take priority over single key parameters\n", + " ParameterKey(mechanism = \"transcription_mm\", part_id = None, name = \"kb\"):.3333, \n", + " ParameterKey(mechanism = \"transcription_mm\", part_id = None, name = \"ktx\"):3.333, \n", + " ParameterKey(mechanism = \"transcription_mm\", part_id = \"ptet_leak\", name = \"ku\"):111.1, #these parameters will take priority over the ones above\n", + " ParameterKey(mechanism = \"transcription_mm\", part_id = \"ptet_leak\", name = \"kb\"):.1111, \n", "}\n", "\n", "#Use the parameter_file keyword to update the parameters with a file.\n", @@ -207,40 +460,178 @@ "reg_rep_assembly = DNAassembly(name=\"reporter\", promoter=Ptet, rbs=\"BCD\")\n", "tet = Protein(\"tetR\")\n", "components = [reg_rep_assembly, tet]\n", - "myMixture = TxTlExtract(name=\"txtl\", parameter_file = default_param_file_name, components=components, parameter_warnings = False)\n", - "\n", - "myCRN = myMixture.compile_crn()\n", - "print(myCRN)" + "myMixture = TxTlExtract(name=\"txtl\", parameter_file = default_param_file_name, components=components)" ] }, { "cell_type": "markdown", "metadata": {}, - "source": [] + "source": [ + "### Mixture parameters come from the file" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "****Mixture Parameters****\n", + "ParameterKey(mechanism=None, part_id=None, name='ku') ==> 1.0\n", + "ParameterKey(mechanism=None, part_id=None, name='kb') ==> 1.0\n", + "ParameterKey(mechanism=None, part_id=None, name='ktx') ==> 2.0\n", + "ParameterKey(mechanism=None, part_id=None, name='ktl') ==> 3.0\n", + "ParameterKey(mechanism=None, part_id=None, name='cooperativity') ==> 2.0\n", + "ParameterKey(mechanism=None, part_id=None, name='kdeg') ==> 0.5\n" + ] + } + ], + "source": [ + "print(\"\\n****Mixture Parameters****\")\n", + "for param in myMixture.parameter_database:\n", + " print(param.parameter_key, \"==>\", param.value)" + ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "### Suppressing warnings:\n", - "We can see when default parameters are loaded by toggling the 'parameter_warnings' keyword for a Mixture or a Component. By default this is set to None for Mixtures, which means warnings can be toggled at the Component level. If set to True/False for a Mixture, this will supersede the Component level toggling. The default setting for Component is parameter_warnings = True. Below if you change the parameter warnings for various Components or the Mixture, the warning messages printed will change/disappear.\n" + "### Component level parameters come from the dictionary" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 9, "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "****Ptet Parameters****\n", + "ParameterKey(mechanism='transcription_mm', part_id=None, name='ku') ==> 33.33\n", + "ParameterKey(mechanism='transcription_mm', part_id=None, name='kb') ==> 0.3333\n", + "ParameterKey(mechanism='transcription_mm', part_id=None, name='ktx') ==> 3.333\n", + "ParameterKey(mechanism='transcription_mm', part_id='ptet_leak', name='ku') ==> 111.1\n", + "ParameterKey(mechanism='transcription_mm', part_id='ptet_leak', name='kb') ==> 0.1111\n" + ] + } + ], + "source": [ + "### Component Parameters are different!\n", + "print(\"\\n****Ptet Parameters****\")\n", + "for param in Ptet.parameter_database:\n", + " print(param.parameter_key, \"==>\", param.value)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### The Compiled CRN uses Component level parameters if it can find them before defaulting to Mixture level Parameters" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Species (12) = {0. [dna[reporter]:2x_protein[tetR]], 1. complex[[dna[reporter]:2x_protein[tetR]]:protein[RNAP]], 2. protein[tetR], 3. protein[RNAP], 4. protein[reporter], 5. complex[protein[RNAase]:rna[reporter]], 6. complex[dna[reporter]:protein[RNAP]], 7. protein[RNAase], 8. rna[reporter], 9. complex[protein[Ribo]:rna[reporter]], 10. dna[reporter], 11. protein[Ribo]}\n", + "Reactions (9) = [\n", + "0. dna[reporter]+protein[RNAP] <--> complex[dna[reporter]:protein[RNAP]]\n", + " Kf=k_forward * dna_reporter * protein_RNAP\n", + " Kr=k_reverse * complex_dna_reporter_protein_RNAP\n", + " k_forward=1.0\n", + " found_key=(mech=None, partid=None, name=kb).\n", + " search_key=(mech=transcription_mm, partid=ptet_leak, name=kb.\n", + " k_reverse=1.0\n", + " found_key=(mech=None, partid=None, name=ku).\n", + " search_key=(mech=transcription_mm, partid=ptet_leak, name=ku.\n", + "\n", + "1. complex[dna[reporter]:protein[RNAP]] --> dna[reporter]+rna[reporter]+protein[RNAP]\n", + " Kf=k_forward * complex_dna_reporter_protein_RNAP\n", + " k_forward=2.0\n", + " found_key=(mech=None, partid=None, name=ktx).\n", + " search_key=(mech=transcription_mm, partid=ptet_leak, name=ktx.\n", + " k_reverse=None\n", + "\n", + "2. 2protein[tetR]+dna[reporter] <--> [dna[reporter]:2x_protein[tetR]]\n", + " Kf=k_forward * protein_tetR^2 * dna_reporter\n", + " Kr=k_reverse * dna_reporter_2x_protein_tetR\n", + " k_forward=1.0\n", + " found_key=(mech=None, partid=None, name=kb).\n", + " search_key=(mech=one_step_cooperative_binding, partid=ptet_tetR, name=kb.\n", + " k_reverse=1.0\n", + " found_key=(mech=None, partid=None, name=ku).\n", + " search_key=(mech=one_step_cooperative_binding, partid=ptet_tetR, name=ku.\n", + "\n", + "3. [dna[reporter]:2x_protein[tetR]]+protein[RNAP] <--> complex[[dna[reporter]:2x_protein[tetR]]:protein[RNAP]]\n", + " Kf=k_forward * dna_reporter_2x_protein_tetR * protein_RNAP\n", + " Kr=k_reverse * complex_dna_reporter_2x_protein_tetR_protein_RNAP\n", + " k_forward=1.0\n", + " found_key=(mech=None, partid=None, name=kb).\n", + " search_key=(mech=transcription_mm, partid=ptet_tetR, name=kb.\n", + " k_reverse=1.0\n", + " found_key=(mech=None, partid=None, name=ku).\n", + " search_key=(mech=transcription_mm, partid=ptet_tetR, name=ku.\n", + "\n", + "4. complex[[dna[reporter]:2x_protein[tetR]]:protein[RNAP]] --> [dna[reporter]:2x_protein[tetR]]+rna[reporter]+protein[RNAP]\n", + " Kf=k_forward * complex_dna_reporter_2x_protein_tetR_protein_RNAP\n", + " k_forward=2.0\n", + " found_key=(mech=None, partid=None, name=ktx).\n", + " search_key=(mech=transcription_mm, partid=ptet_tetR, name=ktx.\n", + " k_reverse=None\n", + "\n", + "5. rna[reporter]+protein[Ribo] <--> complex[protein[Ribo]:rna[reporter]]\n", + " Kf=k_forward * rna_reporter * protein_Ribo\n", + " Kr=k_reverse * complex_protein_Ribo_rna_reporter\n", + " k_forward=1.0\n", + " found_key=(mech=None, partid=None, name=kb).\n", + " search_key=(mech=translation_mm, partid=BCD, name=kb.\n", + " k_reverse=1.0\n", + " found_key=(mech=None, partid=None, name=ku).\n", + " search_key=(mech=translation_mm, partid=BCD, name=ku.\n", + "\n", + "6. complex[protein[Ribo]:rna[reporter]] --> rna[reporter]+protein[reporter]+protein[Ribo]\n", + " Kf=k_forward * complex_protein_Ribo_rna_reporter\n", + " k_forward=3.0\n", + " found_key=(mech=None, partid=None, name=ktl).\n", + " search_key=(mech=translation_mm, partid=BCD, name=ktl.\n", + " k_reverse=None\n", + "\n", + "7. rna[reporter]+protein[RNAase] <--> complex[protein[RNAase]:rna[reporter]]\n", + " Kf=k_forward * rna_reporter * protein_RNAase\n", + " Kr=k_reverse * complex_protein_RNAase_rna_reporter\n", + " k_forward=1.0\n", + " found_key=(mech=None, partid=None, name=kb).\n", + " search_key=(mech=rna_degredation_mm, partid=reporter, name=kb.\n", + " k_reverse=1.0\n", + " found_key=(mech=None, partid=None, name=ku).\n", + " search_key=(mech=rna_degredation_mm, partid=reporter, name=ku.\n", + "\n", + "8. complex[protein[RNAase]:rna[reporter]] --> protein[RNAase]\n", + " Kf=k_forward * complex_protein_RNAase_rna_reporter\n", + " k_forward=0.5\n", + " found_key=(mech=None, partid=None, name=kdeg).\n", + " search_key=(mech=rna_degredation_mm, partid=reporter, name=kdeg.\n", + " k_reverse=None\n", + "\n", + "]\n" + ] + } + ], "source": [ - "Ptet = RegulatedPromoter(\"ptet\", regulators=[\"tetR\"], leak=False)\n", - "reg_rep_assembly = DNAassembly(name=\"reporter\", promoter=Ptet, rbs=\"BCD\", parameter_warnings = True)\n", - "tet = Protein(\"tetR\")\n", - "components = [reg_rep_assembly, tet]\n", - "myMixture = TxTlExtract(name=\"txtl\", parameter_warnings = None, parameter_file = default_param_file_name, components=components)\n", - "\n", "myCRN = myMixture.compile_crn()\n", - "\n", - "print(myCRN)" + "print(myCRN.pretty_print(show_rates = True, show_keys = True))" ] }, { diff --git a/examples/6. Global Mechanisms.ipynb b/examples/6. Global Mechanisms.ipynb index 96326f85..ecdfa7e7 100644 --- a/examples/6. Global Mechanisms.ipynb +++ b/examples/6. Global Mechanisms.ipynb @@ -5,11 +5,26 @@ "metadata": {}, "source": [ "## Dilution with Global Mechanisms\n", - "Global mechanisms provide a framework to have certain reactions work on all, or almost all, species in a CRN. They are to be used with caution: depending on the order global mechanisms are applied, different resulting CRNs are possible. In fact, the recommendation is to only use global mechanisms for degredation by dilution. In the following example, a model will be set up where global mechanisms cause degredation by dilution on all species which are not labeled as \"genomic\" or \"machinery\".\n", + "Global mechanisms provide a framework to have certain reactions work on specific subsets of species in a CRN, applied at the end of compilation to all species created by Component and Mixture Mechanisms.\n", "\n", - "Under the hood, global mechanisms work just like normal mechanisms - they take a set of species and compile them into CRNs. Global mechanisms are called at the end of the compilation, so they apply to all species generated by all local mechanisms. In order to make global mechanisms more selective, a filter_dict keywork can be used. The filter_dict (str:True/False) takes some str such as \"dna\" or \"genomic\" which is either a specie type, name, or attribute. The mechanism is then applied or not based upon the value of that attribute in the filter_dict. For exampe filter_dict = {\"dna\":False} would not apply its mechanism to any \"dna\" species. For species with no attributes in the filter_dict, a global mechanism defaults to its default_on keyword, which can be True or False.\n", + "Under the hood, global mechanisms work just like normal mechanisms - they take a set of species and compile them into CRNs. Global mechanisms are called at the end of the compilation, so they apply to all species generated by all local mechanisms. \n", "\n", - "In the below example, we will show how filters and attributes work on constuitively expressed genes using dilution as the prototypical example. " + "### Keywords:\n", + "__filter_dict__ {str : True/False} is used to make global mechanisms selective. The dictionaries keys (strings) can be species' names, types, or attributes. The mechanism is then applied or not based upon the value of that attribute in the filter_dict. For exampe filter_dict = {\"dna\":False} would not apply its mechanism to any \"dna\" species. \n", + "\n", + "__default_on__ True / False: For species with no attributes in the filter_dict, a global mechanism defaults to its default_on keyword, which can be True or False.\n", + "\n", + "__recursive_species_filtering__ True / False: When applying a filter dictionary to a ComplexSpecies, this keyword determines if the filter will be applied recursively to all species inside that complex species. For example, consider the filter dict filter_dict = {\"dna\":False}. A ComplexSpecies (material_type=\"complex\") consisting of a species of type material_type=\"dna\" and a species of type material_type=\"protein\" will not be effected by this filter unless recursive_species_filtering = True. Note that attributes are automatically inheritted recursively, so this keyword only matters for name and material_type filters.\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Example 1: Global Dilution using attributes\n", + "\n", + "In the following example, a model will be set up where global mechanisms cause degredation by dilution on all species which are do not have the attributes \"genomic\" or \"machinery\"" ] }, { @@ -21,48 +36,185 @@ "name": "stdout", "output_type": "stream", "text": [ - "Species (15) = {0. protein[RNAP(machinery)], 1. protein[Ribo(machinery)], 2. protein[RNAase(machinery)], 3. complex[protein[Ribo]:rna[G1](machinery)], 4. complex[protein[RNAase]:rna[G1](machinery)], 5. complex[dna[G1]:protein[RNAP](machinery)], 6. rna[G1], 7. dna[G1], 8. protein[G1], 9. complex[protein[RNAase]:rna[G2](machinery)], 10. complex[dna[G2]:protein[RNAP](machinery, genomic)], 11. complex[protein[Ribo]:rna[G2](machinery)], 12. dna[G2(genomic)], 13. protein[G2], 14. rna[G2]}\n", - "Reactions (17) = [\n", - "0. dna[G1] + protein[RNAP(machinery)] <--> complex[dna[G1]:protein[RNAP](machinery)] \n", - " massaction: k_f(dna[G1],protein[RNAP(machinery)])=100*dna[G1]*protein[RNAP(machinery)]\n", - " k_r(complex[dna[G1]:protein[RNAP](machinery)])=20*complex[dna[G1]:protein[RNAP](machinery)]\n", - "1. complex[dna[G1]:protein[RNAP](machinery)] --> dna[G1] + rna[G1] + protein[RNAP(machinery)] \n", - " massaction: k_f(complex[dna[G1]:protein[RNAP](machinery)])=3*complex[dna[G1]:protein[RNAP](machinery)]\n", - "2. rna[G1] + protein[Ribo(machinery)] <--> complex[protein[Ribo]:rna[G1](machinery)] \n", - " massaction: k_f(rna[G1],protein[Ribo(machinery)])=100*rna[G1]*protein[Ribo(machinery)]\n", - " k_r(complex[protein[Ribo]:rna[G1](machinery)])=20*complex[protein[Ribo]:rna[G1](machinery)]\n", - "3. complex[protein[Ribo]:rna[G1](machinery)] --> rna[G1] + protein[G1] + protein[Ribo(machinery)] \n", - " massaction: k_f(complex[protein[Ribo]:rna[G1](machinery)])=2*complex[protein[Ribo]:rna[G1](machinery)]\n", - "4. rna[G1] + protein[RNAase(machinery)] <--> complex[protein[RNAase]:rna[G1](machinery)] \n", - " massaction: k_f(rna[G1],protein[RNAase(machinery)])=100*rna[G1]*protein[RNAase(machinery)]\n", - " k_r(complex[protein[RNAase]:rna[G1](machinery)])=20*complex[protein[RNAase]:rna[G1](machinery)]\n", - "5. complex[protein[RNAase]:rna[G1](machinery)] --> protein[RNAase(machinery)] \n", - " massaction: k_f(complex[protein[RNAase]:rna[G1](machinery)])=0.5*complex[protein[RNAase]:rna[G1](machinery)]\n", - "6. dna[G2(genomic)] + protein[RNAP(machinery)] <--> complex[dna[G2]:protein[RNAP](machinery, genomic)] \n", - " massaction: k_f(dna[G2(genomic)],protein[RNAP(machinery)])=100*dna[G2(genomic)]*protein[RNAP(machinery)]\n", - " k_r(complex[dna[G2]:protein[RNAP](machinery, genomic)])=20*complex[dna[G2]:protein[RNAP](machinery, genomic)]\n", - "7. complex[dna[G2]:protein[RNAP](machinery, genomic)] --> dna[G2(genomic)] + rna[G2] + protein[RNAP(machinery)] \n", - " massaction: k_f(complex[dna[G2]:protein[RNAP](machinery, genomic)])=3*complex[dna[G2]:protein[RNAP](machinery, genomic)]\n", - "8. rna[G2] + protein[Ribo(machinery)] <--> complex[protein[Ribo]:rna[G2](machinery)] \n", - " massaction: k_f(rna[G2],protein[Ribo(machinery)])=100*rna[G2]*protein[Ribo(machinery)]\n", - " k_r(complex[protein[Ribo]:rna[G2](machinery)])=20*complex[protein[Ribo]:rna[G2](machinery)]\n", - "9. complex[protein[Ribo]:rna[G2](machinery)] --> rna[G2] + protein[G2] + protein[Ribo(machinery)] \n", - " massaction: k_f(complex[protein[Ribo]:rna[G2](machinery)])=2*complex[protein[Ribo]:rna[G2](machinery)]\n", - "10. rna[G2] + protein[RNAase(machinery)] <--> complex[protein[RNAase]:rna[G2](machinery)] \n", - " massaction: k_f(rna[G2],protein[RNAase(machinery)])=100*rna[G2]*protein[RNAase(machinery)]\n", - " k_r(complex[protein[RNAase]:rna[G2](machinery)])=20*complex[protein[RNAase]:rna[G2](machinery)]\n", - "11. complex[protein[RNAase]:rna[G2](machinery)] --> protein[RNAase(machinery)] \n", - " massaction: k_f(complex[protein[RNAase]:rna[G2](machinery)])=0.5*complex[protein[RNAase]:rna[G2](machinery)]\n", - "12. rna[G1] --> \n", - " massaction: k_f(rna[G1])=0.5*rna[G1]\n", - "13. dna[G1] --> \n", - " massaction: k_f(dna[G1])=0.5*dna[G1]\n", - "14. protein[G1] --> \n", - " massaction: k_f(protein[G1])=0.5*protein[G1]\n", - "15. protein[G2] --> \n", - " massaction: k_f(protein[G2])=0.5*protein[G2]\n", - "16. rna[G2] --> \n", - " massaction: k_f(rna[G2])=0.5*rna[G2]\n", + "Species (15) = {0. protein[RNAP], 1. protein[Ribo], 2. protein[RNAase], 3. dna[G1], 4. rna[G1], 5. complex[dna[G1]:protein[RNAP]], 6. protein[G1], 7. complex[protein[Ribo]:rna[G1]], 8. complex[protein[RNAase]:rna[G1]], 9. dna[G2(genomic)], 10. rna[G2], 11. complex[dna[G2]:protein[RNAP]], 12. protein[G2], 13. complex[protein[Ribo]:rna[G2]], 14. complex[protein[RNAase]:rna[G2]]}\n", + "\n", + "Reactions (41) = [\n", + "0. dna[G1]+protein[RNAP] <--> complex[dna[G1]:protein[RNAP]]\n", + " Kf=k_forward * dna_G1 * protein_RNAP\n", + " Kr=k_reverse * complex_dna_G1_protein_RNAP\n", + " k_forward=100\n", + " k_reverse=20\n", + "\n", + "1. complex[dna[G1]:protein[RNAP]] --> dna[G1]+rna[G1]+protein[RNAP]\n", + " Kf=k_forward * complex_dna_G1_protein_RNAP\n", + " k_forward=3\n", + "\n", + "2. rna[G1]+protein[Ribo] <--> complex[protein[Ribo]:rna[G1]]\n", + " Kf=k_forward * rna_G1 * protein_Ribo\n", + " Kr=k_reverse * complex_protein_Ribo_rna_G1\n", + " k_forward=100\n", + " k_reverse=20\n", + "\n", + "3. complex[protein[Ribo]:rna[G1]] --> rna[G1]+protein[G1]+protein[Ribo]\n", + " Kf=k_forward * complex_protein_Ribo_rna_G1\n", + " k_forward=2\n", + "\n", + "4. rna[G1]+protein[RNAase] <--> complex[protein[RNAase]:rna[G1]]\n", + " Kf=k_forward * rna_G1 * protein_RNAase\n", + " Kr=k_reverse * complex_protein_RNAase_rna_G1\n", + " k_forward=100\n", + " k_reverse=20\n", + "\n", + "5. complex[protein[RNAase]:rna[G1]] --> protein[RNAase]\n", + " Kf=k_forward * complex_protein_RNAase_rna_G1\n", + " k_forward=0.5\n", + "\n", + "6. dna[G2(genomic)]+protein[RNAP] <--> complex[dna[G2]:protein[RNAP]]\n", + " Kf=k_forward * dna_G2_genomic * protein_RNAP\n", + " Kr=k_reverse * complex_dna_G2_genomic_protein_RNAP\n", + " k_forward=100\n", + " k_reverse=20\n", + "\n", + "7. complex[dna[G2]:protein[RNAP]] --> dna[G2(genomic)]+rna[G2]+protein[RNAP]\n", + " Kf=k_forward * complex_dna_G2_genomic_protein_RNAP\n", + " k_forward=3\n", + "\n", + "8. rna[G2]+protein[Ribo] <--> complex[protein[Ribo]:rna[G2]]\n", + " Kf=k_forward * rna_G2 * protein_Ribo\n", + " Kr=k_reverse * complex_protein_Ribo_rna_G2\n", + " k_forward=100\n", + " k_reverse=20\n", + "\n", + "9. complex[protein[Ribo]:rna[G2]] --> rna[G2]+protein[G2]+protein[Ribo]\n", + " Kf=k_forward * complex_protein_Ribo_rna_G2\n", + " k_forward=2\n", + "\n", + "10. rna[G2]+protein[RNAase] <--> complex[protein[RNAase]:rna[G2]]\n", + " Kf=k_forward * rna_G2 * protein_RNAase\n", + " Kr=k_reverse * complex_protein_RNAase_rna_G2\n", + " k_forward=100\n", + " k_reverse=20\n", + "\n", + "11. complex[protein[RNAase]:rna[G2]] --> protein[RNAase]\n", + " Kf=k_forward * complex_protein_RNAase_rna_G2\n", + " k_forward=0.5\n", + "\n", + "12. protein[RNAP] --> \n", + " Kf=k_forward * protein_RNAP\n", + " k_forward=0.5\n", + "\n", + "13. protein[Ribo] --> \n", + " Kf=k_forward * protein_Ribo\n", + " k_forward=0.5\n", + "\n", + "14. protein[RNAase] --> \n", + " Kf=k_forward * protein_RNAase\n", + " k_forward=0.5\n", + "\n", + "15. dna[G1] --> \n", + " Kf=k_forward * dna_G1\n", + " k_forward=0.5\n", + "\n", + "16. dna[G1] --> \n", + " Kf=k_forward * dna_G1\n", + " k_forward=0.5\n", + "\n", + "17. protein[RNAP] --> \n", + " Kf=k_forward * protein_RNAP\n", + " k_forward=0.5\n", + "\n", + "18. dna[G1] --> \n", + " Kf=k_forward * dna_G1\n", + " k_forward=0.5\n", + "\n", + "19. rna[G1] --> \n", + " Kf=k_forward * rna_G1\n", + " k_forward=0.5\n", + "\n", + "20. complex[dna[G1]:protein[RNAP]] --> \n", + " Kf=k_forward * complex_dna_G1_protein_RNAP\n", + " k_forward=0.5\n", + "\n", + "21. protein[Ribo] --> \n", + " Kf=k_forward * protein_Ribo\n", + " k_forward=0.5\n", + "\n", + "22. rna[G1] --> \n", + " Kf=k_forward * rna_G1\n", + " k_forward=0.5\n", + "\n", + "23. protein[G1] --> \n", + " Kf=k_forward * protein_G1\n", + " k_forward=0.5\n", + "\n", + "24. complex[protein[Ribo]:rna[G1]] --> \n", + " Kf=k_forward * complex_protein_Ribo_rna_G1\n", + " k_forward=0.5\n", + "\n", + "25. rna[G1] --> \n", + " Kf=k_forward * rna_G1\n", + " k_forward=0.5\n", + "\n", + "26. protein[RNAase] --> \n", + " Kf=k_forward * protein_RNAase\n", + " k_forward=0.5\n", + "\n", + "27. protein[RNAase] --> \n", + " Kf=k_forward * protein_RNAase\n", + " k_forward=0.5\n", + "\n", + "28. rna[G1] --> \n", + " Kf=k_forward * rna_G1\n", + " k_forward=0.5\n", + "\n", + "29. complex[protein[RNAase]:rna[G1]] --> \n", + " Kf=k_forward * complex_protein_RNAase_rna_G1\n", + " k_forward=0.5\n", + "\n", + "30. protein[RNAP] --> \n", + " Kf=k_forward * protein_RNAP\n", + " k_forward=0.5\n", + "\n", + "31. rna[G2] --> \n", + " Kf=k_forward * rna_G2\n", + " k_forward=0.5\n", + "\n", + "32. protein[Ribo] --> \n", + " Kf=k_forward * protein_Ribo\n", + " k_forward=0.5\n", + "\n", + "33. rna[G2] --> \n", + " Kf=k_forward * rna_G2\n", + " k_forward=0.5\n", + "\n", + "34. protein[G2] --> \n", + " Kf=k_forward * protein_G2\n", + " k_forward=0.5\n", + "\n", + "35. complex[protein[Ribo]:rna[G2]] --> \n", + " Kf=k_forward * complex_protein_Ribo_rna_G2\n", + " k_forward=0.5\n", + "\n", + "36. rna[G2] --> \n", + " Kf=k_forward * rna_G2\n", + " k_forward=0.5\n", + "\n", + "37. protein[RNAase] --> \n", + " Kf=k_forward * protein_RNAase\n", + " k_forward=0.5\n", + "\n", + "38. protein[RNAase] --> \n", + " Kf=k_forward * protein_RNAase\n", + " k_forward=0.5\n", + "\n", + "39. rna[G2] --> \n", + " Kf=k_forward * rna_G2\n", + " k_forward=0.5\n", + "\n", + "40. complex[protein[RNAase]:rna[G2]] --> \n", + " Kf=k_forward * complex_protein_RNAase_rna_G2\n", + " k_forward=0.5\n", + "\n", "]\n", "Simulating with BioSCRAPE\n" ] @@ -74,12 +226,15 @@ "C:\\ProgramData\\Anaconda3\\lib\\site-packages\\html5lib\\_trie\\_base.py:3: DeprecationWarning: Using or importing the ABCs from 'collections' instead of from 'collections.abc' is deprecated, and in 3.8 it will stop working\n", " from collections import Mapping\n", "C:\\ProgramData\\Anaconda3\\lib\\importlib\\_bootstrap.py:219: RuntimeWarning: numpy.ufunc size changed, may indicate binary incompatibility. Expected 192 from C header, got 216 from PyObject\n", - " return f(*args, **kwds)\n" + " return f(*args, **kwds)\n", + "C:\\ProgramData\\Anaconda3\\lib\\site-packages\\biocrnpyler-0.2.1-py3.7.egg\\biocrnpyler\\chemical_reaction_network.py:338: UserWarning: Trying to set species that is not in model: protein_Ribo_machinery\n", + "C:\\ProgramData\\Anaconda3\\lib\\site-packages\\biocrnpyler-0.2.1-py3.7.egg\\biocrnpyler\\chemical_reaction_network.py:338: UserWarning: Trying to set species that is not in model: protein_RNAP_machinery\n", + "C:\\ProgramData\\Anaconda3\\lib\\site-packages\\biocrnpyler-0.2.1-py3.7.egg\\biocrnpyler\\chemical_reaction_network.py:338: UserWarning: Trying to set species that is not in model: protein_RNAase_machinery\n" ] }, { "data": { - "image/png": "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6hPP9UnBggVp2LAhJ06csB0LDQ3l2rVrrFy5kvvuuy/Dc2bMmMFHH33EU089xYkTJ2yfgb3p06fzyCOP2B5PmTKFDz74gAoVKlCrVi2KFCkCmNGnPn368McffwAwfvx4KlasmOF7Wrt27QzlmjVrxrBhwzh58iTx8fGUK1eO+++/P9OfV9WqVenZsyeLFi3i2rVrzJ49m9q1azN16lSioqL4+OOPmT17NsOHD6dgwYKUKlWKVatW8c4775CYmMjGjRt54403SExMtJU/ffo0ffr0sY2YffbZZzRt2pROnTrxxhtv0L17d6d/D2/klfokM/WCtxyvMy5jGkX2dYO7eiHq998Z2qsXl/N5vVCoUCGaNm3KoUOHWLduHcOHD6dChQrExsayb98+xo4dyzfffAOYmRwDBgxg6NChHD58mLCwMO677z5Gjx7N6NGj+fHHH7ly5QqdO3dm+PDhAJQoUYJLly6xbt06hg0bRrly5dizZw/169fn+++/z7BGZs6cOelmbixbtowBAwZQrlw5wsPDbccTEhLo27cvu3fvJjk5mWHDhtGhQ4cM39WHHnooQ7lHHnmEqVOn8vPPP5OUlERCQgLvvPMO7777LrfeeiuxsbE8+uijBAcHM2HCBBITE5k/fz41atRId93h6m+5bt06xowZw+LFi/nll1/o39/kdFNKsX79eoYOHcqvv/5KWFgYPXv2pF69erbyly5dom/fvkRFRaGU4t133+Wxxx6jY8eOtGjRgrfeesv5F8JLbkeMtNYpQHmlVMANvUsupZRpHDkbPU1IIFuy1b388stMnz6df/75J93xV155hR49erBr1y66d++ebojx1KlTbNy4kcWLF7vssdu7d2+6L5C9a9eu0bdvX+bMmUN0dDS9evVK9w8tOTmZ7du3M378eNsX+5NPPgFg9+7dzJgxg549e9qygOzZs4cffviB7du389Zbb1G8eHFiYmJo0qRJhuHWq1ev0rVrVyZMmEBcXByrVq2iWDHPS0XDw8PZv3+/7XGBAgV47bXXeP/99zOU3bRpE9WqVaNGjRpERES47DnZtGmTrfETHR3NzJkziYmJ4aeffmLHjh22cs8//zyTJk0iOjqaMWPG8NJLL9G0aVM6duzI6NGjiY2NpUaNGk7LWR04cIBVq1bx0UcfAaax9fPPP7NgwQKefvppWrduze7duylW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jh3LxIkTzXOPGDGC0NBQ6tWrx/r1653as3jxYjp06AB49i6LCNHR0fj7+2OxWFiwYIF5rvHjx2OxWAgMDGTkyJHm9oULF6azIy4ujpYtWxISEkJISIjZ0Dl58iTh4eEEBQXh7+/P+vXrGTlyJNevXycoKIinn34acBwl4+y6tWrV4vz585w65ckvTwHFWdZX+wUYklGZ/LJkZ7b6tFlyI0RkpoicPCny22aR8BSR2dZ9V63751vX463ri63rZ63ry63rJz24/scffyzDhg1zuf+zzz6Td955R0SM7OMNGzaUQ4cOyZo1a8THx0eOHTsmycnJEhYWJuvXr5fr169L9erVZd++fSIi0rNnT5k0aZKIiNSqVUv+/e9/i4jIsGHDxGKxyKVLl+TMmTNSpUoVERE5fPiw+Pn5iYjIv//9b+natauZ7fz8+fT5tXv37i0LFy502DZ06FB5//33zWueOnVK6tevL/v375eFCxdK7969zbJt2rSRdevWyb59+8RisTh9BjNmzJBXXnnFXPf395fjx4+LiJgZoWfOnCkvvPCCWebFF1+UsWPHiojI6tWrJTAwUEREXnvtNRk6dKhZzpZ5GZDly42/XHR0tPnML1y4ICkpKSIi8p///Me0o1OnTrJhwwYREbl8+bLcunVL1qxZI1FRUea57dddXVdE5L777pNz5845vff8SBYy1e8FlKv9eblkp5aIuNYTEZErIhIiIlOt62n15IiINBORz8XIRp9WT36XjLPUFyY9Wbp0qTz55JPmvoiICNm0aZO0atVKfv75Z9m0aZNERESY+/v16ydfffWVJCQkyD333CM3b95Md/6ff/5Zunbtaq578h5PnDhR+vTpIyIie/fulRo1asj169dd3k+tWrVkypQpIiIydepU6devn4iIJCQkmGV/+ukn044XX3xR5syZIyIiN27ckGvXrjk8t8w8x7Zt28rmzZvT3Xd+pijoiTtduGldz2w9Y7aIbBKROKdXFDkjIgkiEit4hWaSAAAgAElEQVQi49Powg0R2Scil6zrBUkXvv76awkNDTWeY0SEDB482CzXqVMnmTVrloiITJ8+XR599NF0x4uItG7dWmJjY0VEZOPGjdKqVSsRERkzZoxMmDDBPLft9/67776TNm3apLPr0KFDEhISYq578i4vWrRI2rZtK0lJSXLq1CmpUaOGnDhx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\n", + "image/png": "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flKzZk29fOfOnQFo1KgRKSkpAGzcuJHBgwcD4O7uTu3atUlOTgagVatWuLi44OLiQuXKlWnfvj0ABoOBxMREq7r88ccf1KxZk8aNG+vbb0vOld39+/fTtWtXjEajVX7Lli0B9KudOebNm8dzzz0HQI8ePXjxxRd544038iz/1KlT1KhRA4CtW7cSFBSkp7t3765v2+rVq60aSn///bfNK9n5levQoYPVb1uU/ZUj92+S+wp0jubNmxMREcFzzz2nl83P2rVr9ZNTR0dHKleurH8vV64cly5dwsXFpcDl3M8kLty9cUHTNJ599lnatm1LbGwsfn5++stCN27cSKdOnahYsaJe7w0bNtChQwerZa1atYpVq1bh7e0NWO567N+/P093OD8/P2rVqgWAyWQiJSWFFi1aWJXJHU/27duHm5sb9erVA+CFF17gq6++0te5bNky/eJGenq6ftfv5rrZK9e6dWsefPBBvWzjxo3136lu3bqEhITo+znnDt7NbP2WuTVv3pw33niDXr160blzZ3377Vm9ejXz5s3T01WrVtW/P/TQQ5w8eZJq1arlu4z8SMNICCFKkWHDhuHj40Pfvn3tlsn93ofy5cvr33O6dYwePZr//ve/gKW/uoeHB/Hx8bRq1QqDwYDZbOa1117j6tWrKKXw8PBgy5YtNteVs3xHR0e9H7ut7iO26uPg4KCnHRwc8vSDV0oV6h0WOVd2T506RVBQEMuWLctzYjN69GjGjRtHmTL/+7M5d+5cTp8+rXcHO3nyJPv379dPUnI4OztbvWDQXp2ysrLYsmVLvlevCyqXc4KWoyj76+Z5cv8muc2YMYOtW7fy3//+F5PJhNlszre++bl27RpOTk63PL8oHhIX8sqJCzfLfYzlV6eb1zlq1CheeumlfMvl3g57x19h44lSikWLFuldF3Ns3bq10OXuRDwZOXIkYWFh/PLLLzRt2rTAATLy+/3S09MLjJ8Fka50QghRijz44IM899xzzJw5U5/m7++vX4GLjo7Oc4XyZuPGjcNsNusnDaNGjWL48OEcP35cL3P16lUAnnzySc6ePaufAGVkZJCUlJTv8gMCAvTGRnJyMkePHs3zR7sw3N3dOXnypN5d69KlS/k+RFyzZk3Gjx/Pxx9/nCcvJCSECxcukJCQAFiuOqelpXHixAlSUlJISUlh1KhRVlcyczRo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8x40xnQDynUHNHdi5FwWwbvdu3cTGRlJo0aNPOsoiEhB1lrmz5/PwoULufXWW0lISCAhIQGAUaNGhRlj2lhry/VMliLiPytWrGD//v1069ZN9YmI+FVRY4zuAV40xkw1xgx3vd7BOb5opH/C8w13YjRmDKwqpHrNysrirLPOUlIkUgxjDOPGjaNBgwbeTmcB4/0ckoiUY2PHjuWCCy7wdkr1iYj4VKGJkbV2CxALfAs0cr2+BVq5zpVb7jFGsbFFT9etpEikZH777TfOOeccb6eOAVpCWURK7LfffqNRo0beTqk+ERGfKnKBV2vtMeBtP8XiN+4WoxtvhCZNAhuLyJng6NGjRZ2u7K84RKT8U30iIoFSkgVezzglGWNUFhhjGD16tGd/woQJPPbYY6V2//fff59WrVoRExNDXFwcQ4YMISMjo9TufyoeeeQR5s+fX6KyqampRERE0Lp1ay644ALatWvHO++84zk/depUQkJCWLt2redYy5YtSU1N9ewnJydjjGHevHmFPsday2WXXcYff/xR4Nxjjz3GhAkTioxz9uzZbNy4scgyf8WQIUOKvf/rr7/Ou+++W+j5hQsX8v3335e4fHp6OldeeWWB4507d+bFF1/Ey7po9YBvigxSRCSPzp078/DDD6s+ERG/K7LF6Ezl7kr30EPQogV07hzYeAoTHh7ORx99xIMPPkitWrVK9d5ffPEFL7zwAp9//jnnnHMOOTk5vPPOO+zbt4/qRfUv9JEnnnjilMo3adKE5ORkALZv3861115Lbm4ut956KwD169dn3LhxzJgxw+v106dP55JLLmH69Ol07drVa5m5c+cSFxdH1apVTyk2t9mzZ9OjRw9atGhR4muys7MJDS3Zf5b//ve/iy0zbNiwIs8vXLiQKlWq0KFDhxKVj4qKom7duixZsoSLL77Yc/z555+nX79+nHfeecTHxwOwZs0agIrAvcUGKiLi8vzzzzNkyBDVJyLid0V+AzPGOIB3rLU3+ykev3C3GMXFQd26xZcfNQpSUko3hvh4eLGYSUdDQ0MZOnQoL7zwAuPGjct37ueff2bw4MGkp6cTFRXF22+/zbnnnsugQYOoWrUqK1eu5JdffuG5556jb9++Be49btw4JkyY4BkX4nA4GDx4sOf8qlWruPfeezl06BC1atVi6tSp1K1bl6SkJC688EIWLFhARkYGkydP5m9/+xtZWVnccccdrFy5ktDQUCZOnEinTp2YOnUqs2fPJicnh/Xr1zN69GiOHz/Oe++9R3h4OHPnzqVmzZoMGjSIHj160LdvX1asWMHIkSM5fPgw4eHhfP3110RGRhb6OTVu3JiJEycyevRoT2LUo0cPFi1axObNm2nWrFm+8tZaZs6cyVdffeWJvaKXBa2mTZvG0KFD831m7777Lg0aNCAqKoo2bdoAsG3bNu666y7S09OpVKkSb731FgcOHGDOnDl8++23PPnkk8yaNQugQLnmzZszaNAgatasSXJyMgkJCURGRrJjxw727t3Lli1bmDhxIsuWLfMksf/73/+oUKECSUlJTJgwgcTERKpUqcLIkSP59NNPiYiI4JNPPqFOnTo89thjVKlShTFjxjBp0iRef/11QkNDadGiBc888wyvv/46DoeD999/n5dffpmvv/7aU37r1q0MGzaM9PR0HA4H//3vf2nSpAm9e/dm2rRp+RKjypUrM2HCBMLDw9mwYQMAMTExNGnSZLu19lChvzwRkZNUrlyZ6dOns337dtUnIuJXRXals9bmAFHGmDA/xeMX7hajXr0gJiawsRTnrrvuYtq0aRw8eDDf8bvvvpuBAweydu1a+vfvz4gRIzzn9u7dy3fffcenn37KAw884PW+GzZs8EyBerITJ04wfPhwZs6cyapVqxg8eDAPP/yw53x2djbLly/nxRdf5PHHHwfg1VdfBWDdunVMnz6dW265xbMG1Pr16/nggw9Yvnw5Dz/8MJUqVSI5OZn27dsX6LZ1/Phxrr/+el566SXWrFnD/PnziYiIKPZzSkhIYNOmTZ79kJAQ7rvvPp566qkCZZcsWUJ0dDRNmjQhKSmJuXPnFijjLudOflatWsWHH35IcnIyH330EStWrPCUGzp0KC+//DKrVq1iwoQJ3HnnnXTo0IGrr76a8ePHk5KSQpMmTbyWc9uyZQvz58/n+eedaydv27aNzz77jE8++YSbb76ZTp06sW7dOiIiIvjss88KxHr48GEuuugi1qxZQ8eOHXnrrbcKlHnmmWdITk5m7dq1vP766zRq1Ihhw4Zxzz33kJKSwt/+9rd85fv3789dd93FmjVr+P7776nr+itCYmIiixcv9vqZNW7cmJ49e9KzZ08aN27stYyISEmoPhERfytJn51UYIkxZg5w2H3QWjvRV0H5mjsxKukYo+JadnypatWqDBw4kEmTJuVLEJYuXcpHH30EwIABA7jvvvs853r37k1ISAgtWrRg3759xT5j3bp1DBgwgMzMTJ566iliYmJYv349V1xxBQA5OTmeL8UA1157LQBt2rTxjNv57rvvGD58OADNmzenYcOGbNninLywU6dOREZGEhkZSbVq1ejZsycAsbGx+cYBAWzevJm6devStm1bz89fEl76onPTTTcxbtw4duzYke/49OnTueGGGwC44YYbeO+99zw/U14HDhzwtFQtXryYa665hkqVKgFw9dVXA3Do0CG+//57rrvuOs91x44dK3Cv4spdd911ONz/MIFu3bpRoUIFYmNjycnJ8YzriY2NzTdWyi0sLIwePXoAzt/LV199VaBMq1at6N+/P71796Z3794FzueVmZnJnj17PCvO521Rq127NmlpaUVeLyIiIlLelCQxSnO9QoDC+zOVI+7vn489Bo0bw/XXBzScYo0aNYqEhARPNzFv8k4tHh4e7nnvThgefvhhT0tDSkoKMTExrF69mk6dOhEbG0tKSgp33303R48exVpLTEwMS5cu9fos9/27YhDEAAAgAElEQVQdDgfZ2dn5nlNUeXC25Lj3Q0JCPNfnjfd0pklPTk4usO5FaGgoo0eP5tlnn/Ucy8nJYdasWcyZM4dx48ZhreW3334jMzOzQHe90NBQcnNzCXH1vfQWV25uLtWrVyelmL6WxZWrXDn/REt5P6MKFSp4nu3tMwPylcn7e8nrs88+Y9GiRcyZM4d//vOfni4q3hT1+8zKyipRK56IiIhIeVLsrHTW2settY8DE4Hn8+yXW+7EqE0bOO+8wMZSEjVr1qRfv35MnjzZc6xDhw58+OGHgHMszCWXXFLkPcaNG0dKSorni/mDDz7ImDFj2L17t6eMe4rUZs2akZ6e7kmMTpw4UeSXaICOHTsybdo0wNktbOfOnQXG9pRE8+bNSUtL83RVy8zM9PolP6/U1FTGjBnjabHKa9CgQcyfP5/09HQA5s+fT1xcHLt27SI1NZWff/6ZPn36MHv27ALXNmvWjO3bt3t+vo8//pijR4+SmZnJ//73P8DZohUdHc1///tfwJlQuAYJExkZSWZmZrHl/CE3N5ddu3bRqVMnnnvuOTIyMjh06FC+GPOqWrUq9evX93wux44d48iRI4Dz99uyZct85RMTE3nqqaf44osvPF0oRUROR2JiIiNHjlR9IiJ+V2xiZIxpaYxJBtYDG4wxq4wxZXxkTtHcky907uxMjsqD0aNHs3//fs/+pEmTePvtt2nVqhXvvfceL7300indr3v37owYMYJu3brRokULOnTogMPhoGvXroSFhTFz5kzuv/9+4uLiiI+Pzzelszd33nknOTk5xMbGcv311zN16tR8LUUlFRYWxowZMxg+fDhxcXFcccUVXv/HuG3bNs903f369WP48OFeW9TCwsIYMWIEv/76K+DsRufuHubWp08fPvjggwLXXnXVVSxcuBBwjmG6/vrriY+Pp0+fPvnG40ybNo3JkycTFxdHTEwMn3zyCeDspjd+/Hhat27Ntm3bCi3nDzk5Odx8883ExsbSunVr7rnnHqpXr07Pnj35+OOPiY+PLzBu6L333mPSpEm0atWKDh068MsvvwCwYMECrrrqqnxlly1bRufOnVm4cCGXXnop3bt3d/+bPPV/BCIS1JYtW8Y111yj+kRE/M4U1WUGwBjzPfCwtXaBaz8JeMpa28H34Z2axMREu3LlyhKVDQ2F+++HkyZ78/jxxx8LdM2S4LJ3714GDhzodbxOMOvYsSOffPIJNWrUyHc8738ze/fu5fPPP+e22277Hec4xWXW2jsL3KyMOpW6RER8S/WJiJQ2Y8wqa23iycdLssBrZXdSBGCtXcgZsPJ0SAg88wz861+BjkTKqrp163L77bd7XeA1WKWnp3PvvfcWSIpOVrduXff079uBRGCaH8ITkTOQ6hMR8ZeSTL6w3RjzD+A91/7NwI4iypcLDge0bu18iRSmX79+gQ6hTImKiip2RruTWWtzgSW+iUhEgonqExHxpZK0GA0GooCPXK9aQOHTo5UToaFw8cXQvn2gIxERERERkUArtsXIWvs7MKK4cuWNwwHZ2ZCb++dkDCIiIiIiEpxK0pXujORwwMsvQ1QU/OMfgY5G5MyQnp7OW2+9RWpqqnua9UbGmCnW2sGBjk1EyhfVJyLib0HbVuJwQEIC5Jl1WUT+ol69enHw4EE6d+7sntI7A/gswGGJSDmk+kRE/C1oE6PQUGdilJQU6EgKt2/fPm666SYaN25MmzZtaN++PR9//HFAYklLS6Nv374lLj9o0CCio6OJi4ujadOmDBw4kD179njON2rUiD59+nj2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jmSfffZhxYoVnH/++Tz66KOMHDmSn/70pzz88MN88pOf3OLrHnvssdxShWcGOfXUUzn33HN57LHHmDBhAkB3oOouyCgpP+uJpEprtjFKKf1HSmkwcG5KafeU0uDSz4itYSq7Y0fYuBEefbR97ko3ffp0Ro0a1ez9N9xwA71792bChAlMmDCB66+/vn5mZfLkyYwfP54ZM2bw0ksv8fjjj7N27VpOP/10br31VqZNm8aGDRv4+c9/Xv98u+yyC3/961856KCDOP300/nd737HE088wYUXXviO177uuut4+eWXmTx5MlOnTuWUU05p0e80atQoZs6cWT/+3Oc+x6RJk5g9e/Y7tr3llls4+eSTOfnkk5ttEB5//PHN3qNLLrmEe++9l2eeeYY777yTzp07c8kll3DiiScyZcoUTjzxRC666CL22Wcfpk6dyqWXXsoXvlD85+P3vvc9evfuzbRp05g6dSqHHXYYAKtWrWLs2LE888wzjBs3juuvvx6AAw88kCeeeILJkydz0kkn8e///u8AXH755Vx99dVMmTKFRx99lG7dunHZZZdx0EEHMWXKFM4555zNfofmXne77bZj3bp1LFmypEXvbXsxceJEHn/8cX72s5+VG+a5KaUt7zcoSU2wnkiqtJacfOHKiPg4MKjh9iml/2rDXG2uPEs0bhzMnw8DBmx5+4cb3O7UaNy90bh3o3HfRuN3eakmff3rX+exxx6jc+fOTJgwgfvuu4+pU6fW79725ptv8sILL9C5c2fGjBnDzjvvDMDIkSOZM2cOPXv2ZPDgwXz4wx8G4LTTTuPqq6/m7LPPBooZCoBhw4axcuVKevbsSc+ePenatStvvPHGZlkeeOABvvrVr1JX2gexT58+LfodGl+9vGPHjpx33nn84Ac/4Jhjjqlfv2DBAmbPns2BBx5IRFBXV8ezzz5bP2NVNn/+fPr161c/PuCAAzj99NP53Oc+x3HHHddkhscee6x+Vuawww5jyZIlvPnmmzzwwAObzUxtt912AHTu3Ll+dmfffffl/vvvB2DevHmceOKJzJ8/n7feeovBgwfXZ/jmN7/JKaecwnHHHVf/OTSnudcF6N+/P6+99hrbb7/9Fp+jPRk6dCivv/46AwcOzB1FUpWznkiqtJacfOEm4HLgQGC/0k/VT2WXG6O774YG30XbjY9+9KNMmjSpfnz11Vfz4IMPsmjRIqBoMq688kqmTJnClClTePnllznyyCMB6NKlS/3jOnbsyIYNG97RlDRWfkyHDh02e3yHDh3YsGHDZtumlHg/l7WaPHkye++992brTj31VP785z/zyiuv1K+79dZbWbZsGYMHD2bQoEHMmTOnyd3punXrxtq1a+vH11xzDd///veZO3cuI0eObHK2pan3ISKa/Z06depUv778XkKx7/s3vvENpk2bxrXXXluf4/zzz+cXv/gFa9asYezYsZvNkDVlS+/l2rVr6dat2xYf394sXryYIUOGcNRRR5Wb7T0i4s7cuSRVH+uJpEpryQVeRwMHpJT+MaX0T6Wfqp/KLjdGhxwCDfqAduOwww5j7dq1m+3utnr16vrbRx11FD//+c9Zv349UBxvs2rVqmafb6+99mLOnDn1u63ddNNNHHzwwe8r25FHHsk111xT3yQsXbp0i9unlLjiiiuYP38+Rx999Gb3derUiXPOOYfx48fXr7vlllv44x//yJw5c5gzZ079iSca23vvvTfbDe/FF19k//3355JLLqFv377MnTuXnj17smLFivptxo0bx8033wwUx2P17duXXr16ceSRR3LVVZv2EH23M8K9+eab7LTTTgD86le/2izDsGHD+Pa3v83o0aOZOXPmOzI01NzrppR4/fXXGTRo0BZztDcXX3wxd9xxBxdccAHf+ta3oDik7seZY0mqQtYTSZXWksboWd7f3l/tWrkxevBB2EI/kU1EcMcdd/DII48wePBgxowZw2mnncYPf/hDAM444wyGDBnCqFGjGDp0KF/5ylfeMbPTUNeuXfnP//xPTjjhBIYNG0aHDh02O7HDe3HGGWew6667Mnz4cEaMGLHZGdcaOu+88+pP1z1hwgQeeughOnfu/I7tvvSlL9VnnzNnDq+88gpjx46tv3/w4MH06tWLJ598crPHjRs3jsmTJ9fPAp133nkMGzaMoUOHMm7cOEaMGMGhhx7KjBkz6k++cPHFFzNx4kSGDx/O+eefX9/U/Mu//AvLli2rP3nDQw89tMX34OKLL+aEE07goIMOqj/5A8D48ePrn6Nbt24cc8wxDB8+nLq6OkaMGMFPf/rTzZ6nudd9+umnGTt2bP3uitXi4IMPZtCgQaxfv77ceK8GJr3LwyTpHawnkiot3m0Xq4h4CBgJPAWsK69PKR3bttHe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\n", "text/plain": [ "
" ] @@ -103,7 +258,7 @@ "\n", "#Add this mechanism to a dictionary which is passed into the Mixture txtl.TxTlExtract\n", "global_mechanisms = {\"dilution\":dilution_mechanism}\n", - "myMixture = TxTlExtract(name = \"txtl\", parameters = parameters, global_mechanisms = global_mechanisms, parameter_warnings= False)\n", + "myMixture = TxTlExtract(name = \"txtl\", parameters = parameters, global_mechanisms = global_mechanisms)\n", "\n", "#Add machinery attributes to species I want constiutively expressed at the dilution rate\n", "myMixture.rnap.add_attribute(\"machinery\")\n", @@ -121,7 +276,8 @@ "myMixture.add_components(A_dna)\n", "myMixture.add_components(A_genome)\n", "myCRN = myMixture.compile_crn()\n", - "print(myCRN.pretty_print(show_rates = True, show_materials = True, show_attributes = True))\n", + "print(myCRN.pretty_print(show_rates = True, show_materials = True, show_attributes = True, show_keys = False))\n", + "\n", "\n", "\n", "try:\n", @@ -130,61 +286,130 @@ " import pylab as plt\n", " timepoints = np.arange(0, 50, .1)\n", "\n", - " x0_dict = {repr(myMixture.ribosome.get_species()):100, \n", - " repr(myMixture.rnap.get_species()):20, \n", - " repr(myMixture.rnaase.get_species()):10, \n", - " repr(A_dna.dna):20, \n", + " x0_dict = {repr(myMixture.ribosome.get_species()):100,\n", + " repr(myMixture.rnap.get_species()):20,\n", + " repr(myMixture.rnaase.get_species()):10,\n", + " repr(A_dna.dna):20,\n", " repr(A_genome.dna):20}\n", "\n", - " full_result_sto = myCRN.simulate_with_bioscrape(timepoints, x0_dict, stochastic = True)\n", - " full_result_det = myCRN.simulate_with_bioscrape(timepoints, x0_dict, stochastic = False)\n", - "\n", - " #chemical_reaction_network.get_all_species_containing is a useful shortcut to get lists of species\n", - " tot_A_dna_det = np.sum(full_result_det[myCRN.get_all_species_containing(A_dna.dna, return_as_strings=True)], 1)\n", - " tot_A_genome_det = np.sum(full_result_det[myCRN.get_all_species_containing(A_genome.dna, return_as_strings=True)], 1)\n", - " tot_A_dna_sto = np.sum(full_result_sto[myCRN.get_all_species_containing(A_dna.dna, return_as_strings=True)], 1)\n", - " tot_A_genome_sto = np.sum(full_result_sto[myCRN.get_all_species_containing(A_genome.dna, return_as_strings=True)], 1)\n", - "\n", - " tot_A_dna_rna_det = np.sum(full_result_det[myCRN.get_all_species_containing(A_dna.transcript, return_as_strings=True)], 1)\n", - " tot_A_genome_rna_det = np.sum(full_result_det[myCRN.get_all_species_containing(A_genome.protein, return_as_strings=True)], 1)\n", - " tot_A_dna__rna_sto = np.sum(full_result_sto[myCRN.get_all_species_containing(A_dna.transcript, return_as_strings=True)], 1)\n", - " tot_A_genome_rna_sto = np.sum(full_result_sto[myCRN.get_all_species_containing(A_genome.protein, return_as_strings=True)], 1)\n", - "\n", - "\n", - " plt.figure(figsize = (14, 10))\n", - " plt.subplot(131)\n", - " plt.plot(timepoints, tot_A_dna_det, color = \"blue\", label = \"Non-Genomic DNA (deterministic)\")\n", - " plt.plot(timepoints, tot_A_genome_det, color = \"cyan\", label = \"Genomic DNA (deterministic)\")\n", - " plt.plot(timepoints, tot_A_dna_sto, \":\", color = \"blue\", label = \"Non-Genomic DNA (stochastic)\")\n", - " plt.plot(timepoints, tot_A_genome_sto, \":\", color = \"cyan\", label = \"Genomic DNA (stochastic)\")\n", - " plt.legend()\n", - " plt.xlabel(\"Time\")\n", - " plt.title(\"DNA\")\n", - " plt.ylabel(\"Concentration or Count\")\n", - "\n", - " plt.subplot(132)\n", - " plt.plot(timepoints, tot_A_dna_rna_det, color = \"blue\", label = \"Non-Genomic RNA (deterministic)\")\n", - " plt.plot(timepoints, tot_A_genome_rna_det, color = \"cyan\", label = \"Genomic RNA (deterministic)\")\n", - " plt.plot(timepoints, tot_A_dna__rna_sto, \":\", color = \"blue\", label = \"Non-Genomic RNA (stochastic)\")\n", - " plt.plot(timepoints, tot_A_genome_rna_sto, \":\", color = \"cyan\", label = \"Genomic RNA (stochastic)\")\n", - " plt.legend()\n", - " plt.xlabel(\"Time\")\n", - " plt.title(\"RNA\")\n", - " plt.ylabel(\"Concentration / Count\")\n", - "\n", - " plt.subplot(133)\n", - " plt.plot(timepoints, full_result_det[str(A_dna.protein)], color = \"blue\", label = \"Non-Genomic Protein (deterministic)\")\n", - " plt.plot(timepoints, full_result_det[str(A_genome.protein)], color = \"cyan\", label = \"Genomic Protein (deterministic)\")\n", - " plt.plot(timepoints, full_result_sto[str(A_dna.protein)], \":\", color = \"blue\", label = \"Non-Genomic Protein (stochastic)\")\n", - " plt.plot(timepoints, full_result_sto[str(A_genome.protein)], \":\", color = \"cyan\", label = \"Genomic Protein (stochastic)\")\n", - " plt.legend()\n", - " plt.title(\"Protein\")\n", - " plt.xlabel(\"Time\")\n", - " plt.ylabel(\"Concentration / Count\")\n", - "\n", - " plt.show()\n", + " full_result_sto = myCRN.simulate_with_bioscrape_via_sbml(timepoints, initial_condition_dict = x0_dict, stochastic = True)\n", + " full_result_det = myCRN.simulate_with_bioscrape_via_sbml(timepoints, initial_condition_dict = x0_dict, stochastic = False)\n", + "\n", + " if (full_result_det is not None) and (full_result_sto is not None):\n", + " #chemical_reaction_network.get_all_species_containing is a useful shortcut to get lists of species\n", + " tot_A_dna_det = np.sum(full_result_det[myCRN.get_all_species_containing(A_dna.dna, return_as_strings=True)], 1)\n", + " tot_A_genome_det = np.sum(full_result_det[myCRN.get_all_species_containing(A_genome.dna, return_as_strings=True)], 1)\n", + " tot_A_dna_sto = np.sum(full_result_sto[myCRN.get_all_species_containing(A_dna.dna, return_as_strings=True)], 1)\n", + " tot_A_genome_sto = np.sum(full_result_sto[myCRN.get_all_species_containing(A_genome.dna, return_as_strings=True)], 1)\n", + "\n", + " tot_A_dna_rna_det = np.sum(full_result_det[myCRN.get_all_species_containing(A_dna.transcript, return_as_strings=True)], 1)\n", + " tot_A_genome_rna_det = np.sum(full_result_det[myCRN.get_all_species_containing(A_genome.protein, return_as_strings=True)], 1)\n", + " tot_A_dna__rna_sto = np.sum(full_result_sto[myCRN.get_all_species_containing(A_dna.transcript, return_as_strings=True)], 1)\n", + " tot_A_genome_rna_sto = np.sum(full_result_sto[myCRN.get_all_species_containing(A_genome.protein, return_as_strings=True)], 1)\n", + "\n", + " plt.figure(figsize = (14, 10))\n", + " plt.subplot(131)\n", + " plt.plot(timepoints, tot_A_dna_det, color = \"blue\", label = \"Non-Genomic DNA (deterministic)\")\n", + " plt.plot(timepoints, tot_A_genome_det, color = \"cyan\", label = \"Genomic DNA (deterministic)\")\n", + " plt.plot(timepoints, tot_A_dna_sto, \":\", color = \"blue\", label = \"Non-Genomic DNA (stochastic)\")\n", + " plt.plot(timepoints, tot_A_genome_sto, \":\", color = \"cyan\", label = \"Genomic DNA (stochastic)\")\n", + " plt.legend()\n", + " plt.xlabel(\"Time\")\n", + " plt.title(\"DNA\")\n", + " plt.ylabel(\"Concentration or Count\")\n", + "\n", + " plt.subplot(132)\n", + " plt.plot(timepoints, tot_A_dna_rna_det, color = \"blue\", label = \"Non-Genomic RNA (deterministic)\")\n", + " plt.plot(timepoints, tot_A_genome_rna_det, color = \"cyan\", label = \"Genomic RNA (deterministic)\")\n", + " plt.plot(timepoints, tot_A_dna__rna_sto, \":\", color = \"blue\", label = \"Non-Genomic RNA (stochastic)\")\n", + " plt.plot(timepoints, tot_A_genome_rna_sto, \":\", color = \"cyan\", label = \"Genomic RNA (stochastic)\")\n", + " plt.legend()\n", + " plt.xlabel(\"Time\")\n", + " plt.title(\"RNA\")\n", + " plt.ylabel(\"Concentration / Count\")\n", + "\n", + " plt.subplot(133)\n", + " plt.plot(timepoints, full_result_det[str(A_dna.protein)], color = \"blue\", label = \"Non-Genomic Protein (deterministic)\")\n", + " plt.plot(timepoints, full_result_det[str(A_genome.protein)], color = \"cyan\", label = \"Genomic Protein (deterministic)\")\n", + " plt.plot(timepoints, full_result_sto[str(A_dna.protein)], \":\", color = \"blue\", label = \"Non-Genomic Protein (stochastic)\")\n", + " plt.plot(timepoints, full_result_sto[str(A_genome.protein)], \":\", color = \"cyan\", label = \"Genomic Protein (stochastic)\")\n", + " plt.legend()\n", + " plt.title(\"Protein\")\n", + " plt.xlabel(\"Time\")\n", + " plt.ylabel(\"Concentration / Count\")\n", + "\n", + " plt.show()\n", "except ModuleNotFoundError:\n", - " pass" + " print('please install the plotting libraries: pip install biocrnpyler[all]')\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Example 2: Global Dilution using material_type with and without recursive_species_filtering\n", + "\n", + "In this example a very simple model of a piece of DNA $G$ binding to a protein $P$ to form a complex will be considered. Dilution will be applied to all species excent those of type \"dna\". When recursive_species_filtering is False, the protein AND the DNA-protein complex are both diluted. When recursive_species_filtering is True, only the protein is diluted." + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "CRN: recursive_species_filtering = False:\n", + " Species = protein_A, dna_G, complex_dna_G_protein_A\n", + "Reactions = [\n", + "\tprotein[A]+dna[G] <--> complex[dna[G]:protein[A]]\n", + "\tprotein[A] --> \n", + "\tcomplex[dna[G]:protein[A]] --> \n", + "]\n", + "\n", + "CRN: recursive_species_filtering = True:\n", + " Species (3) = {0. protein[A], 1. dna[G], 2. complex[dna[G]:protein[A]]}\n", + "\n", + "Reactions (2) = [\n", + "0. protein[A]+dna[G] <--> complex[dna[G]:protein[A]]\n", + " Kf=k_forward * protein_A * dna_G\n", + " Kr=k_reverse * complex_dna_G_protein_A\n", + " k_forward=100\n", + " found_key=(mech=None, partid=None, name=kb).\n", + " search_key=(mech=one_step_binding, partid=dna_G_protein_A, name=kb).\n", + " k_reverse=20\n", + " found_key=(mech=None, partid=None, name=ku).\n", + " search_key=(mech=one_step_binding, partid=dna_G_protein_A, name=ku).\n", + "\n", + "1. protein[A] --> \n", + " Kf=k_forward * protein_A\n", + " k_forward=0.5\n", + " found_key=(mech=None, partid=None, name=kdil).\n", + " search_key=(mech=global_degredation_via_dilution, partid=protein_A, name=kdil).\n", + "\n", + "]\n" + ] + } + ], + "source": [ + "parameters = {\"kb\":kb, \"ku\":ku,\"kdil\":kdil}\n", + "\n", + "G = Species(\"G\", material_type = \"dna\")\n", + "A = Species(\"A\", material_type = \"protein\")\n", + "C1 = ChemicalComplex([G, A])\n", + "\n", + "dilution_mechanism_no_recursion = Dilution(filter_dict = {\"dna\":False}, default_on = True, recursive_species_filtering = False)\n", + "M_no_recursion = ExpressionExtract(components = [C1], global_mechanisms = {\"dilution\":dilution_mechanism_no_recursion}, parameters = parameters)\n", + "CRN_no_recursion = M_no_recursion.compile_crn()\n", + "print(\"CRN: recursive_species_filtering = False:\\n\", CRN_no_recursion)\n", + "\n", + "dilution_mechanism_recursion = Dilution(filter_dict = {\"dna\":False}, default_on = True, recursive_species_filtering = True)\n", + "M_recursion = ExpressionExtract(components = [C1], global_mechanisms = {\"dilution\":dilution_mechanism_recursion}, parameters = parameters)\n", + "CRN_recursion = M_recursion.compile_crn()\n", + "print(\"\\nCRN: recursive_species_filtering = True:\\n\", CRN_recursion.pretty_print(show_keys = True))" ] }, { @@ -216,4 +441,4 @@ }, "nbformat": 4, "nbformat_minor": 4 -} +} \ No newline at end of file diff --git a/examples/7. Network Plotting Examples.ipynb b/examples/7. Network Plotting Examples.ipynb index 4a095fa9..c4bb043a 100644 --- a/examples/7. Network Plotting Examples.ipynb +++ b/examples/7. Network Plotting Examples.ipynb @@ -45,45 +45,37 @@ }, { "cell_type": "code", - "execution_count": 2, - "metadata": {}, + "execution_count": 3, + "metadata": { + "tags": [] + }, "outputs": [ { - "name": "stdout", - "output_type": "stream", - "text": [ - "Species (9) = {0. protein[RNAP], 1. protein[Ribo], 2. protein[RNAase], 3. complexprotein[RNAase]:rna[G1]], 4. complexprotein[Ribo]:rna[G1]], 5. rna[G1], 6. complexdna[G1]:protein[RNAP]], 7. protein[GFP], 8. dna[G1]}\n", - "Reactions (6) = [\n", - "0. dna[G1] + protein[RNAP] <--> complexdna[G1]:protein[RNAP]] \n", - " massaction: k_f(dna[G1],protein[RNAP])=100.0*dna[G1]*protein[RNAP]\n", - " k_r(complexdna[G1]:protein[RNAP]])=10.0*complexdna[G1]:protein[RNAP]]\n", - "1. complexdna[G1]:protein[RNAP]] --> dna[G1] + rna[G1] + protein[RNAP] \n", - " massaction: k_f(complexdna[G1]:protein[RNAP]])=3.0*complexdna[G1]:protein[RNAP]]\n", - "2. rna[G1] + protein[Ribo] <--> complexprotein[Ribo]:rna[G1]] \n", - " massaction: k_f(rna[G1],protein[Ribo])=10.0*rna[G1]*protein[Ribo]\n", - " k_r(complexprotein[Ribo]:rna[G1]])=0.25*complexprotein[Ribo]:rna[G1]]\n", - "3. complexprotein[Ribo]:rna[G1]] --> rna[G1] + protein[GFP] + protein[Ribo] \n", - " massaction: k_f(complexprotein[Ribo]:rna[G1]])=2.0*complexprotein[Ribo]:rna[G1]]\n", - "4. rna[G1] + protein[RNAase] <--> complexprotein[RNAase]:rna[G1]] \n", - " massaction: k_f(rna[G1],protein[RNAase])=10.0*rna[G1]*protein[RNAase]\n", - " k_r(complexprotein[RNAase]:rna[G1]])=0.5*complexprotein[RNAase]:rna[G1]]\n", - "5. complexprotein[RNAase]:rna[G1]] --> protein[RNAase] \n", - " massaction: k_f(complexprotein[RNAase]:rna[G1]])=1.0*complexprotein[RNAase]:rna[G1]]\n", - "]\n" + "ename": "AttributeError", + "evalue": "module 'numpy' has no attribute 'float64'", + "output_type": "error", + "traceback": [ + "\u001B[0;31m---------------------------------------------------------------------------\u001B[0m", + "\u001B[0;31mAttributeError\u001B[0m Traceback (most recent call last)", + "\u001B[0;32m\u001B[0m in \u001B[0;36m\u001B[0;34m\u001B[0m\n\u001B[0;32m----> 1\u001B[0;31m \u001B[0;32mfrom\u001B[0m \u001B[0mbiocrnpyler\u001B[0m \u001B[0;32mimport\u001B[0m \u001B[0;34m*\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[0m\u001B[1;32m 2\u001B[0m \u001B[0;34m\u001B[0m\u001B[0m\n\u001B[1;32m 3\u001B[0m \u001B[0;34m\u001B[0m\u001B[0m\n\u001B[1;32m 4\u001B[0m \u001B[0mtxtl\u001B[0m \u001B[0;34m=\u001B[0m \u001B[0mTxTlExtract\u001B[0m\u001B[0;34m(\u001B[0m\u001B[0;34m\"mixture1\"\u001B[0m\u001B[0;34m,\u001B[0m \u001B[0mparameter_file\u001B[0m \u001B[0;34m=\u001B[0m \u001B[0;34m'default_parameters.txt'\u001B[0m\u001B[0;34m)\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[1;32m 5\u001B[0m \u001B[0mdna\u001B[0m \u001B[0;34m=\u001B[0m \u001B[0mDNAassembly\u001B[0m\u001B[0;34m(\u001B[0m\u001B[0;34m\"mydna\"\u001B[0m\u001B[0;34m,\u001B[0m\u001B[0mpromoter\u001B[0m\u001B[0;34m=\u001B[0m\u001B[0mRegulatedPromoter\u001B[0m\u001B[0;34m(\u001B[0m\u001B[0;34m\"plac\"\u001B[0m\u001B[0;34m,\u001B[0m\u001B[0;34m[\u001B[0m\u001B[0;34m\"laci\"\u001B[0m\u001B[0;34m]\u001B[0m\u001B[0;34m)\u001B[0m\u001B[0;34m,\u001B[0m\u001B[0mrbs\u001B[0m\u001B[0;34m=\u001B[0m\u001B[0;34m\"UTR1\"\u001B[0m\u001B[0;34m,\u001B[0m\u001B[0mprotein\u001B[0m\u001B[0;34m=\u001B[0m\u001B[0;34m\"GFP\"\u001B[0m\u001B[0;34m,\u001B[0m \u001B[0minitial_conc\u001B[0m \u001B[0;34m=\u001B[0m \u001B[0;36m10\u001B[0m\u001B[0;34m)\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n", + "\u001B[0;32m~/PycharmProjects/biocrnplyler/biocrnpyler/__init__.py\u001B[0m in \u001B[0;36m\u001B[0;34m\u001B[0m\n\u001B[1;32m 35\u001B[0m \u001B[0;32mfrom\u001B[0m \u001B[0;34m.\u001B[0m\u001B[0msbmlutil\u001B[0m \u001B[0;32mimport\u001B[0m \u001B[0;34m*\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[1;32m 36\u001B[0m \u001B[0;32mtry\u001B[0m\u001B[0;34m:\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[0;32m---> 37\u001B[0;31m \u001B[0;32mfrom\u001B[0m \u001B[0;34m.\u001B[0m\u001B[0mplotting\u001B[0m \u001B[0;32mimport\u001B[0m \u001B[0;34m*\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[0m\u001B[1;32m 38\u001B[0m \u001B[0;32mexcept\u001B[0m \u001B[0mModuleNotFoundError\u001B[0m \u001B[0;32mas\u001B[0m \u001B[0me\u001B[0m\u001B[0;34m:\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[1;32m 39\u001B[0m \u001B[0mwarn\u001B[0m\u001B[0;34m(\u001B[0m\u001B[0mstr\u001B[0m\u001B[0;34m(\u001B[0m\u001B[0me\u001B[0m\u001B[0;34m)\u001B[0m\u001B[0;34m)\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n", + "\u001B[0;32m~/PycharmProjects/biocrnplyler/biocrnpyler/plotting.py\u001B[0m in \u001B[0;36m\u001B[0;34m\u001B[0m\n\u001B[1;32m 8\u001B[0m \u001B[0;34m\u001B[0m\u001B[0m\n\u001B[1;32m 9\u001B[0m \u001B[0;32mimport\u001B[0m \u001B[0mrandom\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[0;32m---> 10\u001B[0;31m \u001B[0;32mimport\u001B[0m \u001B[0mnetworkx\u001B[0m \u001B[0;32mas\u001B[0m \u001B[0mnx\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[0m\u001B[1;32m 11\u001B[0m \u001B[0;32mimport\u001B[0m \u001B[0mstatistics\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[1;32m 12\u001B[0m from bokeh.models import (BoxSelectTool, Circle,Square, EdgesAndLinkedNodes, HoverTool,\n", + "\u001B[0;32m~/PycharmProjects/biocrnplyler/venv/lib/python3.7/site-packages/networkx/__init__.py\u001B[0m in \u001B[0;36m\u001B[0;34m\u001B[0m\n\u001B[1;32m 113\u001B[0m \u001B[0;32mfrom\u001B[0m \u001B[0mnetworkx\u001B[0m\u001B[0;34m.\u001B[0m\u001B[0mgenerators\u001B[0m \u001B[0;32mimport\u001B[0m \u001B[0;34m*\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[1;32m 114\u001B[0m \u001B[0;34m\u001B[0m\u001B[0m\n\u001B[0;32m--> 115\u001B[0;31m \u001B[0;32mimport\u001B[0m \u001B[0mnetworkx\u001B[0m\u001B[0;34m.\u001B[0m\u001B[0mreadwrite\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[0m\u001B[1;32m 116\u001B[0m \u001B[0;32mfrom\u001B[0m \u001B[0mnetworkx\u001B[0m\u001B[0;34m.\u001B[0m\u001B[0mreadwrite\u001B[0m \u001B[0;32mimport\u001B[0m \u001B[0;34m*\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[1;32m 117\u001B[0m \u001B[0;34m\u001B[0m\u001B[0m\n", + "\u001B[0;32m~/PycharmProjects/biocrnplyler/venv/lib/python3.7/site-packages/networkx/readwrite/__init__.py\u001B[0m in \u001B[0;36m\u001B[0;34m\u001B[0m\n\u001B[1;32m 13\u001B[0m \u001B[0;32mfrom\u001B[0m \u001B[0mnetworkx\u001B[0m\u001B[0;34m.\u001B[0m\u001B[0mreadwrite\u001B[0m\u001B[0;34m.\u001B[0m\u001B[0mnx_yaml\u001B[0m \u001B[0;32mimport\u001B[0m \u001B[0;34m*\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[1;32m 14\u001B[0m \u001B[0;32mfrom\u001B[0m \u001B[0mnetworkx\u001B[0m\u001B[0;34m.\u001B[0m\u001B[0mreadwrite\u001B[0m\u001B[0;34m.\u001B[0m\u001B[0mgml\u001B[0m \u001B[0;32mimport\u001B[0m \u001B[0;34m*\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[0;32m---> 15\u001B[0;31m \u001B[0;32mfrom\u001B[0m \u001B[0mnetworkx\u001B[0m\u001B[0;34m.\u001B[0m\u001B[0mreadwrite\u001B[0m\u001B[0;34m.\u001B[0m\u001B[0mgraphml\u001B[0m \u001B[0;32mimport\u001B[0m \u001B[0;34m*\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[0m\u001B[1;32m 16\u001B[0m \u001B[0;32mfrom\u001B[0m \u001B[0mnetworkx\u001B[0m\u001B[0;34m.\u001B[0m\u001B[0mreadwrite\u001B[0m\u001B[0;34m.\u001B[0m\u001B[0mgexf\u001B[0m \u001B[0;32mimport\u001B[0m \u001B[0;34m*\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[1;32m 17\u001B[0m \u001B[0;32mfrom\u001B[0m \u001B[0mnetworkx\u001B[0m\u001B[0;34m.\u001B[0m\u001B[0mreadwrite\u001B[0m\u001B[0;34m.\u001B[0m\u001B[0mnx_shp\u001B[0m \u001B[0;32mimport\u001B[0m \u001B[0;34m*\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n", + "\u001B[0;32m~/PycharmProjects/biocrnplyler/venv/lib/python3.7/site-packages/networkx/readwrite/graphml.py\u001B[0m in \u001B[0;36m\u001B[0;34m\u001B[0m\n\u001B[1;32m 312\u001B[0m \u001B[0;34m\u001B[0m\u001B[0m\n\u001B[1;32m 313\u001B[0m \u001B[0;34m\u001B[0m\u001B[0m\n\u001B[0;32m--> 314\u001B[0;31m \u001B[0;32mclass\u001B[0m \u001B[0mGraphML\u001B[0m\u001B[0;34m(\u001B[0m\u001B[0mobject\u001B[0m\u001B[0;34m)\u001B[0m\u001B[0;34m:\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[0m\u001B[1;32m 315\u001B[0m \u001B[0mNS_GRAPHML\u001B[0m \u001B[0;34m=\u001B[0m \u001B[0;34m\"http://graphml.graphdrawing.org/xmlns\"\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[1;32m 316\u001B[0m \u001B[0mNS_XSI\u001B[0m \u001B[0;34m=\u001B[0m \u001B[0;34m\"http://www.w3.org/2001/XMLSchema-instance\"\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n", + "\u001B[0;32m~/PycharmProjects/biocrnplyler/venv/lib/python3.7/site-packages/networkx/readwrite/graphml.py\u001B[0m in \u001B[0;36mGraphML\u001B[0;34m()\u001B[0m\n\u001B[1;32m 342\u001B[0m \u001B[0;32melse\u001B[0m\u001B[0;34m:\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[1;32m 343\u001B[0m \u001B[0;31m# prepend so that python types are created upon read (last entry wins)\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[0;32m--> 344\u001B[0;31m types = [(np.float64, \"float\"), (np.float32, \"float\"),\n\u001B[0m\u001B[1;32m 345\u001B[0m \u001B[0;34m(\u001B[0m\u001B[0mnp\u001B[0m\u001B[0;34m.\u001B[0m\u001B[0mfloat16\u001B[0m\u001B[0;34m,\u001B[0m \u001B[0;34m\"float\"\u001B[0m\u001B[0;34m)\u001B[0m\u001B[0;34m,\u001B[0m \u001B[0;34m(\u001B[0m\u001B[0mnp\u001B[0m\u001B[0;34m.\u001B[0m\u001B[0mfloat_\u001B[0m\u001B[0;34m,\u001B[0m \u001B[0;34m\"float\"\u001B[0m\u001B[0;34m)\u001B[0m\u001B[0;34m,\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[1;32m 346\u001B[0m \u001B[0;34m(\u001B[0m\u001B[0mnp\u001B[0m\u001B[0;34m.\u001B[0m\u001B[0mint\u001B[0m\u001B[0;34m,\u001B[0m \u001B[0;34m\"int\"\u001B[0m\u001B[0;34m)\u001B[0m\u001B[0;34m,\u001B[0m \u001B[0;34m(\u001B[0m\u001B[0mnp\u001B[0m\u001B[0;34m.\u001B[0m\u001B[0mint8\u001B[0m\u001B[0;34m,\u001B[0m \u001B[0;34m\"int\"\u001B[0m\u001B[0;34m)\u001B[0m\u001B[0;34m,\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n", + "\u001B[0;31mAttributeError\u001B[0m: module 'numpy' has no attribute 'float64'" ] } ], "source": [ - "%matplotlib inline\n", - "\n", "from biocrnpyler import *\n", - "import numpy as np\n", "\n", - "txtl = CRNLab(\"GFP\")\n", - "txtl.mixture(\"mixture1\", extract = \"TxTlExtract\", mixture_volume = 1e-6, mixture_parameters = 'BasicExtract.tsv')\n", - "dna = DNAassembly(\"mydna\",promoter=RegulatedPromoter(\"plac\",[\"laci\"]),rbs=\"UTR1\",protein=\"GFP\")\n", - "txtl.add_dna(name = \"G1\", promoter = \"pBest\", rbs = \"BCD2\", protein = \"GFP\", initial_conc = 10, volume = 1e-7)\n", - "crn1 = txtl.get_model()\n", + "\n", + "txtl = TxTlExtract(\"mixture1\", parameter_file = 'default_parameters.txt')\n", + "dna = DNAassembly(\"mydna\",promoter=RegulatedPromoter(\"plac\",[\"laci\"]),rbs=\"UTR1\",protein=\"GFP\", initial_conc = 10)\n", + "txtl.add_component(dna)\n", + "crn1 = txtl.compile_crn()\n", "print(crn1.pretty_print())" ] }, @@ -97,393 +89,25 @@ }, { "cell_type": "code", - "execution_count": 3, - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "\n", - "
\n", - " \n", - " Loading BokehJS ...\n", - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "application/javascript": [ - "\n", - "(function(root) {\n", - " function now() {\n", - " return new Date();\n", - " }\n", - "\n", - " var force = true;\n", - "\n", - " if (typeof root._bokeh_onload_callbacks === \"undefined\" || force === true) {\n", - " root._bokeh_onload_callbacks = [];\n", - " root._bokeh_is_loading = undefined;\n", - " }\n", - "\n", - " var JS_MIME_TYPE = 'application/javascript';\n", - " var HTML_MIME_TYPE = 'text/html';\n", - " var EXEC_MIME_TYPE = 'application/vnd.bokehjs_exec.v0+json';\n", - " var CLASS_NAME = 'output_bokeh rendered_html';\n", - "\n", - " /**\n", - " * Render data to the DOM node\n", - " */\n", - " function render(props, node) {\n", - " var script = document.createElement(\"script\");\n", - " node.appendChild(script);\n", - " }\n", - "\n", - " /**\n", - " * Handle when an output is cleared or removed\n", - " */\n", - " function handleClearOutput(event, handle) {\n", - " var cell = handle.cell;\n", - "\n", - " var id = cell.output_area._bokeh_element_id;\n", - " var server_id = cell.output_area._bokeh_server_id;\n", - " // Clean up Bokeh references\n", - " if (id != null && id in Bokeh.index) {\n", - " Bokeh.index[id].model.document.clear();\n", - " delete Bokeh.index[id];\n", - " }\n", - "\n", - " if (server_id !== undefined) {\n", - " // Clean up Bokeh references\n", - " var cmd = \"from bokeh.io.state import curstate; print(curstate().uuid_to_server['\" + server_id + \"'].get_sessions()[0].document.roots[0]._id)\";\n", - " cell.notebook.kernel.execute(cmd, {\n", - " iopub: {\n", - " output: function(msg) {\n", - " var id = msg.content.text.trim();\n", - " if (id in Bokeh.index) {\n", - " Bokeh.index[id].model.document.clear();\n", - " delete Bokeh.index[id];\n", - " }\n", - " }\n", - " }\n", - " });\n", - " // Destroy server and session\n", - " var cmd = \"import bokeh.io.notebook as ion; ion.destroy_server('\" + server_id + \"')\";\n", - " cell.notebook.kernel.execute(cmd);\n", - " }\n", - " }\n", - "\n", - " /**\n", - " * Handle when a new output is added\n", - " */\n", - " function handleAddOutput(event, handle) {\n", - " var output_area = handle.output_area;\n", - " var output = handle.output;\n", - "\n", - " // limit handleAddOutput to display_data with EXEC_MIME_TYPE content only\n", - " if ((output.output_type != \"display_data\") || (!output.data.hasOwnProperty(EXEC_MIME_TYPE))) {\n", - " return\n", - " }\n", - "\n", - " var toinsert = output_area.element.find(\".\" + CLASS_NAME.split(' ')[0]);\n", - "\n", - " if (output.metadata[EXEC_MIME_TYPE][\"id\"] !== undefined) {\n", - " toinsert[toinsert.length - 1].firstChild.textContent = output.data[JS_MIME_TYPE];\n", - " // store reference to embed id on output_area\n", - " output_area._bokeh_element_id = output.metadata[EXEC_MIME_TYPE][\"id\"];\n", - " }\n", - " if (output.metadata[EXEC_MIME_TYPE][\"server_id\"] !== undefined) {\n", - " var bk_div = document.createElement(\"div\");\n", - " bk_div.innerHTML = output.data[HTML_MIME_TYPE];\n", - " var script_attrs = bk_div.children[0].attributes;\n", - " for (var i = 0; i < script_attrs.length; i++) {\n", - " toinsert[toinsert.length - 1].firstChild.setAttribute(script_attrs[i].name, script_attrs[i].value);\n", - " }\n", - " // store reference to server id on output_area\n", - " output_area._bokeh_server_id = output.metadata[EXEC_MIME_TYPE][\"server_id\"];\n", - " }\n", - " }\n", - "\n", - " function register_renderer(events, OutputArea) {\n", - "\n", - " function append_mime(data, metadata, element) {\n", - " // create a DOM node to render to\n", - " var toinsert = this.create_output_subarea(\n", - " metadata,\n", - " CLASS_NAME,\n", - " EXEC_MIME_TYPE\n", - " );\n", - " this.keyboard_manager.register_events(toinsert);\n", - " // Render to node\n", - " var props = {data: data, metadata: metadata[EXEC_MIME_TYPE]};\n", - " render(props, toinsert[toinsert.length - 1]);\n", - " element.append(toinsert);\n", - " return toinsert\n", - " }\n", - "\n", - " /* Handle when an output is cleared or removed */\n", - " events.on('clear_output.CodeCell', handleClearOutput);\n", - " events.on('delete.Cell', handleClearOutput);\n", - "\n", - " /* Handle when a new output is added */\n", - " events.on('output_added.OutputArea', handleAddOutput);\n", - "\n", - " /**\n", - " * Register the mime type and append_mime function with output_area\n", - " */\n", - " OutputArea.prototype.register_mime_type(EXEC_MIME_TYPE, append_mime, {\n", - " /* Is output safe? */\n", - " safe: true,\n", - " /* Index of renderer in `output_area.display_order` */\n", - " index: 0\n", - " });\n", - " }\n", - "\n", - " // register the mime type if in Jupyter Notebook environment and previously unregistered\n", - " if (root.Jupyter !== undefined) {\n", - " var events = require('base/js/events');\n", - " var OutputArea = require('notebook/js/outputarea').OutputArea;\n", - "\n", - " if (OutputArea.prototype.mime_types().indexOf(EXEC_MIME_TYPE) == -1) {\n", - " register_renderer(events, OutputArea);\n", - " }\n", - " }\n", - "\n", - " \n", - " if (typeof (root._bokeh_timeout) === \"undefined\" || force === true) {\n", - " root._bokeh_timeout = Date.now() + 5000;\n", - " root._bokeh_failed_load = false;\n", - " }\n", - "\n", - " var NB_LOAD_WARNING = {'data': {'text/html':\n", - " \"
\\n\"+\n", - " \"

\\n\"+\n", - " \"BokehJS does not appear to have successfully loaded. If loading BokehJS from CDN, this \\n\"+\n", - " \"may be due to a slow or bad network connection. Possible fixes:\\n\"+\n", - " \"

\\n\"+\n", - " \"
    \\n\"+\n", - " \"
  • re-rerun `output_notebook()` to attempt to load from CDN again, or
  • \\n\"+\n", - " \"
  • use INLINE resources instead, as so:
  • \\n\"+\n", - " \"
\\n\"+\n", - " \"\\n\"+\n", - " \"from bokeh.resources import INLINE\\n\"+\n", - " \"output_notebook(resources=INLINE)\\n\"+\n", - " \"\\n\"+\n", - " \"
\"}};\n", - "\n", - " function display_loaded() {\n", - " var el = document.getElementById(\"1001\");\n", - " if (el != null) {\n", - " el.textContent = \"BokehJS is loading...\";\n", - " }\n", - " if (root.Bokeh !== undefined) {\n", - " if (el != null) {\n", - " el.textContent = \"BokehJS \" + root.Bokeh.version + \" successfully loaded.\";\n", - " }\n", - " } else if (Date.now() < root._bokeh_timeout) {\n", - " setTimeout(display_loaded, 100)\n", - " }\n", - " }\n", - "\n", - "\n", - " function run_callbacks() {\n", - " try {\n", - " root._bokeh_onload_callbacks.forEach(function(callback) {\n", - " if (callback != null)\n", - " callback();\n", - " });\n", - " } finally {\n", - " delete root._bokeh_onload_callbacks\n", - " }\n", - " console.debug(\"Bokeh: all callbacks have finished\");\n", - " }\n", - "\n", - " function load_libs(css_urls, js_urls, callback) {\n", - " if (css_urls == null) css_urls = [];\n", - " if (js_urls == null) js_urls = [];\n", - "\n", - " root._bokeh_onload_callbacks.push(callback);\n", - " if (root._bokeh_is_loading > 0) {\n", - " console.debug(\"Bokeh: BokehJS is being loaded, scheduling callback at\", now());\n", - " return null;\n", - " }\n", - " if (js_urls == null || js_urls.length === 0) {\n", - " run_callbacks();\n", - " return null;\n", - " }\n", - " console.debug(\"Bokeh: BokehJS not loaded, scheduling load and callback at\", now());\n", - " root._bokeh_is_loading = css_urls.length + js_urls.length;\n", - "\n", - " function on_load() {\n", - " root._bokeh_is_loading--;\n", - " if (root._bokeh_is_loading === 0) {\n", - " console.debug(\"Bokeh: all BokehJS libraries/stylesheets loaded\");\n", - " run_callbacks()\n", - " }\n", - " }\n", - "\n", - " function on_error() {\n", - " console.error(\"failed to load \" + url);\n", - " }\n", - "\n", - " for (var i = 0; i < css_urls.length; i++) {\n", - " var url = css_urls[i];\n", - " const element = document.createElement(\"link\");\n", - " element.onload = on_load;\n", - " element.onerror = on_error;\n", - " element.rel = \"stylesheet\";\n", - " element.type = \"text/css\";\n", - " element.href = url;\n", - " console.debug(\"Bokeh: injecting link tag for BokehJS stylesheet: \", url);\n", - " document.body.appendChild(element);\n", - " }\n", - "\n", - " for (var i = 0; i < js_urls.length; i++) {\n", - " var url = js_urls[i];\n", - " var element = document.createElement('script');\n", - " element.onload = on_load;\n", - " element.onerror = on_error;\n", - " element.async = false;\n", - " element.src = url;\n", - " console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n", - " document.head.appendChild(element);\n", - " }\n", - " };var element = document.getElementById(\"1001\");\n", - " if (element == null) {\n", - " console.error(\"Bokeh: ERROR: autoload.js configured with elementid '1001' but no matching script tag was found. \")\n", - " return false;\n", - " }\n", - "\n", - " function inject_raw_css(css) {\n", - " const element = document.createElement(\"style\");\n", - " element.appendChild(document.createTextNode(css));\n", - " document.body.appendChild(element);\n", - " }\n", - "\n", - " var js_urls = [\"https://cdn.pydata.org/bokeh/release/bokeh-1.3.4.min.js\", \"https://cdn.pydata.org/bokeh/release/bokeh-widgets-1.3.4.min.js\", \"https://cdn.pydata.org/bokeh/release/bokeh-tables-1.3.4.min.js\", \"https://cdn.pydata.org/bokeh/release/bokeh-gl-1.3.4.min.js\"];\n", - " var css_urls = [];\n", - "\n", - " var inline_js = [\n", - " function(Bokeh) {\n", - " Bokeh.set_log_level(\"info\");\n", - " },\n", - " \n", - " function(Bokeh) {\n", - " \n", - " },\n", - " function(Bokeh) {} // ensure no trailing comma for IE\n", - " ];\n", - "\n", - " function run_inline_js() {\n", - " \n", - " if ((root.Bokeh !== undefined) || (force === true)) {\n", - " for (var i = 0; i < inline_js.length; i++) {\n", - " inline_js[i].call(root, root.Bokeh);\n", - " }if (force === true) {\n", - " display_loaded();\n", - " }} else if (Date.now() < root._bokeh_timeout) {\n", - " setTimeout(run_inline_js, 100);\n", - " } else if (!root._bokeh_failed_load) {\n", - " console.log(\"Bokeh: BokehJS failed to load within specified timeout.\");\n", - " root._bokeh_failed_load = true;\n", - " } else if (force !== true) {\n", - " var cell = $(document.getElementById(\"1001\")).parents('.cell').data().cell;\n", - " cell.output_area.append_execute_result(NB_LOAD_WARNING)\n", - " }\n", - "\n", - " }\n", - "\n", - " if (root._bokeh_is_loading === 0) {\n", - " console.debug(\"Bokeh: BokehJS loaded, going straight to plotting\");\n", - " run_inline_js();\n", - " } else {\n", - " load_libs(css_urls, js_urls, function() {\n", - " console.debug(\"Bokeh: BokehJS plotting callback run at\", now());\n", - " run_inline_js();\n", - " });\n", - " }\n", - "}(window));" - ], - "application/vnd.bokehjs_load.v0+json": "\n(function(root) {\n function now() {\n return new Date();\n }\n\n var force = true;\n\n if (typeof root._bokeh_onload_callbacks === \"undefined\" || force === true) {\n root._bokeh_onload_callbacks = [];\n root._bokeh_is_loading = undefined;\n }\n\n \n\n \n if (typeof (root._bokeh_timeout) === \"undefined\" || force === true) {\n root._bokeh_timeout = Date.now() + 5000;\n root._bokeh_failed_load = false;\n }\n\n var NB_LOAD_WARNING = {'data': {'text/html':\n \"
\\n\"+\n \"

\\n\"+\n \"BokehJS does not appear to have successfully loaded. If loading BokehJS from CDN, this \\n\"+\n \"may be due to a slow or bad network connection. Possible fixes:\\n\"+\n \"

\\n\"+\n \"
    \\n\"+\n \"
  • re-rerun `output_notebook()` to attempt to load from CDN again, or
  • \\n\"+\n \"
  • use INLINE resources instead, as so:
  • \\n\"+\n \"
\\n\"+\n \"\\n\"+\n \"from bokeh.resources import INLINE\\n\"+\n \"output_notebook(resources=INLINE)\\n\"+\n \"\\n\"+\n \"
\"}};\n\n function display_loaded() {\n var el = document.getElementById(\"1001\");\n if (el != null) {\n el.textContent = \"BokehJS is loading...\";\n }\n if (root.Bokeh !== undefined) {\n if (el != null) {\n el.textContent = \"BokehJS \" + root.Bokeh.version + \" successfully loaded.\";\n }\n } else if (Date.now() < root._bokeh_timeout) {\n setTimeout(display_loaded, 100)\n }\n }\n\n\n function run_callbacks() {\n try {\n root._bokeh_onload_callbacks.forEach(function(callback) {\n if (callback != null)\n callback();\n });\n } finally {\n delete root._bokeh_onload_callbacks\n }\n console.debug(\"Bokeh: all callbacks have finished\");\n }\n\n function load_libs(css_urls, js_urls, callback) {\n if (css_urls == null) css_urls = [];\n if (js_urls == null) js_urls = [];\n\n root._bokeh_onload_callbacks.push(callback);\n if (root._bokeh_is_loading > 0) {\n console.debug(\"Bokeh: BokehJS is being loaded, scheduling callback at\", now());\n return null;\n }\n if (js_urls == null || js_urls.length === 0) {\n run_callbacks();\n return null;\n }\n console.debug(\"Bokeh: BokehJS not loaded, scheduling load and callback at\", now());\n root._bokeh_is_loading = css_urls.length + js_urls.length;\n\n function on_load() {\n root._bokeh_is_loading--;\n if (root._bokeh_is_loading === 0) {\n console.debug(\"Bokeh: all BokehJS libraries/stylesheets loaded\");\n run_callbacks()\n }\n }\n\n function on_error() {\n console.error(\"failed to load \" + url);\n }\n\n for (var i = 0; i < css_urls.length; i++) {\n var url = css_urls[i];\n const element = document.createElement(\"link\");\n element.onload = on_load;\n element.onerror = on_error;\n element.rel = \"stylesheet\";\n element.type = \"text/css\";\n element.href = url;\n console.debug(\"Bokeh: injecting link tag for BokehJS stylesheet: \", url);\n document.body.appendChild(element);\n }\n\n for (var i = 0; i < js_urls.length; i++) {\n var url = js_urls[i];\n var element = document.createElement('script');\n element.onload = on_load;\n element.onerror = on_error;\n element.async = false;\n element.src = url;\n console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n document.head.appendChild(element);\n }\n };var element = document.getElementById(\"1001\");\n if (element == null) {\n console.error(\"Bokeh: ERROR: autoload.js configured with elementid '1001' but no matching script tag was found. \")\n return false;\n }\n\n function inject_raw_css(css) {\n const element = document.createElement(\"style\");\n element.appendChild(document.createTextNode(css));\n document.body.appendChild(element);\n }\n\n var js_urls = [\"https://cdn.pydata.org/bokeh/release/bokeh-1.3.4.min.js\", \"https://cdn.pydata.org/bokeh/release/bokeh-widgets-1.3.4.min.js\", \"https://cdn.pydata.org/bokeh/release/bokeh-tables-1.3.4.min.js\", \"https://cdn.pydata.org/bokeh/release/bokeh-gl-1.3.4.min.js\"];\n var css_urls = [];\n\n var inline_js = [\n function(Bokeh) {\n Bokeh.set_log_level(\"info\");\n },\n \n function(Bokeh) {\n \n },\n function(Bokeh) {} // ensure no trailing comma for IE\n ];\n\n function run_inline_js() {\n \n if ((root.Bokeh !== undefined) || (force === true)) {\n for (var i = 0; i < inline_js.length; i++) {\n inline_js[i].call(root, root.Bokeh);\n }if (force === true) {\n display_loaded();\n }} else if (Date.now() < root._bokeh_timeout) {\n setTimeout(run_inline_js, 100);\n } else if (!root._bokeh_failed_load) {\n console.log(\"Bokeh: BokehJS failed to load within specified timeout.\");\n root._bokeh_failed_load = true;\n } else if (force !== true) {\n var cell = $(document.getElementById(\"1001\")).parents('.cell').data().cell;\n cell.output_area.append_execute_result(NB_LOAD_WARNING)\n }\n\n }\n\n if (root._bokeh_is_loading === 0) {\n console.debug(\"Bokeh: BokehJS loaded, going straight to plotting\");\n run_inline_js();\n } else {\n load_libs(css_urls, js_urls, function() {\n console.debug(\"Bokeh: BokehJS plotting callback run at\", now());\n run_inline_js();\n });\n }\n}(window));" - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - "C:\\Users\\apand\\Anaconda3\\lib\\site-packages\\bokeh\\models\\graphs.py:164: UserWarning: Node keys in 'layout_function' don't match node keys in the graph. These nodes may not be displayed correctly.\n", - " warn(\"Node keys in 'layout_function' don't match node keys in the graph. \"\n" - ] - }, - { - "data": { - "text/html": [ - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "
\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "application/javascript": [ - "(function(root) {\n", - " function embed_document(root) {\n", - " \n", - " var docs_json = {\"e4a6bf3b-e149-48c5-9380-ace86ca13b49\":{\"roots\":{\"references\":[{\"attributes\":{\"plot_height\":500,\"plot_width\":500,\"renderers\":[{\"id\":\"1041\",\"type\":\"GraphRenderer\"},{\"id\":\"1009\",\"type\":\"GraphRenderer\"},{\"id\":\"1025\",\"type\":\"GraphRenderer\"}],\"title\":{\"id\":\"1133\",\"type\":\"Title\"},\"toolbar\":{\"id\":\"1122\",\"type\":\"Toolbar\"},\"x_range\":{\"id\":\"1083\",\"type\":\"Range1d\"},\"x_scale\":{\"id\":\"1134\",\"type\":\"LinearScale\"},\"y_range\":{\"id\":\"1084\",\"type\":\"Range1d\"},\"y_scale\":{\"id\":\"1136\",\"type\":\"LinearScale\"}},\"id\":\"1004\",\"type\":\"Plot\"},{\"attributes\":{\"data_source\":{\"id\":\"1043\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"1055\",\"type\":\"Circle\"},\"hover_glyph\":null,\"muted_glyph\":null,\"view\":{\"id\":\"1045\",\"type\":\"CDSView\"}},\"id\":\"1044\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"fill_alpha\":{\"value\":0},\"fill_color\":{\"field\":\"color\"},\"line_alpha\":{\"value\":0},\"size\":{\"units\":\"screen\",\"value\":12}},\"id\":\"1055\",\"type\":\"Circle\"},{\"attributes\":{},\"id\":\"1030\",\"type\":\"MultiLine\"},{\"attributes\":{\"callback\":null,\"data\":{\"end\":[],\"start\":[]},\"selected\":{\"id\":\"1174\",\"type\":\"Selection\"},\"selection_policy\":{\"id\":\"1175\",\"type\":\"UnionRenderers\"}},\"id\":\"1031\",\"type\":\"ColumnDataSource\"},{\"attributes\":{\"text\":\"\"},\"id\":\"1133\",\"type\":\"Title\"},{\"attributes\":{\"source\":{\"id\":\"1043\",\"type\":\"ColumnDataSource\"}},\"id\":\"1045\",\"type\":\"CDSView\"},{\"attributes\":{\"source\":{\"id\":\"1015\",\"type\":\"ColumnDataSource\"}},\"id\":\"1017\",\"type\":\"CDSView\"},{\"attributes\":{},\"id\":\"1136\",\"type\":\"LinearScale\"},{\"attributes\":{\"data_source\":{\"id\":\"1011\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"1085\",\"type\":\"Square\"},\"hover_glyph\":{\"id\":\"1095\",\"type\":\"Square\"},\"muted_glyph\":null,\"selection_glyph\":{\"id\":\"1090\",\"type\":\"Square\"},\"view\":{\"id\":\"1013\",\"type\":\"CDSView\"}},\"id\":\"1012\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"data_source\":{\"id\":\"1031\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"1030\",\"type\":\"MultiLine\"},\"hover_glyph\":null,\"muted_glyph\":null,\"view\":{\"id\":\"1033\",\"type\":\"CDSView\"}},\"id\":\"1032\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"fill_color\":{\"value\":\"#abdda4\"},\"size\":{\"units\":\"screen\",\"value\":8}},\"id\":\"1095\",\"type\":\"Square\"},{\"attributes\":{},\"id\":\"1134\",\"type\":\"LinearScale\"},{\"attributes\":{\"data_source\":{\"id\":\"1015\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"1014\",\"type\":\"MultiLine\"},\"hover_glyph\":null,\"muted_glyph\":null,\"view\":{\"id\":\"1017\",\"type\":\"CDSView\"}},\"id\":\"1016\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"attachment\":\"right\",\"callback\":null,\"renderers\":[{\"id\":\"1025\",\"type\":\"GraphRenderer\"}],\"tooltips\":[[\"name\",\"@species\"],[\"type\",\"@type\"]]},\"id\":\"1116\",\"type\":\"HoverTool\"},{\"attributes\":{\"callback\":null,\"data\":{\"end\":[10,12,14,14,15,12,13,12,14,10,11,10,9,1,7,9,6,1,6,2,5,6,8,2,6,3,4,3],\"start\":[1,2,3,4,4,5,5,6,6,7,7,9,10,10,10,11,11,11,12,12,12,13,13,13,14,14,14,15],\"weight\":[1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1],\"xs\":[[-55.21233635471055,-53.19062506703611,-52.06339418868147,-50.66042227847986,-55.51807863003807,-53.19062506703611],[26.715285999279068,25.299104519037336,23.506747894768658,23.61536009836396,27.890159278483424,25.299104519037336],[-4.300833886609078,-2.289449418918937,-1.3672289348363722,0.43586774850067966,-4.5044467120343725,-2.289449418918937],[-2.313594333804382,-0.4035818449432734,-3.029711166813157,0.43586774850067966,1.8243475977602812,-0.4035818449432734],[-2.313594333804382,-3.2153095043108477,-0.5953650595835054,-3.966959928251052,-5.478702334354141,-3.2153095043108477],[32.683183570053394,26.779690775073757,28.598535593890897,23.61536009836396,26.461872465708705,26.779690775073757],[32.683183570053394,38.92683545341906,37.26488408893873,42.19984341219332,39.036208338056035,38.92683545341906],[11.787388613642522,20.118171379395516,19.388892259198784,23.61536009836396,19.188530016229052,20.118171379395516],[11.787388613642522,3.84709657275158,5.215650234183155,0.43586774850067966,4.096687605455354,3.84709657275158],[-52.50854912329559,-51.33657341506167,-53.94984772765444,-50.66042227847986,-49.04403700381262,-51.33657341506167],[-52.50854912329559,-54.30766865626799,-51.67573483076475,-55.271339429687025,-56.48247725527935,-54.30766865626799],[-45.9590319355197,-48.160866577755165,-45.818064713063364,-50.66042227847986,-49.317983458176926,-48.160866577755165],[-50.66042227847986,-48.45858763624439,-50.801389500936196,-45.9590319355197,-47.30147075582263,-48.45858763624439],[-50.66042227847986,-52.6821335661543,-53.80936444450894,-55.21233635471055,-50.35468000315234,-52.6821335661543],[-50.66042227847986,-51.83239798671377,-49.219123674121,-52.50854912329559,-54.124934397962825,-51.83239798671377],[-55.271339429687025,-47.24177590087174,-49.872062847940946,-45.9590319355197,-45.21996919608716,-47.24177590087174],[-55.271339429687025,8.327033560953591,7.13109329434183,11.787388613642522,7.881525699393345,8.327033560953591],[-55.271339429687025,-55.22116784736262,-57.72325453455482,-55.21233635471055,-52.72327045198066,-55.22116784736262],[23.61536009836396,15.284577332610965,16.013856452807698,11.787388613642522,16.214218695777433,15.284577332610965],[23.61536009836396,25.031541578605694,26.823898202874368,26.715285999279068,22.44048681915961,25.031541578605694],[23.61536009836396,29.5188528933436,27.70000807452646,32.683183570053394,29.83667120270865,29.5188528933436],[42.19984341219332,15.187729430612523,16.586552325452033,11.787388613642522,15.401886413322021,15.187729430612523],[42.19984341219332,-6.954255511026069,-8.815732640354412,-8.525126722326002,-4.347622589842236,-6.954255511026069],[42.19984341219332,29.35002457303889,31.62060308688656,26.715285999279068,28.32925616083382,29.35002457303889],[0.43586774850067966,8.376159789391622,7.007606127960047,11.787388613642522,8.126568756687847,8.376159789391622],[0.43586774850067966,-1.5755167191894608,-2.4977372032720275,-4.300833886609078,0.639480573925975,-1.5755167191894608],[0.43586774850067966,-1.4741447403604293,1.151984581509454,-2.313594333804382,-3.702074183063983,-1.4741447403604293],[-3.966959928251052,-4.2488226590923315,-6.736210627679378,-4.300833886609078,-1.736762733220166,-4.2488226590923315]],\"ys\":[[-15.558458215328628,-13.626177453714071,-16.007030539149724,-11.20789834476445,-12.392455126926512,-13.626177453714071],[3.7685359113877706,1.1877438612555427,3.118176092385359,-1.8806441073447902,0.7128269199948232,1.1877438612555427],[-3.5653263992787734,-1.9445587950610166,-4.412071762865475,0.25149364897758475,-0.5187615236945943,-1.9445587950610166],[11.380494646649044,3.6493347841789916,3.8556249981007227,0.25149364897758475,5.054838703020655,3.6493347841789916],[11.380494646649044,15.481291259247612,15.207426376345506,18.899627351587057,14.133640056430927,15.481291259247612],[-6.166674940089049,-3.3763082970723244,-1.4708124580302402,-1.8806441073447902,-5.991284853329948,-3.3763082970723244],[-6.166674940089049,-8.531983086707811,-10.575761090710838,-9.771910061089928,-5.900035435319047,-8.531983086707811],[-2.3550009009958655,-2.020897677423604,-4.552154841836126,-1.8806441073447902,0.4438290424045066,-2.020897677423604],[-2.3550009009958655,-0.5317801911318755,1.719035603935966,0.25149364897758475,-3.154148430708177,-0.5317801911318755],[-1.8215466806880158,-7.773830838075171,-7.442306729317741,-11.20789834476445,-6.476376534200863,-7.773830838075171],[-1.8215466806880158,4.460197144187391,4.350492058997446,7.82491684134761,2.973819525541681,4.460197144187391],[-15.81597286347034,-13.657841466343946,-12.453519960125083,-11.20789834476445,-16.02431381830322,-13.657841466343946],[-11.20789834476445,-13.366029741890845,-14.570351248109706,-15.81597286347034,-10.99955738993157,-13.366029741890845],[-11.20789834476445,-13.140179106379007,-10.759326020943352,-15.558458215328628,-14.373901433166566,-13.140179106379007],[-11.20789834476445,-5.255614187377295,-5.587138296134725,-1.8215466806880158,-6.553068491251603,-5.255614187377295],[7.82491684134761,-12.559507307172694,-12.703387269717815,-15.81597286347034,-10.870895890643478,-12.559507307172694],[7.82491684134761,-1.8296982174598049,-4.176789554890292,-2.3550009009958655,0.7665748060938933,-1.8296982174598049],[7.82491684134761,-12.058469357526715,-11.234653190338769,-15.558458215328628,-11.222036772264378,-12.058469357526715],[-1.8806441073447902,-2.2147473309170524,0.31650983349547035,-2.3550009009958655,-4.6794740507451635,-2.2147473309170524],[-1.8806441073447902,0.7001479427874377,-1.2302842883423786,3.7685359113877706,1.1750648840481572,0.7001479427874377],[-1.8806441073447902,-4.671010750361515,-6.576506589403598,-6.166674940089049,-2.0560341941038907,-4.671010750361515],[-9.771910061089928,-3.1842670394868726,-0.9521368066336322,-2.3550009009958655,-5.809766545162205,-3.1842670394868726],[-9.771910061089928,-107.63998816322314,-105.7761175227193,-110.76766519858165,-108.02021925314777,-107.63998816322314],[-9.771910061089928,1.4645930631508484,2.800101984872428,3.7685359113877706,-0.9638102633558878,1.4645930631508484],[0.25149364897758475,-1.571727060886405,-3.8225428559542456,-2.3550009009958655,1.0506411786898964,-1.571727060886405],[0.25149364897758475,-1.3692739552401716,1.098239012564286,-3.5653263992787734,-2.7950712266065945,-1.3692739552401716],[0.25149364897758475,7.982653511447637,7.776363297525905,11.380494646649044,6.5771495926059735,7.982653511447637],[18.899627351587057,-0.06571287315732421,0.8014733590172041,-3.5653263992787734,0.7271716054218524,-0.06571287315732421]]},\"selected\":{\"id\":\"1166\",\"type\":\"Selection\"},\"selection_policy\":{\"id\":\"1167\",\"type\":\"UnionRenderers\"}},\"id\":\"1047\",\"type\":\"ColumnDataSource\"},{\"attributes\":{\"callback\":null,\"data\":{\"end\":[],\"start\":[]},\"selected\":{\"id\":\"1170\",\"type\":\"Selection\"},\"selection_policy\":{\"id\":\"1171\",\"type\":\"UnionRenderers\"}},\"id\":\"1015\",\"type\":\"ColumnDataSource\"},{\"attributes\":{\"callback\":null,\"data\":{\"color\":[\"blue\",\"blue\",\"blue\",\"blue\",\"blue\",\"blue\"],\"index\":[10,11,12,13,14,15],\"k\":[100.0,3.0,10.0,2.0,10.0,1.0],\"k_r\":[10.0,0,0.25,0,0.5,0],\"species\":[\"dna_G1 + protein_RNAP <--> complex_dna_G1_protein_RNAP massaction: k_f(dna_G1,protein_RNAP)=100.0*dna_G1*protein_RNAP k_r(complex_dna_G1_protein_RNAP)=10.0*complex_dna_G1_protein_RNAP\",\"complex_dna_G1_protein_RNAP --> dna_G1 + rna_G1 + protein_RNAP massaction: k_f(complex_dna_G1_protein_RNAP)=3.0*complex_dna_G1_protein_RNAP\",\"rna_G1 + protein_Ribo <--> complex_protein_Ribo_rna_G1 massaction: k_f(rna_G1,protein_Ribo)=10.0*rna_G1*protein_Ribo k_r(complex_protein_Ribo_rna_G1)=0.25*complex_protein_Ribo_rna_G1\",\"complex_protein_Ribo_rna_G1 --> rna_G1 + protein_GFP + protein_Ribo massaction: k_f(complex_protein_Ribo_rna_G1)=2.0*complex_protein_Ribo_rna_G1\",\"rna_G1 + protein_RNAase <--> complex_protein_RNAase_rna_G1 massaction: k_f(rna_G1,protein_RNAase)=10.0*rna_G1*protein_RNAase k_r(complex_protein_RNAase_rna_G1)=0.5*complex_protein_RNAase_rna_G1\",\"complex_protein_RNAase_rna_G1 --> protein_RNAase massaction: k_f(complex_protein_RNAase_rna_G1)=1.0*complex_protein_RNAase_rna_G1\"],\"type\":[\"massaction\",\"massaction\",\"massaction\",\"massaction\",\"massaction\",\"massaction\"]},\"selected\":{\"id\":\"1172\",\"type\":\"Selection\"},\"selection_policy\":{\"id\":\"1173\",\"type\":\"UnionRenderers\"}},\"id\":\"1011\",\"type\":\"ColumnDataSource\"},{\"attributes\":{\"source\":{\"id\":\"1031\",\"type\":\"ColumnDataSource\"}},\"id\":\"1033\",\"type\":\"CDSView\"},{\"attributes\":{},\"id\":\"1169\",\"type\":\"UnionRenderers\"},{\"attributes\":{\"callback\":null,\"end\":22.14130966534129,\"start\":-114.00934751233589},\"id\":\"1084\",\"type\":\"Range1d\"},{\"attributes\":{\"data_source\":{\"id\":\"1047\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"1060\",\"type\":\"MultiLine\"},\"hover_glyph\":{\"id\":\"1070\",\"type\":\"MultiLine\"},\"muted_glyph\":null,\"selection_glyph\":{\"id\":\"1065\",\"type\":\"MultiLine\"},\"view\":{\"id\":\"1049\",\"type\":\"CDSView\"}},\"id\":\"1048\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"callback\":null,\"renderers\":[{\"id\":\"1041\",\"type\":\"GraphRenderer\"}],\"tooltips\":null},\"id\":\"1115\",\"type\":\"HoverTool\"},{\"attributes\":{},\"id\":\"1166\",\"type\":\"Selection\"},{\"attributes\":{},\"id\":\"1159\",\"type\":\"NodesOnly\"},{\"attributes\":{\"callback\":null,\"overlay\":{\"id\":\"1165\",\"type\":\"BoxAnnotation\"}},\"id\":\"1119\",\"type\":\"BoxSelectTool\"},{\"attributes\":{\"edge_renderer\":{\"id\":\"1016\",\"type\":\"GlyphRenderer\"},\"inspection_policy\":{\"id\":\"1149\",\"type\":\"NodesOnly\"},\"layout_provider\":{\"id\":\"1022\",\"type\":\"StaticLayoutProvider\"},\"node_renderer\":{\"id\":\"1012\",\"type\":\"GlyphRenderer\"},\"selection_policy\":{\"id\":\"1150\",\"type\":\"NodesOnly\"}},\"id\":\"1009\",\"type\":\"GraphRenderer\"},{\"attributes\":{\"callback\":null},\"id\":\"1118\",\"type\":\"TapTool\"},{\"attributes\":{\"source\":{\"id\":\"1011\",\"type\":\"ColumnDataSource\"}},\"id\":\"1013\",\"type\":\"CDSView\"},{\"attributes\":{\"callback\":null,\"end\":61.53958058009174,\"start\":-74.61107659758544},\"id\":\"1083\",\"type\":\"Range1d\"},{\"attributes\":{\"source\":{\"id\":\"1047\",\"type\":\"ColumnDataSource\"}},\"id\":\"1049\",\"type\":\"CDSView\"},{\"attributes\":{\"fill_color\":{\"value\":\"#fdae61\"},\"size\":{\"units\":\"screen\",\"value\":8}},\"id\":\"1090\",\"type\":\"Square\"},{\"attributes\":{\"graph_layout\":{\"0\":[8.229090814157361,108.51396833498563],\"1\":[-55.21233635471055,-15.558458215328628],\"10\":[-50.66042227847986,-11.20789834476445],\"11\":[-55.271339429687025,7.82491684134761],\"12\":[23.61536009836396,-1.8806441073447902],\"13\":[42.19984341219332,-9.771910061089928],\"14\":[0.43586774850067966,0.25149364897758475],\"15\":[-3.966959928251052,18.899627351587057],\"2\":[26.715285999279068,3.7685359113877706],\"3\":[-4.300833886609078,-3.5653263992787734],\"4\":[-2.313594333804382,11.380494646649044],\"5\":[32.683183570053394,-6.166674940089049],\"6\":[11.787388613642522,-2.3550009009958655],\"7\":[-52.50854912329559,-1.8215466806880158],\"8\":[-8.525126722326002,-110.76766519858165],\"9\":[-45.9590319355197,-15.81597286347034]}},\"id\":\"1038\",\"type\":\"StaticLayoutProvider\"},{\"attributes\":{},\"id\":\"1173\",\"type\":\"UnionRenderers\"},{\"attributes\":{},\"id\":\"1120\",\"type\":\"PanTool\"},{\"attributes\":{},\"id\":\"1160\",\"type\":\"NodesOnly\"},{\"attributes\":{},\"id\":\"1121\",\"type\":\"WheelZoomTool\"},{\"attributes\":{\"fill_color\":{\"value\":\"#2b83ba\"},\"size\":{\"units\":\"screen\",\"value\":8}},\"id\":\"1085\",\"type\":\"Square\"},{\"attributes\":{},\"id\":\"1172\",\"type\":\"Selection\"},{\"attributes\":{},\"id\":\"1129\",\"type\":\"NodesAndLinkedEdges\"},{\"attributes\":{\"graph_layout\":{\"0\":[8.229090814157361,108.51396833498563],\"1\":[-55.21233635471055,-15.558458215328628],\"10\":[-50.66042227847986,-11.20789834476445],\"11\":[-55.271339429687025,7.82491684134761],\"12\":[23.61536009836396,-1.8806441073447902],\"13\":[42.19984341219332,-9.771910061089928],\"14\":[0.43586774850067966,0.25149364897758475],\"15\":[-3.966959928251052,18.899627351587057],\"2\":[26.715285999279068,3.7685359113877706],\"3\":[-4.300833886609078,-3.5653263992787734],\"4\":[-2.313594333804382,11.380494646649044],\"5\":[32.683183570053394,-6.166674940089049],\"6\":[11.787388613642522,-2.3550009009958655],\"7\":[-52.50854912329559,-1.8215466806880158],\"8\":[-8.525126722326002,-110.76766519858165],\"9\":[-45.9590319355197,-15.81597286347034]}},\"id\":\"1054\",\"type\":\"StaticLayoutProvider\"},{\"attributes\":{},\"id\":\"1171\",\"type\":\"UnionRenderers\"},{\"attributes\":{\"edge_renderer\":{\"id\":\"1032\",\"type\":\"GlyphRenderer\"},\"inspection_policy\":{\"id\":\"1159\",\"type\":\"NodesOnly\"},\"layout_provider\":{\"id\":\"1038\",\"type\":\"StaticLayoutProvider\"},\"node_renderer\":{\"id\":\"1028\",\"type\":\"GlyphRenderer\"},\"selection_policy\":{\"id\":\"1160\",\"type\":\"NodesOnly\"}},\"id\":\"1025\",\"type\":\"GraphRenderer\"},{\"attributes\":{\"active_drag\":\"auto\",\"active_inspect\":\"auto\",\"active_multi\":null,\"active_scroll\":\"auto\",\"active_tap\":\"auto\",\"tools\":[{\"id\":\"1115\",\"type\":\"HoverTool\"},{\"id\":\"1116\",\"type\":\"HoverTool\"},{\"id\":\"1117\",\"type\":\"HoverTool\"},{\"id\":\"1118\",\"type\":\"TapTool\"},{\"id\":\"1119\",\"type\":\"BoxSelectTool\"},{\"id\":\"1120\",\"type\":\"PanTool\"},{\"id\":\"1121\",\"type\":\"WheelZoomTool\"}]},\"id\":\"1122\",\"type\":\"Toolbar\"},{\"attributes\":{\"source\":{\"id\":\"1027\",\"type\":\"ColumnDataSource\"}},\"id\":\"1029\",\"type\":\"CDSView\"},{\"attributes\":{},\"id\":\"1170\",\"type\":\"Selection\"},{\"attributes\":{\"line_color\":{\"value\":\"#fdae61\"},\"line_width\":{\"value\":5}},\"id\":\"1065\",\"type\":\"MultiLine\"},{\"attributes\":{},\"id\":\"1167\",\"type\":\"UnionRenderers\"},{\"attributes\":{},\"id\":\"1175\",\"type\":\"UnionRenderers\"},{\"attributes\":{\"fill_color\":{\"value\":\"#fdae61\"},\"size\":{\"units\":\"screen\",\"value\":15}},\"id\":\"1105\",\"type\":\"Circle\"},{\"attributes\":{},\"id\":\"1014\",\"type\":\"MultiLine\"},{\"attributes\":{\"bottom_units\":\"screen\",\"fill_alpha\":{\"value\":0.5},\"fill_color\":{\"value\":\"lightgrey\"},\"left_units\":\"screen\",\"level\":\"overlay\",\"line_alpha\":{\"value\":1.0},\"line_color\":{\"value\":\"black\"},\"line_dash\":[4,4],\"line_width\":{\"value\":2},\"render_mode\":\"css\",\"right_units\":\"screen\",\"top_units\":\"screen\"},\"id\":\"1165\",\"type\":\"BoxAnnotation\"},{\"attributes\":{},\"id\":\"1168\",\"type\":\"Selection\"},{\"attributes\":{},\"id\":\"1176\",\"type\":\"Selection\"},{\"attributes\":{\"edge_renderer\":{\"id\":\"1048\",\"type\":\"GlyphRenderer\"},\"inspection_policy\":{\"id\":\"1131\",\"type\":\"EdgesAndLinkedNodes\"},\"layout_provider\":{\"id\":\"1054\",\"type\":\"StaticLayoutProvider\"},\"node_renderer\":{\"id\":\"1044\",\"type\":\"GlyphRenderer\"},\"selection_policy\":{\"id\":\"1129\",\"type\":\"NodesAndLinkedEdges\"}},\"id\":\"1041\",\"type\":\"GraphRenderer\"},{\"attributes\":{\"callback\":null,\"data\":{\"color\":[\"purple\",\"green\",\"green\",\"green\",\"cyan\",\"cyan\",\"orange\",\"cyan\",\"green\",\"grey\"],\"index\":[0,1,2,3,4,5,6,7,8,9],\"species\":[\"nothing\",\"protein_RNAP\",\"protein_Ribo\",\"protein_RNAase\",\"complex_protein_RNAase_rna_G1\",\"complex_protein_Ribo_rna_G1\",\"rna_G1\",\"complex_dna_G1_protein_RNAP\",\"protein_GFP\",\"dna_G1\"],\"type\":[\"nothing\",\"protein\",\"protein\",\"protein\",\"complex\",\"complex\",\"rna\",\"complex\",\"protein\",\"dna\"]},\"selected\":{\"id\":\"1176\",\"type\":\"Selection\"},\"selection_policy\":{\"id\":\"1177\",\"type\":\"UnionRenderers\"}},\"id\":\"1027\",\"type\":\"ColumnDataSource\"},{\"attributes\":{\"callback\":null,\"data\":{\"color\":[\"purple\",\"green\",\"green\",\"green\",\"cyan\",\"cyan\",\"orange\",\"cyan\",\"green\",\"grey\",\"blue\",\"blue\",\"blue\",\"blue\",\"blue\",\"blue\"],\"index\":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15],\"k\":[null,null,null,null,null,null,null,null,null,null,100.0,3.0,10.0,2.0,10.0,1.0],\"k_r\":[null,null,null,null,null,null,null,null,null,null,10.0,0,0.25,0,0.5,0],\"species\":[\"nothing\",\"protein_RNAP\",\"protein_Ribo\",\"protein_RNAase\",\"complex_protein_RNAase_rna_G1\",\"complex_protein_Ribo_rna_G1\",\"rna_G1\",\"complex_dna_G1_protein_RNAP\",\"protein_GFP\",\"dna_G1\",\"dna_G1 + protein_RNAP <--> complex_dna_G1_protein_RNAP massaction: k_f(dna_G1,protein_RNAP)=100.0*dna_G1*protein_RNAP k_r(complex_dna_G1_protein_RNAP)=10.0*complex_dna_G1_protein_RNAP\",\"complex_dna_G1_protein_RNAP --> dna_G1 + rna_G1 + protein_RNAP massaction: k_f(complex_dna_G1_protein_RNAP)=3.0*complex_dna_G1_protein_RNAP\",\"rna_G1 + protein_Ribo <--> complex_protein_Ribo_rna_G1 massaction: k_f(rna_G1,protein_Ribo)=10.0*rna_G1*protein_Ribo k_r(complex_protein_Ribo_rna_G1)=0.25*complex_protein_Ribo_rna_G1\",\"complex_protein_Ribo_rna_G1 --> rna_G1 + protein_GFP + protein_Ribo massaction: k_f(complex_protein_Ribo_rna_G1)=2.0*complex_protein_Ribo_rna_G1\",\"rna_G1 + protein_RNAase <--> complex_protein_RNAase_rna_G1 massaction: k_f(rna_G1,protein_RNAase)=10.0*rna_G1*protein_RNAase k_r(complex_protein_RNAase_rna_G1)=0.5*complex_protein_RNAase_rna_G1\",\"complex_protein_RNAase_rna_G1 --> protein_RNAase massaction: k_f(complex_protein_RNAase_rna_G1)=1.0*complex_protein_RNAase_rna_G1\"],\"type\":[\"nothing\",\"protein\",\"protein\",\"protein\",\"complex\",\"complex\",\"rna\",\"complex\",\"protein\",\"dna\",\"massaction\",\"massaction\",\"massaction\",\"massaction\",\"massaction\",\"massaction\"]},\"selected\":{\"id\":\"1168\",\"type\":\"Selection\"},\"selection_policy\":{\"id\":\"1169\",\"type\":\"UnionRenderers\"}},\"id\":\"1043\",\"type\":\"ColumnDataSource\"},{\"attributes\":{},\"id\":\"1177\",\"type\":\"UnionRenderers\"},{\"attributes\":{},\"id\":\"1150\",\"type\":\"NodesOnly\"},{\"attributes\":{\"data_source\":{\"id\":\"1027\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"1100\",\"type\":\"Circle\"},\"hover_glyph\":{\"id\":\"1110\",\"type\":\"Circle\"},\"muted_glyph\":null,\"selection_glyph\":{\"id\":\"1105\",\"type\":\"Circle\"},\"view\":{\"id\":\"1029\",\"type\":\"CDSView\"}},\"id\":\"1028\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"attachment\":\"right\",\"callback\":null,\"renderers\":[{\"id\":\"1009\",\"type\":\"GraphRenderer\"}],\"tooltips\":[[\"reaction\",\"@species\"],[\"type\",\"@type\"],[\"k_f\",\"@k\"],[\"k_r\",\"@k_r\"]]},\"id\":\"1117\",\"type\":\"HoverTool\"},{\"attributes\":{\"line_alpha\":{\"value\":0.2},\"line_width\":{\"value\":4}},\"id\":\"1060\",\"type\":\"MultiLine\"},{\"attributes\":{\"line_color\":{\"value\":\"#abdda4\"},\"line_width\":{\"value\":5}},\"id\":\"1070\",\"type\":\"MultiLine\"},{\"attributes\":{\"fill_color\":{\"value\":\"#abdda4\"},\"size\":{\"units\":\"screen\",\"value\":15}},\"id\":\"1110\",\"type\":\"Circle\"},{\"attributes\":{\"graph_layout\":{\"0\":[8.229090814157361,108.51396833498563],\"1\":[-55.21233635471055,-15.558458215328628],\"10\":[-50.66042227847986,-11.20789834476445],\"11\":[-55.271339429687025,7.82491684134761],\"12\":[23.61536009836396,-1.8806441073447902],\"13\":[42.19984341219332,-9.771910061089928],\"14\":[0.43586774850067966,0.25149364897758475],\"15\":[-3.966959928251052,18.899627351587057],\"2\":[26.715285999279068,3.7685359113877706],\"3\":[-4.300833886609078,-3.5653263992787734],\"4\":[-2.313594333804382,11.380494646649044],\"5\":[32.683183570053394,-6.166674940089049],\"6\":[11.787388613642522,-2.3550009009958655],\"7\":[-52.50854912329559,-1.8215466806880158],\"8\":[-8.525126722326002,-110.76766519858165],\"9\":[-45.9590319355197,-15.81597286347034]}},\"id\":\"1022\",\"type\":\"StaticLayoutProvider\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"size\":{\"units\":\"screen\",\"value\":12}},\"id\":\"1100\",\"type\":\"Circle\"},{\"attributes\":{},\"id\":\"1149\",\"type\":\"NodesOnly\"},{\"attributes\":{},\"id\":\"1131\",\"type\":\"EdgesAndLinkedNodes\"},{\"attributes\":{},\"id\":\"1174\",\"type\":\"Selection\"}],\"root_ids\":[\"1004\"]},\"title\":\"Bokeh Application\",\"version\":\"1.3.4\"}};\n", - " var render_items = [{\"docid\":\"e4a6bf3b-e149-48c5-9380-ace86ca13b49\",\"roots\":{\"1004\":\"abb3769e-2398-40a8-a5ae-0604b852ee13\"}}];\n", - " root.Bokeh.embed.embed_items_notebook(docs_json, render_items);\n", - "\n", - " }\n", - " if (root.Bokeh !== undefined) {\n", - " embed_document(root);\n", - " } else {\n", - " var attempts = 0;\n", - " var timer = setInterval(function(root) {\n", - " if (root.Bokeh !== undefined) {\n", - " embed_document(root);\n", - " clearInterval(timer);\n", - " }\n", - " attempts++;\n", - " if (attempts > 100) {\n", - " console.log(\"Bokeh: ERROR: Unable to run BokehJS code because BokehJS library is missing\");\n", - " clearInterval(timer);\n", - " }\n", - " }, 10, root)\n", - " }\n", - "})(window);" - ], - "application/vnd.bokehjs_exec.v0+json": "" - }, - "metadata": { - "application/vnd.bokehjs_exec.v0+json": { - "id": "1004" - } - }, - "output_type": "display_data" - } - ], + "execution_count": null, + "metadata": { + "tags": [] + }, + "outputs": [], "source": [ - "from bokeh.models import (Plot , Range1d)\n", - "import bokeh.plotting\n", - "import bokeh.io\n", - "bokeh.io.output_notebook() #this makes the graph appear in line with the notebook\n", - "DG, DGspec, DGrxn = generate_networkx_graph(crn1) #this creates the networkx objects\n", - "plot = Plot(plot_width=500, plot_height=500, x_range=Range1d(-500, 500), y_range=Range1d(-500, 500)) #this generates a bokeh plot\n", - "graphPlot(DG,DGspec,DGrxn,plot,layout=\"force\",posscale=1) #now you draw the network on the plot. Layout \"force\" is the default. \n", - "#\"posscale\" scales the entire graph. This mostly just affects the size of the arrows relative to everything else\n", - "bokeh.io.show(plot) #if you don't type this the plot won't show\n", + "try:\n", + " from bokeh.models import (Plot , Range1d)\n", + " import bokeh.plotting\n", + " import bokeh.io\n", + " bokeh.io.output_notebook() #this makes the graph appear in line with the notebook\n", + " DG, DGspec, DGrxn = generate_networkx_graph(crn1) #this creates the networkx objects\n", + " plot = Plot(plot_width=500, plot_height=500, x_range=Range1d(-500, 500), y_range=Range1d(-500, 500)) #this generates a bokeh plot\n", + " graphPlot(DG,DGspec,DGrxn,plot,layout=\"force\",posscale=1) #now you draw the network on the plot. Layout \"force\" is the default.\n", + " #\"posscale\" scales the entire graph. This mostly just affects the size of the arrows relative to everything else\n", + " bokeh.io.show(plot) #if you don't type this the plot won't show\n", + "except ModuleNotFoundError:\n", + " print('please install the plotting libraries: pip install biocrnpyler[all]')\n", + "\n", "\n", "#mouse over nodes to get a tooltip telling you what they are\n", "#mouse over single lines to outline them\n", @@ -520,88 +144,40 @@ }, { "cell_type": "code", - "execution_count": 4, + "execution_count": null, "metadata": { - "tags": [ - "outputPrepend" - ] + "tags": [] }, - "outputs": [ - { - "data": { - "text/html": [ - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "
\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "application/javascript": [ - "(function(root) {\n", - " function embed_document(root) {\n", - " \n", - " var docs_json = {\"52f970b4-02ad-4de2-bddd-458f7a87fe5d\":{\"roots\":{\"references\":[{\"attributes\":{\"plot_height\":500,\"plot_width\":500,\"renderers\":[{\"id\":\"1531\",\"type\":\"GraphRenderer\"},{\"id\":\"1499\",\"type\":\"GraphRenderer\"},{\"id\":\"1515\",\"type\":\"GraphRenderer\"}],\"title\":{\"id\":\"1668\",\"type\":\"Title\"},\"toolbar\":{\"id\":\"1612\",\"type\":\"Toolbar\"},\"x_range\":{\"id\":\"1573\",\"type\":\"Range1d\"},\"x_scale\":{\"id\":\"1669\",\"type\":\"LinearScale\"},\"y_range\":{\"id\":\"1574\",\"type\":\"Range1d\"},\"y_scale\":{\"id\":\"1671\",\"type\":\"LinearScale\"}},\"id\":\"1494\",\"type\":\"Plot\"},{\"attributes\":{\"data_source\":{\"id\":\"1501\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"1575\",\"type\":\"Square\"},\"hover_glyph\":{\"id\":\"1585\",\"type\":\"Square\"},\"muted_glyph\":null,\"selection_glyph\":{\"id\":\"1580\",\"type\":\"Square\"},\"view\":{\"id\":\"1503\",\"type\":\"CDSView\"}},\"id\":\"1502\",\"type\":\"GlyphRenderer\"},{\"attributes\":{},\"id\":\"1694\",\"type\":\"NodesOnly\"},{\"attributes\":{\"fill_color\":{\"value\":\"#abdda4\"},\"size\":{\"units\":\"screen\",\"value\":15}},\"id\":\"1600\",\"type\":\"Circle\"},{\"attributes\":{},\"id\":\"1709\",\"type\":\"Selection\"},{\"attributes\":{},\"id\":\"1702\",\"type\":\"UnionRenderers\"},{\"attributes\":{\"attachment\":\"right\",\"callback\":null,\"renderers\":[{\"id\":\"1515\",\"type\":\"GraphRenderer\"}],\"tooltips\":[[\"name\",\"@species\"],[\"type\",\"@type\"]]},\"id\":\"1606\",\"type\":\"HoverTool\"},{\"attributes\":{},\"id\":\"1712\",\"type\":\"UnionRenderers\"},{\"attributes\":{},\"id\":\"1671\",\"type\":\"LinearScale\"},{\"attributes\":{\"callback\":null,\"data\":{\"color\":[\"blue\",\"blue\",\"blue\",\"blue\",\"blue\",\"blue\"],\"index\":[10,11,12,13,14,15],\"k\":[100.0,3.0,10.0,2.0,10.0,1.0],\"k_r\":[10.0,0,0.25,0,0.5,0],\"species\":[\"dna[G1] + protein[RNAP] <--> complexdna[G1]:protein[RNAP]] \",\"complexdna[G1]:protein[RNAP]] --> dna[G1] + rna[G1] + protein[RNAP] \",\"rna[G1] + protein[Ribo] <--> complexprotein[Ribo]:rna[G1]] \",\"complexprotein[Ribo]:rna[G1]] --> rna[G1] + protein[GFP] + protein[Ribo] \",\"rna[G1] + protein[RNAase] <--> complexprotein[RNAase]:rna[G1]] \",\"complexprotein[RNAase]:rna[G1]] --> protein[RNAase] \"],\"type\":[\"massaction\",\"massaction\",\"massaction\",\"massaction\",\"massaction\",\"massaction\"]},\"selected\":{\"id\":\"1707\",\"type\":\"Selection\"},\"selection_policy\":{\"id\":\"1708\",\"type\":\"UnionRenderers\"}},\"id\":\"1501\",\"type\":\"ColumnDataSource\"},{\"attributes\":{\"bottom_units\":\"screen\",\"fill_alpha\":{\"value\":0.5},\"fill_color\":{\"value\":\"lightgrey\"},\"left_units\":\"screen\",\"level\":\"overlay\",\"line_alpha\":{\"value\":1.0},\"line_color\":{\"value\":\"black\"},\"line_dash\":[4,4],\"line_width\":{\"value\":2},\"render_mode\":\"css\",\"right_units\":\"screen\",\"top_units\":\"screen\"},\"id\":\"1700\",\"type\":\"BoxAnnotation\"},{\"attributes\":{},\"id\":\"1711\",\"type\":\"Selection\"},{\"attributes\":{\"callback\":null,\"data\":{\"color\":[null,\"blue\",\"blue\",\"blue\",\"grey\",\"grey\",\"red\",\"grey\",\"green\",\"red\",\"blue\",\"blue\",\"blue\",\"blue\",\"blue\",\"blue\"],\"index\":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15],\"k\":[null,null,null,null,null,null,null,null,null,null,100.0,3.0,10.0,2.0,10.0,1.0],\"k_r\":[null,null,null,null,null,null,null,null,null,null,10.0,0,0.25,0,0.5,0],\"species\":[\"nothing\",\"protein[RNAP]\",\"protein[Ribo]\",\"protein[RNAase]\",\"complexprotein[RNAase]:rna[G1]]\",\"complexprotein[Ribo]:rna[G1]]\",\"rna[G1]\",\"complexdna[G1]:protein[RNAP]]\",\"protein[GFP]\",\"dna[G1]\",\"dna[G1] + protein[RNAP] <--> complexdna[G1]:protein[RNAP]] \",\"complexdna[G1]:protein[RNAP]] --> dna[G1] + rna[G1] + protein[RNAP] \",\"rna[G1] + protein[Ribo] <--> complexprotein[Ribo]:rna[G1]] \",\"complexprotein[Ribo]:rna[G1]] --> rna[G1] + protein[GFP] + protein[Ribo] \",\"rna[G1] + protein[RNAase] <--> complexprotein[RNAase]:rna[G1]] \",\"complexprotein[RNAase]:rna[G1]] --> protein[RNAase] \"],\"type\":[\"nothing\",\"protein\",\"protein\",\"protein\",\"complex\",\"complex\",\"rna\",\"complex\",\"protein\",\"dna\",\"massaction\",\"massaction\",\"massaction\",\"massaction\",\"massaction\",\"massaction\"]},\"selected\":{\"id\":\"1703\",\"type\":\"Selection\"},\"selection_policy\":{\"id\":\"1704\",\"type\":\"UnionRenderers\"}},\"id\":\"1533\",\"type\":\"ColumnDataSource\"},{\"attributes\":{},\"id\":\"1684\",\"type\":\"NodesOnly\"},{\"attributes\":{\"line_alpha\":{\"value\":0.2},\"line_width\":{\"value\":4}},\"id\":\"1550\",\"type\":\"MultiLine\"},{\"attributes\":{\"graph_layout\":{\"0\":[50.0,1.3311835425965304e-06],\"1\":[40.45085021450356,29.38926326782492],\"10\":[35.0,8.576599450882586e-07],\"11\":[17.499999217689048,30.31089108058355],\"12\":[-17.500001303851583,30.310888994421013],\"13\":[-34.99999895691873,-2.2021371893888662e-06],\"14\":[-17.499996088445243,-30.310889365263655],\"15\":[17.499997131526513,-30.310889365263655],\"2\":[15.450848947904866,47.55282790664612],\"3\":[-15.450851034067412,47.55282492641391],\"4\":[-40.45085230066611,29.38926028759271],\"5\":[-49.999999105930335,-3.0399552469962367e-06],\"6\":[-40.45084634020168,-29.389266565922263],\"7\":[-15.450854014299624,-47.55282226404683],\"8\":[15.450856398485397,-47.55282226404683],\"9\":[40.45084723427134,-29.389263585690053]}},\"id\":\"1512\",\"type\":\"StaticLayoutProvider\"},{\"attributes\":{},\"id\":\"1701\",\"type\":\"Selection\"},{\"attributes\":{\"callback\":null,\"end\":45.15589189390042,\"start\":-54.705040785327185},\"id\":\"1573\",\"type\":\"Range1d\"},{\"attributes\":{\"active_drag\":\"auto\",\"active_inspect\":\"auto\",\"active_multi\":null,\"active_scroll\":\"auto\",\"active_tap\":\"auto\",\"tools\":[{\"id\":\"1605\",\"type\":\"HoverTool\"},{\"id\":\"1606\",\"type\":\"HoverTool\"},{\"id\":\"1607\",\"type\":\"HoverTool\"},{\"id\":\"1608\",\"type\":\"TapTool\"},{\"id\":\"1609\",\"type\":\"BoxSelectTool\"},{\"id\":\"1610\",\"type\":\"PanTool\"},{\"id\":\"1611\",\"type\":\"WheelZoomTool\"}]},\"id\":\"1612\",\"type\":\"Toolbar\"},{\"attributes\":{},\"id\":\"1695\",\"type\":\"NodesOnly\"},{\"attributes\":{},\"id\":\"1705\",\"type\":\"Selection\"},{\"attributes\":{\"edge_renderer\":{\"id\":\"1522\",\"type\":\"GlyphRenderer\"},\"inspection_policy\":{\"id\":\"1694\",\"type\":\"NodesOnly\"},\"layout_provider\":{\"id\":\"1528\",\"type\":\"StaticLayoutProvider\"},\"node_renderer\":{\"id\":\"1518\",\"type\":\"GlyphRenderer\"},\"selection_policy\":{\"id\":\"1695\",\"type\":\"NodesOnly\"}},\"id\":\"1515\",\"type\":\"GraphRenderer\"},{\"attributes\":{},\"id\":\"1619\",\"type\":\"NodesAndLinkedEdges\"},{\"attributes\":{\"fill_color\":{\"value\":\"#2b83ba\"},\"size\":{\"units\":\"screen\",\"value\":8}},\"id\":\"1575\",\"type\":\"Square\"},{\"attributes\":{},\"id\":\"1685\",\"type\":\"NodesOnly\"},{\"attributes\":{\"fill_color\":{\"value\":\"#fdae61\"},\"size\":{\"units\":\"screen\",\"value\":15}},\"id\":\"1595\",\"type\":\"Circle\"},{\"attributes\":{\"source\":{\"id\":\"1521\",\"type\":\"ColumnDataSource\"}},\"id\":\"1523\",\"type\":\"CDSView\"},{\"attributes\":{\"text\":\"\"},\"id\":\"1668\",\"type\":\"Title\"},{\"attributes\":{\"fill_color\":{\"value\":\"#fdae61\"},\"size\":{\"units\":\"screen\",\"value\":8}},\"id\":\"1580\",\"type\":\"Square\"},{\"attributes\":{\"callback\":null,\"overlay\":{\"id\":\"1700\",\"type\":\"BoxAnnotation\"}},\"id\":\"1609\",\"type\":\"BoxSelectTool\"},{\"attributes\":{\"line_color\":{\"value\":\"#fdae61\"},\"line_width\":{\"value\":5}},\"id\":\"1555\",\"type\":\"MultiLine\"},{\"attributes\":{},\"id\":\"1704\",\"type\":\"UnionRenderers\"},{\"attributes\":{\"edge_renderer\":{\"id\":\"1506\",\"type\":\"GlyphRenderer\"},\"inspection_policy\":{\"id\":\"1684\",\"type\":\"NodesOnly\"},\"layout_provider\":{\"id\":\"1512\",\"type\":\"StaticLayoutProvider\"},\"node_renderer\":{\"id\":\"1502\",\"type\":\"GlyphRenderer\"},\"selection_policy\":{\"id\":\"1685\",\"type\":\"NodesOnly\"}},\"id\":\"1499\",\"type\":\"GraphRenderer\"},{\"attributes\":{\"source\":{\"id\":\"1533\",\"type\":\"ColumnDataSource\"}},\"id\":\"1535\",\"type\":\"CDSView\"},{\"attributes\":{},\"id\":\"1610\",\"type\":\"PanTool\"},{\"attributes\":{},\"id\":\"1611\",\"type\":\"WheelZoomTool\"},{\"attributes\":{\"fill_color\":{\"value\":\"#abdda4\"},\"size\":{\"units\":\"screen\",\"value\":8}},\"id\":\"1585\",\"type\":\"Square\"},{\"attributes\":{},\"id\":\"1706\",\"type\":\"UnionRenderers\"},{\"attributes\":{\"graph_layout\":{\"0\":[50.0,1.3311835425965304e-06],\"1\":[40.45085021450356,29.38926326782492],\"10\":[35.0,8.576599450882586e-07],\"11\":[17.499999217689048,30.31089108058355],\"12\":[-17.500001303851583,30.310888994421013],\"13\":[-34.99999895691873,-2.2021371893888662e-06],\"14\":[-17.499996088445243,-30.310889365263655],\"15\":[17.499997131526513,-30.310889365263655],\"2\":[15.450848947904866,47.55282790664612],\"3\":[-15.450851034067412,47.55282492641391],\"4\":[-40.45085230066611,29.38926028759271],\"5\":[-49.999999105930335,-3.0399552469962367e-06],\"6\":[-40.45084634020168,-29.389266565922263],\"7\":[-15.450854014299624,-47.55282226404683],\"8\":[15.450856398485397,-47.55282226404683],\"9\":[40.45084723427134,-29.389263585690053]}},\"id\":\"1528\",\"type\":\"StaticLayoutProvider\"},{\"attributes\":{\"line_color\":{\"value\":\"#abdda4\"},\"line_width\":{\"value\":5}},\"id\":\"1560\",\"type\":\"MultiLine\"},{\"attributes\":{},\"id\":\"1707\",\"type\":\"Selection\"},{\"attributes\":{\"data_source\":{\"id\":\"1521\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"1520\",\"type\":\"MultiLine\"},\"hover_glyph\":null,\"muted_glyph\":null,\"view\":{\"id\":\"1523\",\"type\":\"CDSView\"}},\"id\":\"1522\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"callback\":null,\"data\":{\"end\":[10,12,14,14,15,12,13,12,14,10,11,10,9,1,7,9,6,1,6,2,5,6,8,2,6,3,4,3],\"start\":[1,2,3,4,4,5,5,6,6,7,7,9,10,10,10,11,11,11,12,12,12,13,13,13,14,14,14,15],\"weight\":[1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1],\"xs\":[[40.45085021450356,35.638262709626865,33.3315661008632,35.0,38.24772453006582,35.638262709626865],[15.450848947904866,-14.398893742284695,-14.82244197092275,-17.500001303851583,-12.504309413394871,-14.398893742284695],[-15.450851034067412,-17.407918213398133,-19.885213975444625,-17.499996088445243,-14.886944547396471,-17.407918213398133],[-40.45085230066611,-18.755910882638634,-21.387292321206246,-17.499996088445243,-16.720283046427618,-18.755910882638634],[-40.45085230066611,15.062190643668721,12.690140962124127,17.499997131526513,16.277846592370704,15.062190643668721],[-49.999999105930335,-20.059576083939206,-18.96153296975844,-17.500001303851583,-22.371774730635728,-20.059576083939206],[-49.999999105930335,-38.49999895691872,-39.33012583620457,-34.99999895691873,-39.330126115477256,-38.49999895691872],[-40.45084634020168,-18.755915456951467,-16.72028729264428,-17.500001303851583,-21.387296919507225,-18.755915456951467],[-40.45084634020168,-20.99717756233948,-21.926946162684693,-17.499996088445243,-21.726326008596402,-20.99717756233948],[-15.450854014299624,32.453055988956365,33.56371739946794,35.0,30.13423055601657,32.453055988956365],[-15.450854014299624,16.13596035308902,18.11476656706825,17.499999217689048,13.510110986901532,16.13596035308902],[40.45084723427134,35.63826232957681,38.2477241102245,35.0,33.3315655803245,35.63826232957681],[35.0,39.81258490469453,37.20312312404684,40.45084723427134,42.11928165394684,39.81258490469453],[35.0,39.812587504876696,42.11928411364036,40.45085021450356,37.203125684437744,39.812587504876696],[35.0,-12.903910003255989,-14.014571413767563,-15.450854014299624,-10.585084570316194,-12.903910003255989],[17.499999217689048,39.19493292269952,36.563551466073385,40.45084723427134,41.23056100590461,39.19493292269952],[17.499999217689048,-38.013040104315635,-39.2286962874862,-40.45084634020168,-35.64099030782735,-38.013040104315635],[17.499999217689048,36.95366877105388,36.02389963639525,40.45085021450356,36.22452087355198,36.95366877105388],[-17.500001303851583,-39.19493218710179,-41.23056035140898,-40.45084634020168,-36.56355072454603,-39.19493218710179],[-17.500001303851583,12.349741386337978,12.773289614976035,15.450848947904866,10.455157057448154,12.349741386337978],[-17.500001303851583,-47.44042432584271,-48.53846744002348,-49.999999105930335,-45.12822567914619,-47.44042432584271],[-34.99999895691873,-39.812583992086246,-42.1192807344856,-40.45084634020168,-37.20312220949756,-39.812583992086246],[-34.99999895691873,12.903912278490193,10.585086902274682,15.450856398485397,14.0145735805954,12.903912278490193],[-34.99999895691873,12.903905258021604,14.01456698808639,15.450848947904866,10.585079657873687,12.903905258021604],[-17.499996088445243,-36.95366486630744,-36.02389626596223,-40.45084634020168,-36.22451642005052,-36.95366486630744],[-17.499996088445243,-15.542928909114522,-13.06563314706803,-15.450851034067412,-18.063902575116185,-15.542928909114522],[-17.499996088445243,-39.19493750647271,-36.563556067905104,-40.45085230066611,-41.23056534268373,-39.19493750647271],[17.499997131526513,-14.086812361412525,-11.46096298273004,-15.450851034067412,-16.065618678937533,-14.086812361412525]],\"ys\":[[29.38926326782492,3.4413117581017776,4.713420881826172,8.576599450882586e-07,3.8016170109306553,3.4413117581017776],[47.55282790664612,31.933581784690528,34.53352750827058,30.310888994421013,30.103373848889316,31.933581784690528],[47.55282492641391,-26.812100765629946,-25.9164911548669,-30.310889365263655,-26.04803097636277,-26.812100765629946],[29.38926028759271,-27.043982872918615,-27.166222769460198,-30.310889365263655,-25.37205877775535,-27.043982872918615],[29.38926028759271,-27.799495424091052,-28.945135496639512,-30.310889365263655,-25.46255479969981,-27.799495424091052],[-3.0399552469962367e-06,27.923719761806915,25.52926529639212,30.310888994421013,29.185800696517294,27.923719761806915],[-3.0399552469962367e-06,-2.3976280677475193e-06,-2.5000024439944233,-2.2021371893888662e-06,2.4999975560055674,-2.3976280677475193e-06],[-29.389266565922263,27.04398225561695,25.372058559922678,30.310888994421013,27.166221635779657,27.04398225561695],[-29.389266565922263,-30.17045525740185,-32.63513398237936,-30.310889365263655,-27.639160448244738,-30.17045525740185],[-47.55282226404683,-2.4006399327560137,-4.789267592887472,8.576599450882586e-07,-1.150776148539423,-2.4006399327560137],[-47.55282226404683,27.087632174466844,25.34882889776709,30.31089108058355,27.297455847195703,27.087632174466844],[-29.389263585690053,-3.4413101132700556,-3.8016156542815813,8.576599450882586e-07,-4.7134189822484505,-3.4413101132700556],[8.576599450882586e-07,-25.94795261476005,-25.587647073748528,-29.389263585690053,-24.675843745781656,-25.94795261476005],[8.576599450882586e-07,25.94795236738309,24.67584324365869,29.38926326782492,25.587647114554212,25.94795236738309],[8.576599450882586e-07,-45.152181473630876,-42.76355381349941,-47.55282226404683,-46.40204525784746,-45.152181473630876],[30.31089108058355,-26.122356907808197,-26.244596415614616,-29.389263585690053,-24.450433113369158,-26.122356907808197],[30.31089108058355,-26.87787238016107,-24.540931877738334,-29.389266565922263,-28.023512214718394,-26.87787238016107],[30.31089108058355,29.529698133834636,27.065019610420112,29.38926326782492,32.06099310106252,29.529698133834636],[30.310888994421013,-26.1223598271182,-24.450436131423928,-29.389266565922263,-26.244599207280906,-26.1223598271182],[30.310888994421013,45.930135116376604,43.330189392796555,47.55282790664612,47.76034305217782,45.930135116376604],[30.310888994421013,2.3871661926588534,4.781620658073649,-3.0399552469962367e-06,1.1250852579484727,2.3871661926588534],[-2.2021371893888662e-06,-25.94795559843063,-24.675846717025873,-29.389266565922263,-25.587650071476492,-25.94795559843063],[-2.2021371893888662e-06,-45.15218158922233,-46.40204547867735,-47.55282226404683,-42.7635538786842,-45.15218158922233],[-2.2021371893888662e-06,45.15218677549723,42.763559263951294,47.55282790664612,46.40205024949881,45.15218677549723],[-30.310889365263655,-29.529700673784067,-27.06502194880656,-29.389266565922263,-32.06099548294118,-29.529700673784067],[-30.310889365263655,44.054036326780206,43.15842671601716,47.55282492641391,43.289966537513024,44.054036326780206],[-30.310889365263655,26.12235379524767,26.24459369178925,29.38926028759271,24.450429700084406,26.12235379524767],[-30.310889365263655,44.329565939068665,44.539389455428136,47.55282492641391,42.590762780206866,44.329565939068665]]},\"selected\":{\"id\":\"1701\",\"type\":\"Selection\"},\"selection_policy\":{\"id\":\"1702\",\"type\":\"UnionRenderers\"}},\"id\":\"1537\",\"type\":\"ColumnDataSource\"},{\"attributes\":{\"attachment\":\"right\",\"callback\":null,\"renderers\":[{\"id\":\"1499\",\"type\":\"GraphRenderer\"}],\"tooltips\":[[\"reaction\",\"@species\"],[\"type\",\"@type\"],[\"k_f\",\"@k\"],[\"k_r\",\"@k_r\"]]},\"id\":\"1607\",\"type\":\"HoverTool\"},{\"attributes\":{\"source\":{\"id\":\"1505\",\"type\":\"ColumnDataSource\"}},\"id\":\"1507\",\"type\":\"CDSView\"},{\"attributes\":{\"callback\":null,\"data\":{\"end\":[],\"start\":[]},\"selected\":{\"id\":\"1709\",\"type\":\"Selection\"},\"selection_policy\":{\"id\":\"1710\",\"type\":\"UnionRenderers\"}},\"id\":\"1521\",\"type\":\"ColumnDataSource\"},{\"attributes\":{\"callback\":null,\"data\":{\"color\":[null,\"blue\",\"blue\",\"blue\",\"grey\",\"grey\",\"red\",\"grey\",\"green\",\"red\"],\"index\":[0,1,2,3,4,5,6,7,8,9],\"species\":[\"nothing\",\"protein[RNAP]\",\"protein[Ribo]\",\"protein[RNAase]\",\"complexprotein[RNAase]:rna[G1]]\",\"complexprotein[Ribo]:rna[G1]]\",\"rna[G1]\",\"complexdna[G1]:protein[RNAP]]\",\"protein[GFP]\",\"dna[G1]\"],\"type\":[\"nothing\",\"protein\",\"protein\",\"protein\",\"complex\",\"complex\",\"rna\",\"complex\",\"protein\",\"dna\"]},\"selected\":{\"id\":\"1711\",\"type\":\"Selection\"},\"selection_policy\":{\"id\":\"1712\",\"type\":\"UnionRenderers\"}},\"id\":\"1517\",\"type\":\"ColumnDataSource\"},{\"attributes\":{},\"id\":\"1710\",\"type\":\"UnionRenderers\"},{\"attributes\":{\"fill_alpha\":{\"value\":0},\"fill_color\":{\"field\":\"color\"},\"line_alpha\":{\"value\":0},\"size\":{\"units\":\"screen\",\"value\":12}},\"id\":\"1545\",\"type\":\"Circle\"},{\"attributes\":{},\"id\":\"1621\",\"type\":\"EdgesAndLinkedNodes\"},{\"attributes\":{\"data_source\":{\"id\":\"1505\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"1504\",\"type\":\"MultiLine\"},\"hover_glyph\":null,\"muted_glyph\":null,\"view\":{\"id\":\"1507\",\"type\":\"CDSView\"}},\"id\":\"1506\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"source\":{\"id\":\"1501\",\"type\":\"ColumnDataSource\"}},\"id\":\"1503\",\"type\":\"CDSView\"},{\"attributes\":{},\"id\":\"1520\",\"type\":\"MultiLine\"},{\"attributes\":{\"edge_renderer\":{\"id\":\"1538\",\"type\":\"GlyphRenderer\"},\"inspection_policy\":{\"id\":\"1621\",\"type\":\"EdgesAndLinkedNodes\"},\"layout_provider\":{\"id\":\"1544\",\"type\":\"StaticLayoutProvider\"},\"node_renderer\":{\"id\":\"1534\",\"type\":\"GlyphRenderer\"},\"selection_policy\":{\"id\":\"1619\",\"type\":\"NodesAndLinkedEdges\"}},\"id\":\"1531\",\"type\":\"GraphRenderer\"},{\"attributes\":{\"data_source\":{\"id\":\"1517\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"1590\",\"type\":\"Circle\"},\"hover_glyph\":{\"id\":\"1600\",\"type\":\"Circle\"},\"muted_glyph\":null,\"selection_glyph\":{\"id\":\"1595\",\"type\":\"Circle\"},\"view\":{\"id\":\"1519\",\"type\":\"CDSView\"}},\"id\":\"1518\",\"type\":\"GlyphRenderer\"},{\"attributes\":{},\"id\":\"1703\",\"type\":\"Selection\"},{\"attributes\":{},\"id\":\"1708\",\"type\":\"UnionRenderers\"},{\"attributes\":{\"callback\":null,\"end\":49.93046916091345,\"start\":-49.930463518314156},\"id\":\"1574\",\"type\":\"Range1d\"},{\"attributes\":{\"data_source\":{\"id\":\"1537\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"1550\",\"type\":\"MultiLine\"},\"hover_glyph\":{\"id\":\"1560\",\"type\":\"MultiLine\"},\"muted_glyph\":null,\"selection_glyph\":{\"id\":\"1555\",\"type\":\"MultiLine\"},\"view\":{\"id\":\"1539\",\"type\":\"CDSView\"}},\"id\":\"1538\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"callback\":null,\"data\":{\"end\":[],\"start\":[]},\"selected\":{\"id\":\"1705\",\"type\":\"Selection\"},\"selection_policy\":{\"id\":\"1706\",\"type\":\"UnionRenderers\"}},\"id\":\"1505\",\"type\":\"ColumnDataSource\"},{\"attributes\":{\"callback\":null,\"renderers\":[{\"id\":\"1531\",\"type\":\"GraphRenderer\"}],\"tooltips\":null},\"id\":\"1605\",\"type\":\"HoverTool\"},{\"attributes\":{},\"id\":\"1504\",\"type\":\"MultiLine\"},{\"attributes\":{},\"id\":\"1669\",\"type\":\"LinearScale\"},{\"attributes\":{\"data_source\":{\"id\":\"1533\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"1545\",\"type\":\"Circle\"},\"hover_glyph\":null,\"muted_glyph\":null,\"view\":{\"id\":\"1535\",\"type\":\"CDSView\"}},\"id\":\"1534\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"size\":{\"units\":\"screen\",\"value\":12}},\"id\":\"1590\",\"type\":\"Circle\"},{\"attributes\":{\"source\":{\"id\":\"1517\",\"type\":\"ColumnDataSource\"}},\"id\":\"1519\",\"type\":\"CDSView\"},{\"attributes\":{\"callback\":null},\"id\":\"1608\",\"type\":\"TapTool\"},{\"attributes\":{\"source\":{\"id\":\"1537\",\"type\":\"ColumnDataSource\"}},\"id\":\"1539\",\"type\":\"CDSView\"},{\"attributes\":{\"graph_layout\":{\"0\":[50.0,1.3311835425965304e-06],\"1\":[40.45085021450356,29.38926326782492],\"10\":[35.0,8.576599450882586e-07],\"11\":[17.499999217689048,30.31089108058355],\"12\":[-17.500001303851583,30.310888994421013],\"13\":[-34.99999895691873,-2.2021371893888662e-06],\"14\":[-17.499996088445243,-30.310889365263655],\"15\":[17.499997131526513,-30.310889365263655],\"2\":[15.450848947904866,47.55282790664612],\"3\":[-15.450851034067412,47.55282492641391],\"4\":[-40.45085230066611,29.38926028759271],\"5\":[-49.999999105930335,-3.0399552469962367e-06],\"6\":[-40.45084634020168,-29.389266565922263],\"7\":[-15.450854014299624,-47.55282226404683],\"8\":[15.450856398485397,-47.55282226404683],\"9\":[40.45084723427134,-29.389263585690053]}},\"id\":\"1544\",\"type\":\"StaticLayoutProvider\"}],\"root_ids\":[\"1494\"]},\"title\":\"Bokeh Application\",\"version\":\"1.3.4\"}};\n", - " var render_items = [{\"docid\":\"52f970b4-02ad-4de2-bddd-458f7a87fe5d\",\"roots\":{\"1494\":\"2c0df5ef-cdd1-4744-95bb-c83d4dc0099f\"}}];\n", - " root.Bokeh.embed.embed_items_notebook(docs_json, render_items);\n", - "\n", - " }\n", - " if (root.Bokeh !== undefined) {\n", - " embed_document(root);\n", - " } else {\n", - " var attempts = 0;\n", - " var timer = setInterval(function(root) {\n", - " if (root.Bokeh !== undefined) {\n", - " embed_document(root);\n", - " clearInterval(timer);\n", - " }\n", - " attempts++;\n", - " if (attempts > 100) {\n", - " console.log(\"Bokeh: ERROR: Unable to run BokehJS code because BokehJS library is missing\");\n", - " clearInterval(timer);\n", - " }\n", - " }, 10, root)\n", - " }\n", - "})(window);" - ], - "application/vnd.bokehjs_exec.v0+json": "" - }, - "metadata": { - "application/vnd.bokehjs_exec.v0+json": { - "id": "1494" - } - }, - "output_type": "display_data" - } - ], + "outputs": [], "source": [ - "#this demonstrates the \"circle\" layout. reactions are in the middle with species on the outside.\n", - "#also, the pretty_print text display style\n", + "try:\n", + " from bokeh.models import (Plot , Range1d)\n", + " import bokeh.plotting\n", + " import bokeh.io\n", + " bokeh.io.output_notebook() #this makes the graph appear in line with the notebook\n", + "\n", + " #this demonstrates the \"circle\" layout. reactions are in the middle with species on the outside.\n", + " #also, the pretty_print text display style\n", "\n", - "colordict = {\n", - " \"G1\":\"red\", #will only effect the species dna_G1 and rna_G1\n", - " \"protein_GFP\": \"green\", #will only effect the species protein_GFP\n", - " \"protein\": \"blue\" #All protein species, protein_Ribo, protein_RNAase, and protein_RNAP will be blue\n", - " #All other species will be grey by default. This will include all complexes.\n", - "}\n", - "DG, DGspec, DGrxn = generate_networkx_graph(crn1,\n", - " colordict = colordict,\n", - " use_pretty_print=True, #uses pretty print\n", - " pp_show_rates=False, #this would put the reaction rates in the reaction name. It's already listed seperately in the tool tip\n", - " pp_show_attributes=False, \n", - " pp_show_material = True #this lists the material of the species being displayed\n", - ")\n", + " colordict = {\n", + " \"G1\":\"red\", #will only effect the species dna_G1 and rna_G1\n", + " \"protein_GFP\": \"green\", #will only effect the species protein_GFP\n", + " \"protein\": \"blue\" #All protein species, protein_Ribo, protein_RNAase, and protein_RNAP will be blue\n", + " #All other species will be grey by default. This will include all complexes.\n", + " }\n", + " DG, DGspec, DGrxn = generate_networkx_graph(crn1,\n", + " colordict = colordict,\n", + " use_pretty_print=True, #uses pretty print\n", + " pp_show_rates=False, #this would put the reaction rates in the reaction name. It's already listed seperately in the tool tip\n", + " pp_show_attributes=False,\n", + " pp_show_material = True #this lists the material of the species being displayed\n", + " )\n", "\n", - "plot = Plot(plot_width=500, plot_height=500, x_range=Range1d(-500, 500), y_range=Range1d(-500, 500)) \n", - "graphPlot(DG,DGspec,DGrxn,plot,layout=\"circle\",posscale=1) \n", - "bokeh.io.show(plot) " + " plot = Plot(plot_width=500, plot_height=500, x_range=Range1d(-500, 500), y_range=Range1d(-500, 500))\n", + " graphPlot(DG,DGspec,DGrxn,plot,layout=\"circle\",posscale=1)\n", + " bokeh.io.show(plot)\n", + "except ModuleNotFoundError:\n", + " print('please install the plotting libraries: pip install biocrnpyler[all]')\n" ] }, { @@ -628,9 +204,9 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.7.4" + "version": "3.7.6" } }, "nbformat": 4, "nbformat_minor": 2 -} +} \ No newline at end of file diff --git a/examples/8. Developer Overview.ipynb b/examples/8. Developer Overview.ipynb index d4c0221d..67315dc4 100644 --- a/examples/8. Developer Overview.ipynb +++ b/examples/8. Developer Overview.ipynb @@ -46,30 +46,33 @@ " ['protein', 'dna', 'protein', 'complex']\n", "\n", "rxns representation:\n", - " [dna_G + protein_P <--> complex_dna_G_protein_P massaction: k_f(dna_G,protein_P)=100*dna_G*protein_P k_r(complex_dna_G_protein_P)=0.01*complex_dna_G_protein_P, complex_dna_G_protein_P --> dna_G + protein_P + protein_X massaction: k_f(complex_dna_G_protein_P)=1.0*complex_dna_G_protein_P]\n", + " [dna[G]+protein[P] <--> complex[dna[G]:protein[P]], complex[dna[G]:protein[P]] --> dna[G]+protein[P]+protein[X]]\n", "\n", "CRN Representation:\n", " Species = protein_P, dna_G, protein_X, complex_dna_G_protein_P\n", "Reactions = [\n", - "\tdna_G + protein_P <--> complex_dna_G_protein_P massaction: k_f(dna_G,protein_P)=100*dna_G*protein_P k_r(complex_dna_G_protein_P)=0.01*complex_dna_G_protein_P\n", - "\tcomplex_dna_G_protein_P --> dna_G + protein_P + protein_X massaction: k_f(complex_dna_G_protein_P)=1.0*complex_dna_G_protein_P\n", + "\tdna[G]+protein[P] <--> complex[dna[G]:protein[P]]\n", + "\tcomplex[dna[G]:protein[P]] --> dna[G]+protein[P]+protein[X]\n", "]\n", "\n", "CRN2:\n", " Species = protein_P, dna_G, protein_X, complex_dna_G_protein_P\n", "Reactions = [\n", - "\tdna_G + protein_P --> hillpositive: k(protein_P)=10*protein_P^2/(K+protein_P^2)\n", + "\tdna[G]+protein[P] --> \n", "]\n" ] } ], "source": [ - "from biocrnpyler.chemical_reaction_network import Species, Reaction, ComplexSpecies, ChemicalReactionNetwork\n", + "from biocrnpyler.chemical_reaction_network import ChemicalReactionNetwork\n", + "from biocrnpyler.species import Species, Complex\n", + "from biocrnpyler.reaction import Reaction\n", + "from biocrnpyler.propensities import HillPositive\n", "#create the three species in the CRN\n", "G = Species(name = \"G\", material_type = \"dna\")\n", "P = Species(name = \"P\", material_type = \"protein\")\n", "X = Species(name = \"X\", material_type = \"protein\")\n", - "PG = ComplexSpecies([P, G]) #complex takes a list of species and returns a complex\n", + "PG = Complex([P, G]) #complex takes a list of species and returns a complex\n", "species = [P, G, X, PG] #a list of species\n", "\n", "#Create the reversible reaction: + P <--> G:P\n", @@ -77,12 +80,12 @@ "kr = .01\n", "inputs1 = [G, P]\n", "outputs1 = [PG]\n", - "rxn1 = Reaction(inputs1, outputs1, k = kf, k_rev = kr) #type defaults to massaction\n", + "rxn1 = Reaction.from_massaction(inputs1, outputs1, k_forward = kf, k_reverse = kr) #type defaults to massaction\n", "#Create the irreversible reaction G:P --> G + P + X\n", "inputs2 = [PG]\n", "outputs2 = [G, P, X]\n", "kexpress = 1.\n", - "rxn2 = Reaction(inputs2, outputs2, k = kexpress)\n", + "rxn2 = Reaction.from_massaction(inputs2, outputs2, k_forward = kexpress)\n", "\n", "\n", "\n", @@ -99,8 +102,9 @@ "inputs3 = [G, P]\n", "outputs3 = []\n", "khill = 10\n", - "params_hill = {\"K\":\"K\", \"n\":2, \"s1\":P} #parmeters can be numbers or strings\n", - "rxn3 = Reaction(inputs3, outputs3, k=khill, propensity_type = \"hillpositive\", propensity_params = params_hill)\n", + "#parmeters can be numbers or strings\n", + "pos_hill = HillPositive(k=khill, K=0.3, n=2, s1=P)\n", + "rxn3 = Reaction(inputs3, outputs3,propensity_type=pos_hill)\n", "CRN2 = ChemicalReactionNetwork(species, [rxn3])\n", "print(\"\\nCRN2:\\n\",CRN2)" ] @@ -115,7 +119,7 @@ "* In update_species, we will create a list of all the species used in the reaction schema: the gene, gene-rnap complex, and the product species.\n", "* In update_reactions we create a list of all the reactions required for our reaction schema: the polymerase binding and unbinding reactions as well as the reaction producing the gene product X. \n", "\n", - "Note that this code could be generated much faster using the built in MichalisMentenRXN Mechanism, but we will do it by hand here for educational purposes." + "Note that this code could be generated much faster using the built in MichaelisMentenRXN Mechanism, but we will do it by hand here for educational purposes." ] }, { @@ -137,14 +141,8 @@ " #Check if the rnap type species (see chemical reaction network details below)\n", " if isinstance(rnap, Species):\n", " self.rnap = rnap\n", - " #or is type string, in which case create a \n", - " elif isinstance(rnap, str):\n", - " self.rnap = Species(name = rnap, material_type = \"protein\")\n", - " #someone might make RNAP a component if they want to add it to a mixture, as you might with a T7 polymerase in a cell-free system\n", - " elif isinstance(rnap, Component) and rnap.get_species() != None:\n", - " self.rnap = rnap.get_species()\n", " else:\n", - " raise ValueError(\"'rnap' parameter must be a string, a Component with defined get_specie(), or a chemical_reaction_network.specie\")\n", + " raise ValueError(\"'rnap' must be a Species!\")\n", " #The superclass constructor will take care of the name\n", " Mechanism.__init__(self = self, name = name, mechanism_type = type, **keywords) #MUST CALL THE SUPER CONSTRUCTOR!\n", " \n", @@ -156,8 +154,8 @@ " #We do not need to do a check on the DNA or product types because that will be performed at the Component level.\n", " #Create the list of species to return\n", " species = [dna, self.rnap, product]\n", - " #The ComplexSpecies class is chemical_reaction_network.specie complex made up a list of species\n", - " species += [ComplexSpecies([dna, self.rnap])]\n", + " #The Complex returns a ComplexSpecies made up a list of species\n", + " species += [Complex([dna, self.rnap])]\n", " #Return a list of species\n", " return species\n", " \n", @@ -169,19 +167,19 @@ " #update_reactions will require rates as well as the relevant species. Returns a list of chemical_reaction_network.reaction\n", " def update_reactions(self, dna, product, component, part_id = None):\n", " \n", - " #Component.get_parameter will automatically search a parameter dictionary for the best parameter to use.\n", + " #Component.get_parameter will automatically search the ParameterDatabases for the best parameter to use.\n", " #The string names here, 'kexpress', 'kb', 'ku', must be defined by you to match the parameter data file.\n", - " #see parameter loading examples for more information.\n", + " #see parameter jupyter notebook for more information.\n", " kexpress = component.get_parameter(\"kexpress\", part_id = part_id, mechanism = self)\n", " kb = component.get_parameter(\"kb\", part_id = part_id, mechanism = self)\n", " ku = component.get_parameter(\"ku\", part_id = part_id, mechanism = self)\n", " \n", " #complex specie\n", - " comp = ComplexSpecies([dna, self.rnap])\n", + " comp = Complex([dna, self.rnap])\n", " #Binding Reaction: dna + rnap <--> dna:rnap\n", - " binding_rxn = Reaction(inputs=[dna, self.rnap], outputs=[comp], k=kb, k_rev=ku)\n", + " binding_rxn = Reaction.from_massaction(inputs=[dna, self.rnap], outputs=[comp], k_forward=kb, k_reverse=ku)\n", " #Catalytic Reaction: dna:rnap --> dna + rnap + product\n", - " cat_rxn = Reaction(inputs=[comp], outputs=[dna, product, self.rnap], k=kexpress)\n", + " cat_rxn = Reaction.from_massaction(inputs=[comp], outputs=[dna, product, self.rnap], k_forward=kexpress)\n", " #Return a list of reactions\n", " return [binding_rxn, cat_rxn]" ] @@ -201,7 +199,7 @@ }, { "cell_type": "code", - "execution_count": 3, + "execution_count": 7, "metadata": {}, "outputs": [], "source": [ @@ -228,7 +226,7 @@ " #The Component will automatically search for a mechanism called \"gene_expression\", which it can find in 2 ways\n", " # 1: it can inherit this from its Mixture (which requires the Mixture has an appropriate \"gene_expression\" mechanism)\n", " # 2: this can be passed into the Gene constructor in a dictionary as a keyword arg mechanisms= {'gene_expression':Mechanism [Object Instance]}\n", - " mech_express = self.mechanisms[\"gene_expression\"] #key is the mechanism type\n", + " mech_express = self.get_mechanism(\"gene_expression\") #argument is the mechanism type\n", " \n", " #Return the species from the mechanisms in your mixture. In this case, just one.\n", " return mech_express.update_species(self.dna, self.product)\n", @@ -236,8 +234,8 @@ " #OVERWRITE update_reactions\n", " def update_reactions(self):\n", " \n", - " #get mechanism: key is the mechanism type\n", - " mech_express = self.mechanisms[\"gene_expression\"] \n", + " #argument is the mechanism type\n", + " mech_express = self.get_mechanism(\"gene_expression\")\n", " \n", " #Return the reactions from each mechanism in your mixture. In this case, just this one.\n", " return mech_express.update_reactions(self.dna, self.product, component = self, part_id = self.name)" @@ -253,41 +251,37 @@ }, { "cell_type": "code", - "execution_count": 4, + "execution_count": 8, "metadata": {}, "outputs": [], "source": [ "#ExpressionMixture\n", - "from biocrnpyler import Mixture\n", + "from biocrnpyler import Mixture, Protein\n", "\n", "class ExpressionMixture(Mixture):\n", " #OVERWRITE THIS METHOD\n", " def __init__(self, name=\"\", rnap = \"RNAP\", **keywords):\n", - " #Check if the rnap type species (see chemical reaction network details below)\n", - " if isinstance(rnap, Species):\n", - " self.rnap = rnap\n", - " #or is type string, in which case create a \n", - " elif isinstance(rnap, str):\n", - " self.rnap = Species(name = rnap, material_type = \"protein\")\n", - " #someone might make RNAP a component if they want to add it to a mixture, as you might with a T7 polymerase in a cell-free system\n", - " elif isinstance(rnap, Component) and rnap.get_species() != None:\n", - " self.rnap = rnap.get_species()\n", - " else:\n", - " raise ValueError(\"'rnap' parameter must be a string, a Component with defined get_species(), or a chemical_reaction_network.species\")\n", + " #MUST CALL THE SUPERCLASS CONSTRUCTOR!\n", + " Mixture.__init__(self, name = name, **keywords)\n", + " \n", + " #RNAP is a component which will be added to the Mixture\n", + " self.rnap = Protein(rnap) \n", + " \n", + " #add the components to the Mixture\n", + " self.add_components([self.rnap])\n", " \n", " #Create an instance of the GeneExpression mechanism\n", - " mech_express = GeneExpression(\"default_gene_expression\", self.rnap)\n", + " mech_express = GeneExpression(\"gene_expression\", self.rnap.get_species())\n", + " #notice the Species inside the Component is passed in with Component.get_species()\n", " \n", " #Create default mechanism dict\n", " default_mechanisms = {\n", " mech_express.mechanism_type:mech_express\n", " }\n", " \n", - " #Create default components\n", - "# default_components = [self.rnap]\n", - " species = [self.rnap]\n", - " #MUST CALL THE SUPERCLASS CONSTRUCTOR!\n", - " Mixture.__init__(self, name = name, default_mechanisms=default_mechanisms, **keywords) \n", + " #add the mechanisms to the Mixture\n", + " self.add_mechanisms(default_mechanisms)\n", + " \n", " " ] }, @@ -300,48 +294,57 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": 10, "metadata": {}, "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "C:\\Users\\apand\\Anaconda3\\lib\\site-packages\\biocrnpyler-0.1-py3.7.egg\\biocrnpyler\\component.py:11: UserWarning: get_species() not defined for component {self.name}, None returned.\n" - ] - }, { "name": "stdout", "output_type": "stream", "text": [ + "ExpressionMixture: \n", "Internal String Representation of the CRN:\n", " Species = dna_Reporter, protein_RNAP, GFP, complex_dna_Reporter_protein_RNAP\n", "Reactions = [\n", - "\tdna_Reporter + protein_RNAP <--> complex_dna_Reporter_protein_RNAP massaction: k_f(dna_Reporter,protein_RNAP)=100.0*dna_Reporter*protein_RNAP k_r(complex_dna_Reporter_protein_RNAP)=0.01*complex_dna_Reporter_protein_RNAP\n", - "\tcomplex_dna_Reporter_protein_RNAP --> dna_Reporter + GFP + protein_RNAP massaction: k_f(complex_dna_Reporter_protein_RNAP)=1.0*complex_dna_Reporter_protein_RNAP\n", + "\tdna[Reporter]+protein[RNAP] <--> complex[dna[Reporter]:protein[RNAP]]\n", + "\tcomplex[dna[Reporter]:protein[RNAP]] --> dna[Reporter]+GFP+protein[RNAP]\n", "]\n", "\n", "Fancier Pretty Print Representation Can also be used for Species, Reactions, and CRNS:\n", - " Species (4) = {0. dna[Reporter], 1. protein[RNAP], 2. GFP, 3. complexdna[Reporter]:protein[RNAP]]}\n", + " Species (4) = {0. dna[Reporter], 1. protein[RNAP], 2. GFP, 3. complex[dna[Reporter]:protein[RNAP]]}\n", + "\n", "Reactions (2) = [\n", - "0. dna[Reporter] + protein[RNAP] <--> complexdna[Reporter]:protein[RNAP]] \n", - " massaction: k_f(dna[Reporter],protein[RNAP])=100.0*dna[Reporter]*protein[RNAP]\n", - " k_r(complexdna[Reporter]:protein[RNAP]])=0.01*complexdna[Reporter]:protein[RNAP]]\n", - "1. complexdna[Reporter]:protein[RNAP]] --> dna[Reporter] + GFP + protein[RNAP] \n", - " massaction: k_f(complexdna[Reporter]:protein[RNAP]])=1.0*complexdna[Reporter]:protein[RNAP]]\n", + "0. dna[Reporter]+protein[RNAP] <--> complex[dna[Reporter]:protein[RNAP]]\n", + " Kf=k_forward * dna_Reporter * protein_RNAP\n", + " Kr=k_reverse * complex_dna_Reporter_protein_RNAP\n", + " k_forward=100.0\n", + " found_key=(mech=gene_expression, partid=Reporter, name=kb).\n", + " search_key=(mech=gene_expression, partid=Reporter, name=kb).\n", + " k_reverse=0.01\n", + " found_key=(mech=gene_expression, partid=Reporter, name=ku).\n", + " search_key=(mech=gene_expression, partid=Reporter, name=ku).\n", + "\n", + "1. complex[dna[Reporter]:protein[RNAP]] --> dna[Reporter]+GFP+protein[RNAP]\n", + " Kf=k_forward * complex_dna_Reporter_protein_RNAP\n", + " k_forward=1.0\n", + " found_key=(mech=gene_expression, partid=Reporter, name=kexpress).\n", + " search_key=(mech=gene_expression, partid=Reporter, name=kexpress).\n", + "\n", "]\n" ] } ], "source": [ "#Create a fake parameter dictionary for the example\n", - "parameters = {(\"default_gene_expression\",\"Reporter\", \"kexpress\"):1.0, \n", - " (\"default_gene_expression\",\"Reporter\", \"ku\"):.01,\n", - " (\"default_gene_expression\",\"Reporter\", \"kb\"):100.0 }\n", + "parameters = {(\"gene_expression\",\"Reporter\", \"kexpress\"):1.0, \n", + " (\"gene_expression\",\"Reporter\", \"ku\"):.01,\n", + " (\"gene_expression\",\"Reporter\", \"kb\"):100.0 }\n", "\n", "#Instantiate a gene\n", "G1 = Gene(\"Reporter\", \"GFP\", parameters = parameters)\n", "myMixture = ExpressionMixture(components = [G1])\n", + "\n", + "print(myMixture)\n", + "\n", "CRN = myMixture.compile_crn()\n", "#Print the CRN\n", "print(\"Internal String Representation of the CRN:\\n\", CRN)\n", @@ -386,4 +389,4 @@ }, "nbformat": 4, "nbformat_minor": 2 -} +} \ No newline at end of file diff --git a/examples/DNA_construct Examples.ipynb b/examples/DNA_construct Examples.ipynb new file mode 100644 index 00000000..e65b76c5 --- /dev/null +++ b/examples/DNA_construct Examples.ipynb @@ -0,0 +1,783 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# DNA_construct Introduction\n", + "DNA_construct is a flexible way to indicate a DNA sequence.\n", + "\n", + "A DNA sequence is composed of a string of nucleotides. The sequence of these nucleotides can allow binding of other biomolecules such as proteins or RNA. We choose to annotate known binding interactions and other features of DNA sequences by considering them to be \"DNA parts\". a \"part\" has a certain function, and the order and orientation of parts on a dna sequence describes the overall function of that DNA sequence.\n", + "\n", + "For example, a `Promoter` is a part which binds to RNA polymerase and causes everything downstream to be transcribed into RNA. A `Terminator`, then, is a sequence which stops the transcription of DNA into RNA. Therefore, anything between a `Promoter` and a `Terminator` gets turned into RNA.\n", + "\n", + "Other parts such as a Ribosome Binding Site or `RBS`, binds to the ribosome, but only if it is made of RNA and not DNA. Thus, an `RBS` is _like_ a `Promoter`, but instead of RNA it makes Protein. As always the position and orientation of parts determines what those parts actually do. If your sequence contains a Coding Sequence (`CDS`) _before_ an `RBS`, then the ribosome actually cannot translate that protein. Likewise if your `RBS` is after a `Terminator`, that `RBS` never gets turned into RNA.\n", + "\n", + "This type of logic is incorporated into `DNA_construct`." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The basic workflow is to first define a list of parts, then string them together into a `DNA_construct`" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": { + "tags": [] + }, + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": "imports done!\n\nCRN species\ndna[dna[ptet-forward]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]]\ndna[dna[ptet-forward]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]]\nprotein[RNAP]\ndna[dna[ptet-forward]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]]\nrna[rna[UTR1-forward]:rna[GFP-forward]:rna[t16-forward]]\nordered_polymer[complex[dna[ptet]:protein[RNAP]-forward]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]]\nprotein[tetr]\ndna[dna[ptet-forward]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]]\nordered_polymer[[dna[ptet]:2x_protein[tetr]-forward]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]]\nordered_polymer[[dna[ptet]:2x_protein[tetr]-forward]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]]\nprotein[RNAP]\nordered_polymer[[dna[ptet]:2x_protein[tetr]-forward]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]]\nrna[rna[UTR1-forward]:rna[GFP-forward]:rna[t16-forward]]\nordered_polymer[complex[[dna[ptet]:2x_protein[tetr]]:protein[RNAP]-forward]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]]\nrna[rna[UTR1-forward]:rna[GFP-forward]:rna[t16-forward]]\nprotein[Ribosome]\nrna[rna[UTR1-forward]:rna[GFP-forward]:rna[t16-forward]]\nordered_polymer[complex[protein[Ribosome]:rna[UTR1]-forward]:rna[GFP-forward]:rna[t16-forward]]\nprotein[GFP]\n\nCRN reactions\ndna[dna[ptet-forward]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]]+protein[RNAP] <--> ordered_polymer[complex[dna[ptet]:protein[RNAP]-forward]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]]\n Kf=k_forward * dna_ptet_f_UTR1_f_GFP_f_t16_f * protein_RNAP\n Kr=k_reverse * ordered_polymer_dna_ptet_protein_RNAP_f_UTR1_f_GFP_f_t16_f\n k_forward=100\n found_key=(mech=None, partid=None, name=kb).\n search_key=(mech=transcription_mm, partid=ptet_leak, name=kb).\n k_reverse=10\n found_key=(mech=None, partid=None, name=ku).\n search_key=(mech=transcription_mm, partid=ptet_leak, name=ku).\n\nordered_polymer[complex[dna[ptet]:protein[RNAP]-forward]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]] --> dna[dna[ptet-forward]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]]+rna[rna[UTR1-forward]:rna[GFP-forward]:rna[t16-forward]]+protein[RNAP]\n Kf=k_forward * ordered_polymer_dna_ptet_protein_RNAP_f_UTR1_f_GFP_f_t16_f\n k_forward=0.05\n found_key=(mech=None, partid=None, name=ktx).\n search_key=(mech=transcription_mm, partid=ptet_leak, name=ktx).\n\n2protein[tetr]+dna[dna[ptet-forward]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]] <--> ordered_polymer[[dna[ptet]:2x_protein[tetr]-forward]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]]\n Kf=k_forward * protein_tetr^2 * dna_ptet_f_UTR1_f_GFP_f_t16_f\n Kr=k_reverse * ordered_polymer_dna_ptet_protein_tetr_2x_f_UTR1_f_GFP_f_t16_f\n k_forward=100\n found_key=(mech=None, partid=None, name=kb).\n search_key=(mech=one_step_cooperative_binding, partid=ptet_tetr, name=kb).\n k_reverse=10\n found_key=(mech=None, partid=None, name=ku).\n search_key=(mech=one_step_cooperative_binding, partid=ptet_tetr, name=ku).\n\nordered_polymer[[dna[ptet]:2x_protein[tetr]-forward]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]]+protein[RNAP] <--> ordered_polymer[complex[[dna[ptet]:2x_protein[tetr]]:protein[RNAP]-forward]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]]\n Kf=k_forward * ordered_polymer_dna_ptet_protein_tetr_2x_f_UTR1_f_GFP_f_t16_f * protein_RNAP\n Kr=k_reverse * ordered_polymer_dna_ptet_protein_tetr_2x_protein_RNAP_f_UTR1_f_GFP_f_t16_f\n k_forward=100\n found_key=(mech=None, partid=None, name=kb).\n search_key=(mech=transcription_mm, partid=ptet_tetr, name=kb).\n k_reverse=10\n found_key=(mech=None, partid=None, name=ku).\n search_key=(mech=transcription_mm, partid=ptet_tetr, name=ku).\n\nordered_polymer[complex[[dna[ptet]:2x_protein[tetr]]:protein[RNAP]-forward]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]] --> ordered_polymer[[dna[ptet]:2x_protein[tetr]-forward]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]]+rna[rna[UTR1-forward]:rna[GFP-forward]:rna[t16-forward]]+protein[RNAP]\n Kf=k_forward * ordered_polymer_dna_ptet_protein_tetr_2x_protein_RNAP_f_UTR1_f_GFP_f_t16_f\n k_forward=0.05\n found_key=(mech=None, partid=None, name=ktx).\n search_key=(mech=transcription_mm, partid=ptet_tetr, name=ktx).\n\nrna[rna[UTR1-forward]:rna[GFP-forward]:rna[t16-forward]]+protein[Ribosome] <--> ordered_polymer[complex[protein[Ribosome]:rna[UTR1]-forward]:rna[GFP-forward]:rna[t16-forward]]\n Kf=k_forward * rna_UTR1_f_GFP_f_t16_f * protein_Ribosome\n Kr=k_reverse * ordered_polymer_protein_Ribosome_rna_UTR1_f_GFP_f_t16_f\n k_forward=100\n found_key=(mech=None, partid=None, name=kb).\n search_key=(mech=translation_mm, partid=UTR1, name=kb).\n k_reverse=10\n found_key=(mech=None, partid=None, name=ku).\n search_key=(mech=translation_mm, partid=UTR1, name=ku).\n\nordered_polymer[complex[protein[Ribosome]:rna[UTR1]-forward]:rna[GFP-forward]:rna[t16-forward]] --> rna[rna[UTR1-forward]:rna[GFP-forward]:rna[t16-forward]]+protein[GFP]+protein[Ribosome]\n Kf=k_forward * ordered_polymer_protein_Ribosome_rna_UTR1_f_GFP_f_t16_f\n k_forward=0.2\n found_key=(mech=None, partid=None, name=ktl).\n search_key=(mech=translation_mm, partid=UTR1, name=ktl).\n\n" + } + ], + "source": [ + "from biocrnpyler import *\n", + "try:\n", + " #dnaplotlib is a cool library for plotting DNAs.\n", + " #please use my fork located at https://github.com/dr3y/dnaplotlib\n", + " #to install it type: pip install git+git://github.com/dr3y/dnaplotlib.git@master\n", + " import dnaplotlib as dpl\n", + " %matplotlib inline\n", + " dpl_enabled = True\n", + "except (ModuleNotFoundError,ImportError) as e:\n", + " dpl_enabled = False\n", + "\n", + "print(\"imports done!\")\n", + "\n", + "def plotNetwork(inCRN,use_pretty_print=True,colordict = None,iterations=2000,rseed=30,posscale=1,export=False):\n", + " try:\n", + " from bokeh.models import (Plot , Range1d)\n", + "\n", + " import bokeh.plotting\n", + " import bokeh.io\n", + " bokeh.io.output_notebook() #this makes the graph appear in line with the notebook\n", + " if(colordict is None):\n", + " colordict={\"complex\":\"cyan\",\"protein\":\"green\",\n", + " \"GFP\":\"lightgreen\",\n", + " \"RFP\":\"red\",\n", + " \"ribosome\":\"blue\",\n", + " \"dna\":\"white\",\"rna\":\"orange\",\n", + " \"ligand\":\"pink\",\"phosphate\":\"yellow\",\"nothing\":\"purple\"}\n", + " layout_str = \"force\"\n", + " DG, DGspec, DGrxn = generate_networkx_graph(inCRN,use_pretty_print=use_pretty_print,colordict=colordict) #this creates the networkx objects\n", + " plot = Plot(plot_width=500, plot_height=500, x_range=Range1d(-500, 500), y_range=Range1d(-500, 500)) #this generates a \n", + " if(export):\n", + " plot.output_backend = \"svg\"\n", + " graphPlot(DG,DGspec,DGrxn,plot,layout=layout_str,posscale=posscale,iterations=iterations,rseed=rseed) #now you draw the network on the plot. Layout \"force\" is \n", + " bokeh.io.show(plot) #if you don't type this the plot won't show\n", + " if(export):\n", + " bokeh.io.export_svgs(plot, \"plot_file.svg\")\n", + " \n", + " except ModuleNotFoundError:\n", + " return None\n", + "\n", + "\n", + "\n", + "\n", + "ptet = RegulatedPromoter(\"ptet\",[\"tetr\"],leak=True) #this is a repressible promoter\n", + "pconst = Promoter(\"pconst\") #constitutive promoter\n", + "utr1 = RBS(\"UTR1\") #regular RBS\n", + "gfp = CDS(\"GFP\",\"GFP\")\n", + "t16 = Terminator(\"t16\") #a terminator stops transcription\n", + "\n", + "\n", + "#now that the parts are defined, we can put together our construct.\n", + "parameters={\"cooperativity\":2,\"kb\":100, \"ku\":10, \"ktx\":.05, \"ktl\":.2, \"kdeg\":2,\"kint\":.05}\n", + "\n", + "construct_1 = DNA_construct([[ptet,\"forward\"],[utr1,\"forward\"],[gfp,\"forward\"],[t16,\"forward\"]],\\\n", + " mechanisms = {\"transcription\":Transcription_MM(Species(\"RNAP\",material_type=\"protein\")),\\\n", + " \"translation\":Translation_MM(Species(\"Ribosome\",material_type=\"protein\")),\\\n", + " \"binding\":One_Step_Cooperative_Binding()},parameters=parameters) \n", + "x = construct_1.update_species()\n", + "print()\n", + "print(\"CRN species\")\n", + "print('\\n'.join([a.pretty_print() for a in x]))\n", + "\n", + "y = construct_1.update_reactions()\n", + "print()\n", + "print(\"CRN reactions\")\n", + "print('\\n'.join([a.pretty_print() for a in y]))\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": { + "scrolled": true, + "tags": [] + }, + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": "imports done!\n" + }, + { + "output_type": "display_data", + "data": { + "text/plain": "
", + "image/svg+xml": "\r\n\r\n\r\n\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n\r\n", + "image/png": "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\n" + }, + "metadata": { + "needs_background": "light" + } + }, + { + "output_type": "display_data", + "data": { + "text/plain": "
", + "image/svg+xml": "\r\n\r\n\r\n\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n\r\n", + "image/png": "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\n" + }, + "metadata": { + "needs_background": "light" + } + }, + { + "output_type": "display_data", + "data": { + "text/plain": "
", + "image/svg+xml": "\r\n\r\n\r\n\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n\r\n", + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAOYAAABtCAYAAAC1HR2gAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADh0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uMy4xLjMsIGh0dHA6Ly9tYXRwbG90bGliLm9yZy+AADFEAAAPo0lEQVR4nO2deZgV1ZnGf283LSggiBoRBBFlEbeQeVTCxMRdozJN1KhoO3GLrcbRMSpxXFAUjJkhaIxx7DhRH233ZWwnxhWDQUUxioqoiChrszYgdrM13d/8UXXJ5drLvbeXqr73+z1PP111qr46b9Wtt85y654jM8NxnHhRELUAx3G+jRvTcWKIG9NxYogb03FiiBvTcWKIG9NxYkirGVPSA5ImtNbxHCef6RAlpqQBkkxSp6S03SU9J6ky3DaggbijJb0vqUbSIkmntYGm6vBvvqRrUvaZL2lD0j7VkvqkE9tK2jqlpD8gaYKka5Py3iipLml9drivhdetWtISSZMlFSYd6zRJb0laL2lqa2mPK5KmSrqgvfLrEMZshHrgReCUhjZKGgY8AlwH9AC+C7yXSQapN3Yj9DSzbsCpwA2SjknZPsrMuiX9VTYQOwYYJ+n4VtbWIGZ2a0IPcBEwPUnffkm7HhTu8yPgdOC8pG2rgTuA27LV0ZJz6Chke45ZG1PS8LA0+kbS40CXMP1wSYslXSlphaSlks5NijtR0kxJ68JS7KY0svtb+H9t+AT/vpktN7O7gXcbibkeKDOzF8xsi5lVmdm8Zs4pUdKcL2kh8Foa2gAws78DswkeABlhZtPD2P2b0WeSfiFpLjA303yyxcy+AN4k6dzM7FUzewKobDQwhUyub9K+F4a1oqWSrkzaXhiW/PPCe/A9Sf3CbSMlvSvp6/D/yKS4qZJukfRmGPeypF3CbV0klUuqkrQ2jN1N0kTgMOCu8P67q5nzbPHnlJUxJW0HPAs8BPQCnmTbkqs3QSnVFzgf+IOkncJtNcC/Aj2BE4GLJY1uJssfhv97hk/16WnIHBFqnRV+qOWSeqURB0EJsS9wXJr7I2kEgbG+SDcmjJOkfwb2A2amETIaOBQYlkk+LUHSUIIbM6Nza4JMru8RwCDgWOAaSUeH6b8kqGmcAOxIUJqvDz/j54E7gZ2BycDzknZOOuaZwLnAd4DtgKvC9J8R3Lf9wtiLgA1mdh0wDbg0vP8uTUN3yz4nM8v4j8AolYCS0t4CJgCHAxuATknbVgAjGjnWHcDtzeQ3ALDkYyZt6xRuG5CSvhmYDwwGugFPAw+nmc/ANK5BYt+14fkaMCnlmswHqsN91gLPNhC7BvgUuCyNPA04MgNtnVLSHwAmpKSdA7zRSF7rCB6kBjwKdG5gvwuAqWneN9lc36FJaf8J/ClcngMUNxB3NjAjJW06cE64PBW4PmnbJcCL4fJ54X18YAPHnQpckOZ5pvU5NfWXbR2/D7DEQhUhC5KWq8xsS9L6egJzIOlQgnbJ/gRPq84EJW5rswG438w+D/O9FXg1zdhFGeSzC8EH8e8ET/AigodCgtFm1li+u6Rcp9bSljhmUdJyYr02g7y+B8wDfkrwmXUFNmUQ3xiZXN/kfRcAB4TL/UJtqfRh23sxEdc3aX1Z0vLWe5OgBtgPeExST6AcuM7MMrlmDenOmGzbmEuBvpKUlNY/zdhHgOeAfmbWA7gHUNMhZPMTmI+yjMs4PzOrM7PfAhsJnsBtSTralhIYcEBK+l58+6ZtOrOAJwhKnXGZxDZ12Az27Ze03J9/tGkXAXs3sH8lsGdKWn9gSbOizGrNbLyZDQNGAicRNLsy1ZzN/tuQrTGnEzyJL5PUSdLJwCFpxnYHVpvZRkmHENT3m2MlQS/swORESV0ISlyAzuF6gvuBcyUNlLQD8Cvgz2lqzJbbgLEpOtodM6sjqLpPlLSzpCJJYwjaOy9kedjbgAsl9YatnS9dCJoSBWHHSVFr6E/hBkk7SNqPoF34eJj+P8AtkgaF7fQDw3bkX4DBks4M783TCc672c9e0hGSDlDwtdA6godbXbh5OSn3X1uSlTHNbDNwMkH7ZA1BV/ozaYZfAtws6RuCJ/ATaeS3HpgIvBn2lo0IN20gaMMBfBauJ2LuAx4E3iEoJTYBl6WpMVueJ7geP2/jfNLhEoKvND4iaONfCpxoZsuzOZiZzQJeB64Ok84muN7/TdAxtAG4t4WaG+J1gk6nKcAkM3s5TJ9McO+8TGCiPwHbm1kVQUl3JVAFjAVOMrNVaeTVG3gqPN6nYd7l4bbfAadKWiPpztY4sabQts1Ex4kHCl4Y+QooyqId3uHpyC8YOE7OEhtjSjpL2766ts0rYlHk016akvI7rJH8qluyb3sS5+vbWrTHtfeqrOPEkNiUmI7j/AM3puPEEDem48QQN6bjxBA3puPEEDem48QQN6bjxBA3puPEEDem48QQN6bjxBA3puPEEDem48QQN6bjxBA3ZjNI6tz8Xo7Turgxm0BSV4LBwxynXcn5IeqzJRzA6880Mzq647QFXmI2gKTtCYbYPDxiKU6e4sZMIRyS8X+Bo6LW4uQvbswkwo6ep8lgzhLHaQvcmCHhRElPEkxS4ziR4sYEwhHEHwNGRa3FccCNmZhY9BHgJ4m0XYenPX+s47QJeW3M0JQPEcwGDUDvEafQ78hzItPkOJDHxgwnjrkfOCOR1vvQ0fQ/5oLoRDlOSF4aU1IBwWxRJYm03Q4eRf9jS9l2ZkHHiYa8M2ZoyjKCmcoA+M4/ncCex1/spnRiQ169khdOtHs3wfTkAOw6/DgGnHApgV8bpKukm9pBXpz5nZmtiVpEPpE3xgxN+XugNJG2y0FHs9dJlzdlSoDtgRvbWF7ceZBg3k+nnciLqmxoytuBXyTSdj7gCAaOuqI5UzpOJOR8iRma8r+AyxNpO+/3I/YuvgoVFDYYU1DUhb4/PKudFMaTZTMqqNsY6Yx+eU1OGzM05a0E034D0GvfH7D3T8Y2akqAwu26sMfhZ7eDwviy6qMpbswIyfV63HjgmsTKTkNHsvfJ1zRpSseJAzlrTEnjgBsS6z0HH8o+p/wHBYU5XUlwcoScNKakawlKSwB67nMwg069joLCoghVOU765JwxJY0FJibWewz8HoNOu4GCTttFqMpxMiOnjCnpCuA3ifUd9/oug0+/0U3pdDhyxpiS/g2YnFjvvueBDD7jJgqKfPRJp+ORE8aUdDFwZ2K9e//9GTJmPIVFXSJU5TjZ0+GNKennBO+/AtBtj2EMGXMzhdttH6Eqx2kZHfq7A0nnAX9MrHftO5QhZ91CYecdIlSVH0jqTvTDe04xs/URa2gT0jKmJGuNzBb32WPr8h6Vi1vjkFvp2mcQQ8+aQKfOXVv1uA4A8+L6k7g46rrnXx7aunzRcw2/QWZmTQrv8FXZBD33OYROXbpFLcNxWoUOXZVNZsnfHqaw8w7s/v1TopaSl+w6fFcKCtu29KqrrWPVh1VtmkdcSMuYzRW76bKkb7+tVeLWOGbS/CJHACx85V5UUEjvQ0e39NDOtuxtZl+mJkpaCPQD2LdkMD0G9mhTEas/XZ1szDlmNrRNM8ySsuLyFt/nHboqGzb8RwHTEmkLXrqHZe8+F52o/OLtxELV7NVtnlnVJ9vk8XZj++UCHdqYAGZWA5wIvJVIW/DC3ax47y/RicofpiYW5r+4EKtvlT7CBqnfUs+ClxYmJ73eZpnFgA5vTAAz+wb4MfBOIu2r5+9kxcyXohOVH5QDXwPUVNawdPqyNstoybRKNqzcmFhdRTByfs6SE8YEMLN1BJMBvZtI++r/7mDlh69EJyrHCa/5PYn1WX+czcbVG5uIyI71Kzcw+75Pk5PuMrMNrZ5RjMgZYwKY2dcE5nw/TOHLismsmvValLJynd8CywA2r9vM+7d/QF1tXasdfMumOt6f/AG11bWJpEUkvX6Zq+SUMQHCYRaPBT4MU5j37CSqZud0kyQyzGwlwcDZBlD18WpmTHyP2vW1TQemwebqWmbc8i5rPts6QF8dMCYfhtLMOWMCmFkVcDQwK0io54tnfkPVJ9OajHOyw8ymAOMS66s+XMW0sW+xalb23zmu+GAl065+M7W39xozezN7pR2HnHnBIBUzWyXpaOCvwDCsnnnP3IYKCuk1dGTU8nKRiQQP+vEANUtqmD7uHfr8YHcGjtqLnoN6NPv6nJmxZs5a5lV8ybK3l6du/pWZTWoT5TEkZ40JYGYrJB1F0K0/xOrr+OKpWxn00+vZaciIxuPq66itWdteMmOJ1WfWTjQzA26W9BXBr326AVS+sZTKN5bSrW9Xdjt4N3bcszvd9+xOUbciMKit3sy6hdWsm7+O5TOWU7P0W++krwMuNLPHW+G0Ogw5bUwAM1sm6UgCcw6y+i3MfWoig08bR89BBzcYs2XDN8y8Pb/Hlc0WM3tI0hRgEjAmkV69pIbqJd96eag5HgTGmtm3is9cJyfbmKmYWSVwJPAlgNXV8vkTN7N23nvRCstRzKzSzM4ERgL3AZkMULsOuBc4xMx+lo+mhDwoMROY2WJJRxC8MTLA6mr5/PHxDDljPD0GDm8ylPDrgDwmq+8/zGw6MF3SZQRfYw0HDgSGAl2BemA98CnwETATeDlXf2OZCXljTAAzW5hkzv62ZTOfP3YTQ868mR0HHNRYWJWZ9Wk/lblH+NrkM+GfkwZ5UZVNxszmE1RrFwPUb9nEnEdvZN2CjyPV5TjJ5J0xAcxsHoE5KwHqazcy59Eb+GbRJ9EKc5yQvDQmgJnNJTDnMoD6zRv47OHrqV78WbTCnFhQVlwe6ZgleWtMADObAxwFrACo37yezx6+jprKudEKcyKjrLh8UFlx+d3A+VHqyKvOn4Yws0/ClxD+CuxSt6mGuU9OiFqW046EpeNI4CqgGBBJ86lGQd4bE8DMPg5f33sN6FW/ZVPUkpx2oKy4vBAYTWDIxl8FiwA3ZoiZfZhkzp5R63HajrLi8q7AucAVwMCI5TSIGzMJM5sp6RjgVaBtR5Zy2p2y4vLewKXAJcBOEctpEjdmCmb2d0nHAa8A3aPW47ScsuLyYcCVBL8b7RBTv7kxG8DM3pF0POCDBnVQwg6dwwnajydEqyZzFPxaJzuSx4ltS/ouWRTJd0qSDgMeMrMBUeTvZEdZcXkv4Gmin1uF0oqS/BtXtq0xs2nAyVHrcDKjtKJkNUFv69XAkojlZIUbsxnM7P2oNTiZU1pR8nVpRckkgl7Xs4EPIpaUES2qyjpORyFscx5J0OY8Po2Qy0srSiIbjc87f5y8oLSixIApwJSy4vL9gV8S9NIWRSqsEbwq6+QdpRUlH5dWlJwHDAB+DcRuOEw3ppO3lFaUVJZWlFwL9AcuA76KWNJW3JhO3lNaUVJdWlHye2AwcBowI2JJ3vnjOKmEHUVdSytKMhlErFVxYzpODPGqrOPEEDem48QQN6bjxBA3puPEEDem48QQN6bjxBA3puPEEDem48QQN6bjxBA3puPEEDem48SQ/wea65B2arCoBwAAAABJRU5ErkJggg==\n" + }, + "metadata": { + "needs_background": "light" + } + }, + { + "output_type": "display_data", + "data": { + "text/plain": "
", + "image/svg+xml": "\r\n\r\n\r\n\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n\r\n", + "image/png": "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\n" + }, + "metadata": { + "needs_background": "light" + } + }, + { + "output_type": "stream", + "name": "stdout", + "text": "ptet_UTR1_GFP_t16\n\tptet_0\n\trna = UTR1_GFP_t16\n\tUTR1_0\n\tprotein = GFP_1\nt16_r_RFP_r_UTR1_r_pconst_r\n\tpconst_3_r\n\trna = UTR1_RFP_t16\n\tUTR1_0\n\tprotein = RFP_1\n" + } + ], + "source": [ + "from biocrnpyler import *\n", + "try:\n", + " #dnaplotlib is a cool library for plotting DNAs.\n", + " #please use my fork located at https://github.com/dr3y/dnaplotlib\n", + " #to install it type: pip install git+git://github.com/dr3y/dnaplotlib.git@master\n", + " import dnaplotlib as dpl\n", + " dpl_enabled = True\n", + "except (ModuleNotFoundError,ImportError) as e:\n", + " dpl_enabled = False\n", + "\n", + "print(\"imports done!\")\n", + "\n", + "#part definitions below\n", + "\n", + "ptet = RegulatedPromoter(\"ptet\",[\"tetr\"],leak=True) #this is a repressible promoter\n", + "pconst = Promoter(\"pconst\") #constitutive promoter\n", + "pcomb = CombinatorialPromoter(\"pcomb\",[\"arac\",\"laci\"], leak=False,\n", + " tx_capable_list = [[\"arac\"], [\"laci\"]]) #the Combinations A and B or just A or just B be transcribed\n", + "utr1 = RBS(\"UTR1\") #regular RBS\n", + "utr2 = RBS(\"UTR1\") #regular RBS\n", + "gfp = CDS(\"GFP\",\"GFP\") #a CDS has a name and a protein name. so this one is called GFP and the protein is also called GFP\n", + "fusrfp = CDS(\"fusRFP\",\"RFP\",no_stop_codons=[\"forward\"]) #you can say that a protein has no stop codon. This is a little different from a fusion protein, because in this case you are saying that the ribosome reads through two proteins but still produces two distinct proteins, rather than one fused protein. This can happen in the case of the ta peptide which causes a peptide bond not to be formed while making a protein.\n", + "rfp = CDS(\"RFP\",\"RFP\") #regular RFP\n", + "cfp = CDS(\"CFP\",\"CFP\") #cfp\n", + "t16 = Terminator(\"t16\") #a terminator stops transcription\n", + "\n", + "\n", + "#now that the parts are defined, we can put together our construct.\n", + "construct_1 = DNA_construct([[ptet,\"forward\"],[utr1,\"forward\"],[gfp,\"forward\"],[t16,\"forward\"]])\n", + "construct_2 = DNA_construct([[t16,\"reverse\"],[rfp,\"reverse\"],[utr2,\"reverse\"],[pconst,\"reverse\"]])\n", + "#now, we are using dnaplotlib to plot the constructs\n", + "\n", + "\n", + "if(dpl_enabled):\n", + " plotConstruct(construct_1,debug=False,plot_rnas=True)\n", + " plotConstruct(construct_2,debug=False,plot_rnas=True)\n", + " print(construct_1.show())\n", + " print(construct_2.show())\n", + "\n", + "#some very basic parameters are defined\n", + "parameters={\"cooperativity\":2,\"kb\":100, \"ku\":10, \"ktx\":.05, \"ktl\":.2, \"kdeg\":2,\"kint\":.05}\n", + "\n", + "components = [construct_1,construct_2]\n", + "myMixture = TxTlExtract(name = \"txtl\", parameters = parameters, components = components)\n", + "myCRN = myMixture.compile_crn()\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "You can see that for the first construct, your DNA is given an automatic name: `ptet_f_UTR1_f_GFP_f_t16_f`. \n", + "\n", + "The RNA made from your DNA is also given an automatic name: `UTR1_f_GFP_f_t16_f`\n", + "\n", + "Likewise for the second construct, which I've made in reverse to make the difference more apparent. Though you'll see that the RNA from the second construct is still produced in the right orientation, so the RNA is shown in the forwards direction.\n", + "\n", + "This is because DNA and RNA are now represented as an OrderedPolymer. Each member of the OrderedPolymer represents a part. So, in the case of promoters or RBSes, you'll see ribosomes and polymerases bind directly to the part inside the OrderedPolymer." + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": { + "tags": [] + }, + "outputs": [ + { + "output_type": "display_data", + "data": { + "text/html": "\n
\n \n Loading BokehJS ...\n
" + }, + "metadata": {} + }, + { + "output_type": "display_data", + "data": { + "application/javascript": "\n(function(root) {\n function now() {\n return new Date();\n }\n\n var force = true;\n\n if (typeof root._bokeh_onload_callbacks === \"undefined\" || force === true) {\n root._bokeh_onload_callbacks = [];\n root._bokeh_is_loading = undefined;\n }\n\n var JS_MIME_TYPE = 'application/javascript';\n var HTML_MIME_TYPE = 'text/html';\n var EXEC_MIME_TYPE = 'application/vnd.bokehjs_exec.v0+json';\n var CLASS_NAME = 'output_bokeh rendered_html';\n\n /**\n * Render data to the DOM node\n */\n function render(props, node) {\n var script = document.createElement(\"script\");\n node.appendChild(script);\n }\n\n /**\n * Handle when an output is cleared or removed\n */\n function handleClearOutput(event, handle) {\n var cell = handle.cell;\n\n var id = cell.output_area._bokeh_element_id;\n var server_id = cell.output_area._bokeh_server_id;\n // Clean up Bokeh references\n if (id != null && id in Bokeh.index) {\n Bokeh.index[id].model.document.clear();\n delete Bokeh.index[id];\n }\n\n if (server_id !== undefined) {\n // Clean up Bokeh references\n var cmd = \"from bokeh.io.state import curstate; print(curstate().uuid_to_server['\" + server_id + \"'].get_sessions()[0].document.roots[0]._id)\";\n cell.notebook.kernel.execute(cmd, {\n iopub: {\n output: function(msg) {\n var id = msg.content.text.trim();\n if (id in Bokeh.index) {\n Bokeh.index[id].model.document.clear();\n delete Bokeh.index[id];\n }\n }\n }\n });\n // Destroy server and session\n var cmd = \"import bokeh.io.notebook as ion; ion.destroy_server('\" + server_id + \"')\";\n cell.notebook.kernel.execute(cmd);\n }\n }\n\n /**\n * Handle when a new output is added\n */\n function handleAddOutput(event, handle) {\n var output_area = handle.output_area;\n var output = handle.output;\n\n // limit handleAddOutput to display_data with EXEC_MIME_TYPE content only\n if ((output.output_type != \"display_data\") || (!output.data.hasOwnProperty(EXEC_MIME_TYPE))) {\n return\n }\n\n var toinsert = output_area.element.find(\".\" + CLASS_NAME.split(' ')[0]);\n\n if (output.metadata[EXEC_MIME_TYPE][\"id\"] !== undefined) {\n toinsert[toinsert.length - 1].firstChild.textContent = output.data[JS_MIME_TYPE];\n // store reference to embed id on output_area\n output_area._bokeh_element_id = output.metadata[EXEC_MIME_TYPE][\"id\"];\n }\n if (output.metadata[EXEC_MIME_TYPE][\"server_id\"] !== undefined) {\n var bk_div = document.createElement(\"div\");\n bk_div.innerHTML = output.data[HTML_MIME_TYPE];\n var script_attrs = bk_div.children[0].attributes;\n for (var i = 0; i < script_attrs.length; i++) {\n toinsert[toinsert.length - 1].firstChild.setAttribute(script_attrs[i].name, script_attrs[i].value);\n }\n // store reference to server id on output_area\n output_area._bokeh_server_id = output.metadata[EXEC_MIME_TYPE][\"server_id\"];\n }\n }\n\n function register_renderer(events, OutputArea) {\n\n function append_mime(data, metadata, element) {\n // create a DOM node to render to\n var toinsert = this.create_output_subarea(\n metadata,\n CLASS_NAME,\n EXEC_MIME_TYPE\n );\n this.keyboard_manager.register_events(toinsert);\n // Render to node\n var props = {data: data, metadata: metadata[EXEC_MIME_TYPE]};\n render(props, toinsert[toinsert.length - 1]);\n element.append(toinsert);\n return toinsert\n }\n\n /* Handle when an output is cleared or removed */\n events.on('clear_output.CodeCell', handleClearOutput);\n events.on('delete.Cell', handleClearOutput);\n\n /* Handle when a new output is added */\n events.on('output_added.OutputArea', handleAddOutput);\n\n /**\n * Register the mime type and append_mime function with output_area\n */\n OutputArea.prototype.register_mime_type(EXEC_MIME_TYPE, append_mime, {\n /* Is output safe? */\n safe: true,\n /* Index of renderer in `output_area.display_order` */\n index: 0\n });\n }\n\n // register the mime type if in Jupyter Notebook environment and previously unregistered\n if (root.Jupyter !== undefined) {\n var events = require('base/js/events');\n var OutputArea = require('notebook/js/outputarea').OutputArea;\n\n if (OutputArea.prototype.mime_types().indexOf(EXEC_MIME_TYPE) == -1) {\n register_renderer(events, OutputArea);\n }\n }\n\n \n if (typeof (root._bokeh_timeout) === \"undefined\" || force === true) {\n root._bokeh_timeout = Date.now() + 5000;\n root._bokeh_failed_load = false;\n }\n\n var NB_LOAD_WARNING = {'data': {'text/html':\n \"
\\n\"+\n \"

\\n\"+\n \"BokehJS does not appear to have successfully loaded. If loading BokehJS from CDN, this \\n\"+\n \"may be due to a slow or bad network connection. Possible fixes:\\n\"+\n \"

\\n\"+\n \"
    \\n\"+\n \"
  • re-rerun `output_notebook()` to attempt to load from CDN again, or
  • \\n\"+\n \"
  • use INLINE resources instead, as so:
  • \\n\"+\n \"
\\n\"+\n \"\\n\"+\n \"from bokeh.resources import INLINE\\n\"+\n \"output_notebook(resources=INLINE)\\n\"+\n \"\\n\"+\n \"
\"}};\n\n function display_loaded() {\n var el = document.getElementById(\"1001\");\n if (el != null) {\n el.textContent = \"BokehJS is loading...\";\n }\n if (root.Bokeh !== undefined) {\n if (el != null) {\n el.textContent = \"BokehJS \" + root.Bokeh.version + \" successfully loaded.\";\n }\n } else if (Date.now() < root._bokeh_timeout) {\n setTimeout(display_loaded, 100)\n }\n }\n\n\n function run_callbacks() {\n try {\n root._bokeh_onload_callbacks.forEach(function(callback) {\n if (callback != null)\n callback();\n });\n } finally {\n delete root._bokeh_onload_callbacks\n }\n console.debug(\"Bokeh: all callbacks have finished\");\n }\n\n function load_libs(css_urls, js_urls, callback) {\n if (css_urls == null) css_urls = [];\n if (js_urls == null) js_urls = [];\n\n root._bokeh_onload_callbacks.push(callback);\n if (root._bokeh_is_loading > 0) {\n console.debug(\"Bokeh: BokehJS is being loaded, scheduling callback at\", now());\n return null;\n }\n if (js_urls == null || js_urls.length === 0) {\n run_callbacks();\n return null;\n }\n console.debug(\"Bokeh: BokehJS not loaded, scheduling load and callback at\", now());\n root._bokeh_is_loading = css_urls.length + js_urls.length;\n\n function on_load() {\n root._bokeh_is_loading--;\n if (root._bokeh_is_loading === 0) {\n console.debug(\"Bokeh: all BokehJS libraries/stylesheets loaded\");\n run_callbacks()\n }\n }\n\n function on_error() {\n console.error(\"failed to load \" + url);\n }\n\n for (var i = 0; i < css_urls.length; i++) {\n var url = css_urls[i];\n const element = document.createElement(\"link\");\n element.onload = on_load;\n element.onerror = on_error;\n element.rel = \"stylesheet\";\n element.type = \"text/css\";\n element.href = url;\n console.debug(\"Bokeh: injecting link tag for BokehJS stylesheet: \", url);\n document.body.appendChild(element);\n }\n\n for (var i = 0; i < js_urls.length; i++) {\n var url = js_urls[i];\n var element = document.createElement('script');\n element.onload = on_load;\n element.onerror = on_error;\n element.async = false;\n element.src = url;\n console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n document.head.appendChild(element);\n }\n };var element = document.getElementById(\"1001\");\n if (element == null) {\n console.error(\"Bokeh: ERROR: autoload.js configured with elementid '1001' but no matching script tag was found. \")\n return false;\n }\n\n function inject_raw_css(css) {\n const element = document.createElement(\"style\");\n element.appendChild(document.createTextNode(css));\n document.body.appendChild(element);\n }\n\n \n var js_urls = [\"https://cdn.pydata.org/bokeh/release/bokeh-1.4.0.min.js\", \"https://cdn.pydata.org/bokeh/release/bokeh-widgets-1.4.0.min.js\", \"https://cdn.pydata.org/bokeh/release/bokeh-tables-1.4.0.min.js\", \"https://cdn.pydata.org/bokeh/release/bokeh-gl-1.4.0.min.js\"];\n var css_urls = [];\n \n\n var inline_js = [\n function(Bokeh) {\n Bokeh.set_log_level(\"info\");\n },\n function(Bokeh) {\n \n \n }\n ];\n\n function run_inline_js() {\n \n if (root.Bokeh !== undefined || force === true) {\n \n for (var i = 0; i < inline_js.length; i++) {\n inline_js[i].call(root, root.Bokeh);\n }\n if (force === true) {\n display_loaded();\n }} else if (Date.now() < root._bokeh_timeout) {\n setTimeout(run_inline_js, 100);\n } else if (!root._bokeh_failed_load) {\n console.log(\"Bokeh: BokehJS failed to load within specified timeout.\");\n root._bokeh_failed_load = true;\n } else if (force !== true) {\n var cell = $(document.getElementById(\"1001\")).parents('.cell').data().cell;\n cell.output_area.append_execute_result(NB_LOAD_WARNING)\n }\n\n }\n\n if (root._bokeh_is_loading === 0) {\n console.debug(\"Bokeh: BokehJS loaded, going straight to plotting\");\n run_inline_js();\n } else {\n load_libs(css_urls, js_urls, function() {\n console.debug(\"Bokeh: BokehJS plotting callback run at\", now());\n run_inline_js();\n });\n }\n}(window));", + "application/vnd.bokehjs_load.v0+json": "\n(function(root) {\n function now() {\n return new Date();\n }\n\n var force = true;\n\n if (typeof root._bokeh_onload_callbacks === \"undefined\" || force === true) {\n root._bokeh_onload_callbacks = [];\n root._bokeh_is_loading = undefined;\n }\n\n \n\n \n if (typeof (root._bokeh_timeout) === \"undefined\" || force === true) {\n root._bokeh_timeout = Date.now() + 5000;\n root._bokeh_failed_load = false;\n }\n\n var NB_LOAD_WARNING = {'data': {'text/html':\n \"
\\n\"+\n \"

\\n\"+\n \"BokehJS does not appear to have successfully loaded. If loading BokehJS from CDN, this \\n\"+\n \"may be due to a slow or bad network connection. Possible fixes:\\n\"+\n \"

\\n\"+\n \"
    \\n\"+\n \"
  • re-rerun `output_notebook()` to attempt to load from CDN again, or
  • \\n\"+\n \"
  • use INLINE resources instead, as so:
  • \\n\"+\n \"
\\n\"+\n \"\\n\"+\n \"from bokeh.resources import INLINE\\n\"+\n \"output_notebook(resources=INLINE)\\n\"+\n \"\\n\"+\n \"
\"}};\n\n function display_loaded() {\n var el = document.getElementById(\"1001\");\n if (el != null) {\n el.textContent = \"BokehJS is loading...\";\n }\n if (root.Bokeh !== undefined) {\n if (el != null) {\n el.textContent = \"BokehJS \" + root.Bokeh.version + \" successfully loaded.\";\n }\n } else if (Date.now() < root._bokeh_timeout) {\n setTimeout(display_loaded, 100)\n }\n }\n\n\n function run_callbacks() {\n try {\n root._bokeh_onload_callbacks.forEach(function(callback) {\n if (callback != null)\n callback();\n });\n } finally {\n delete root._bokeh_onload_callbacks\n }\n console.debug(\"Bokeh: all callbacks have finished\");\n }\n\n function load_libs(css_urls, js_urls, callback) {\n if (css_urls == null) css_urls = [];\n if (js_urls == null) js_urls = [];\n\n root._bokeh_onload_callbacks.push(callback);\n if (root._bokeh_is_loading > 0) {\n console.debug(\"Bokeh: BokehJS is being loaded, scheduling callback at\", now());\n return null;\n }\n if (js_urls == null || js_urls.length === 0) {\n run_callbacks();\n return null;\n }\n console.debug(\"Bokeh: BokehJS not loaded, scheduling load and callback at\", now());\n root._bokeh_is_loading = css_urls.length + js_urls.length;\n\n function on_load() {\n root._bokeh_is_loading--;\n if (root._bokeh_is_loading === 0) {\n console.debug(\"Bokeh: all BokehJS libraries/stylesheets loaded\");\n run_callbacks()\n }\n }\n\n function on_error() {\n console.error(\"failed to load \" + url);\n }\n\n for (var i = 0; i < css_urls.length; i++) {\n var url = css_urls[i];\n const element = document.createElement(\"link\");\n element.onload = on_load;\n element.onerror = on_error;\n element.rel = \"stylesheet\";\n element.type = \"text/css\";\n element.href = url;\n console.debug(\"Bokeh: injecting link tag for BokehJS stylesheet: \", url);\n document.body.appendChild(element);\n }\n\n for (var i = 0; i < js_urls.length; i++) {\n var url = js_urls[i];\n var element = document.createElement('script');\n element.onload = on_load;\n element.onerror = on_error;\n element.async = false;\n element.src = url;\n console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n document.head.appendChild(element);\n }\n };var element = document.getElementById(\"1001\");\n if (element == null) {\n console.error(\"Bokeh: ERROR: autoload.js configured with elementid '1001' but no matching script tag was found. \")\n return false;\n }\n\n function inject_raw_css(css) {\n const element = document.createElement(\"style\");\n element.appendChild(document.createTextNode(css));\n document.body.appendChild(element);\n }\n\n \n var js_urls = [\"https://cdn.pydata.org/bokeh/release/bokeh-1.4.0.min.js\", \"https://cdn.pydata.org/bokeh/release/bokeh-widgets-1.4.0.min.js\", \"https://cdn.pydata.org/bokeh/release/bokeh-tables-1.4.0.min.js\", \"https://cdn.pydata.org/bokeh/release/bokeh-gl-1.4.0.min.js\"];\n var css_urls = [];\n \n\n var inline_js = [\n function(Bokeh) {\n Bokeh.set_log_level(\"info\");\n },\n function(Bokeh) {\n \n \n }\n ];\n\n function run_inline_js() {\n \n if (root.Bokeh !== undefined || force === true) {\n \n for (var i = 0; i < inline_js.length; i++) {\n inline_js[i].call(root, root.Bokeh);\n }\n if (force === true) {\n display_loaded();\n }} else if (Date.now() < root._bokeh_timeout) {\n setTimeout(run_inline_js, 100);\n } else if (!root._bokeh_failed_load) {\n console.log(\"Bokeh: BokehJS failed to load within specified timeout.\");\n root._bokeh_failed_load = true;\n } else if (force !== true) {\n var cell = $(document.getElementById(\"1001\")).parents('.cell').data().cell;\n cell.output_area.append_execute_result(NB_LOAD_WARNING)\n }\n\n }\n\n if (root._bokeh_is_loading === 0) {\n console.debug(\"Bokeh: BokehJS loaded, going straight to plotting\");\n run_inline_js();\n } else {\n load_libs(css_urls, js_urls, function() {\n console.debug(\"Bokeh: BokehJS plotting callback run at\", now());\n run_inline_js();\n });\n }\n}(window));" + }, + "metadata": {} + }, + { + "output_type": "stream", + "name": "stderr", + "text": "D:\\anaconda3\\lib\\site-packages\\bokeh\\models\\graphs.py:164: UserWarning: Node keys in 'layout_function' don't match node keys in the graph. These nodes may not be displayed correctly.\n warn(\"Node keys in 'layout_function' don't match node keys in the graph. \"\n" + }, + { + "output_type": "display_data", + "data": { + "text/html": "\n\n\n\n\n\n
\n" + }, + "metadata": {} + }, + { + "output_type": "display_data", + "data": { + "application/javascript": "(function(root) {\n function embed_document(root) {\n \n var docs_json = {\"df083da7-2a52-4c4c-a210-d31408d268ad\":{\"roots\":{\"references\":[{\"attributes\":{\"plot_height\":500,\"plot_width\":500,\"renderers\":[{\"id\":\"1041\",\"type\":\"GraphRenderer\"},{\"id\":\"1009\",\"type\":\"GraphRenderer\"},{\"id\":\"1025\",\"type\":\"GraphRenderer\"}],\"title\":{\"id\":\"1136\",\"type\":\"Title\"},\"toolbar\":{\"id\":\"1122\",\"type\":\"Toolbar\"},\"x_range\":{\"id\":\"1083\",\"type\":\"Range1d\"},\"x_scale\":{\"id\":\"1135\",\"type\":\"LinearScale\"},\"y_range\":{\"id\":\"1084\",\"type\":\"Range1d\"},\"y_scale\":{\"id\":\"1133\",\"type\":\"LinearScale\"}},\"id\":\"1004\",\"type\":\"Plot\"},{\"attributes\":{\"data_source\":{\"id\":\"1027\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"1100\",\"type\":\"Circle\"},\"hover_glyph\":{\"id\":\"1110\",\"type\":\"Circle\"},\"muted_glyph\":null,\"selection_glyph\":{\"id\":\"1105\",\"type\":\"Circle\"},\"view\":{\"id\":\"1029\",\"type\":\"CDSView\"}},\"id\":\"1028\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"fill_color\":{\"value\":\"#2b83ba\"},\"size\":{\"units\":\"screen\",\"value\":8}},\"id\":\"1085\",\"type\":\"Square\"},{\"attributes\":{\"edge_renderer\":{\"id\":\"1048\",\"type\":\"GlyphRenderer\"},\"inspection_policy\":{\"id\":\"1131\",\"type\":\"EdgesAndLinkedNodes\"},\"layout_provider\":{\"id\":\"1054\",\"type\":\"StaticLayoutProvider\"},\"node_renderer\":{\"id\":\"1044\",\"type\":\"GlyphRenderer\"},\"selection_policy\":{\"id\":\"1129\",\"type\":\"NodesAndLinkedEdges\"}},\"id\":\"1041\",\"type\":\"GraphRenderer\"},{\"attributes\":{\"data_source\":{\"id\":\"1031\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"1030\",\"type\":\"MultiLine\"},\"hover_glyph\":null,\"muted_glyph\":null,\"view\":{\"id\":\"1033\",\"type\":\"CDSView\"}},\"id\":\"1032\",\"type\":\"GlyphRenderer\"},{\"attributes\":{},\"id\":\"1177\",\"type\":\"Selection\"},{\"attributes\":{},\"id\":\"1172\",\"type\":\"UnionRenderers\"},{\"attributes\":{\"callback\":null,\"end\":123.14760523297373,\"start\":-196.4808253550434},\"id\":\"1083\",\"type\":\"Range1d\"},{\"attributes\":{},\"id\":\"1150\",\"type\":\"NodesOnly\"},{\"attributes\":{\"fill_color\":{\"value\":\"#fdae61\"},\"size\":{\"units\":\"screen\",\"value\":15}},\"id\":\"1105\",\"type\":\"Circle\"},{\"attributes\":{\"callback\":null,\"renderers\":[{\"id\":\"1041\",\"type\":\"GraphRenderer\"}],\"tooltips\":null},\"id\":\"1115\",\"type\":\"HoverTool\"},{\"attributes\":{\"line_color\":{\"value\":\"#fdae61\"},\"line_join\":\"round\",\"line_width\":{\"value\":5}},\"id\":\"1065\",\"type\":\"MultiLine\"},{\"attributes\":{\"data_source\":{\"id\":\"1011\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"1085\",\"type\":\"Square\"},\"hover_glyph\":{\"id\":\"1095\",\"type\":\"Square\"},\"muted_glyph\":null,\"selection_glyph\":{\"id\":\"1090\",\"type\":\"Square\"},\"view\":{\"id\":\"1013\",\"type\":\"CDSView\"}},\"id\":\"1012\",\"type\":\"GlyphRenderer\"},{\"attributes\":{},\"id\":\"1131\",\"type\":\"EdgesAndLinkedNodes\"},{\"attributes\":{\"callback\":null,\"data\":{\"color\":[\"purple\",\"grey\",\"grey\",\"grey\",\"green\",\"grey\",\"green\",\"white\",\"red\",\"green\",\"orange\",\"green\",\"grey\",\"orange\",\"grey\",\"white\",\"lightgreen\",\"blue\",\"blue\",\"blue\",\"blue\",\"blue\",\"blue\",\"blue\",\"blue\",\"blue\",\"blue\",\"blue\"],\"index\":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27],\"k\":[null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,\"100\",\"0.05\",\"100\",\"100\",\"0.05\",\"100\",\"0.2\",\"100\",\"0.05\",\"100\",\"0.2\"],\"k_r\":[null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,\"10\",\"None\",\"10\",\"10\",\"None\",\"10\",\"None\",\"10\",\"None\",\"10\",\"None\"],\"species\":[\"nothing\",\"ordered_polymer[complex[protein[Ribo]:rna[UTR1]-forward]:rna[RFP-forward]:rna[t16-forward]]\",\"ordered_polymer[[dna[ptet]:2x_protein[tetr]-forward]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]]\",\"ordered_polymer[complex[dna[ptet]:protein[RNAP]-forward]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]]\",\"protein[RNAase]\",\"ordered_polymer[dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:complex[dna[pconst]:protein[RNAP]-reverse]]\",\"protein[RNAP]\",\"dna[dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:dna[pconst-reverse]]\",\"protein[RFP]\",\"protein[tetr]\",\"rna[rna[UTR1-forward]:rna[GFP-forward]:rna[t16-forward]]\",\"protein[Ribo]\",\"ordered_polymer[complex[protein[Ribo]:rna[UTR1]-forward]:rna[GFP-forward]:rna[t16-forward]]\",\"rna[rna[UTR1-forward]:rna[RFP-forward]:rna[t16-forward]]\",\"ordered_polymer[complex[[dna[ptet]:2x_protein[tetr]]:protein[RNAP]-forward]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]]\",\"dna[dna[ptet-forward]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]]\",\"protein[GFP]\",\"dna[dna[ptet-forward]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]]+protein[RNAP] <--> ordered_polymer[complex[dna[ptet]:protein[RNAP]-forward]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]]\\n Kf=k_forward * dna_ptet_f_UTR1_f_GFP_f_t16_f * protein_RNAP\\n Kr=k_reverse * ordered_polymer_dna_ptet_protein_RNAP_f_UTR1_f_GFP_f_t16_f\\n k_forward=100\\n found_key=(mech=None, partid=None, name=kb).\\n search_key=(mech=transcription_mm, partid=ptet_leak, name=kb).\\n k_reverse=10\\n found_key=(mech=None, partid=None, name=ku).\\n search_key=(mech=transcription_mm, partid=ptet_leak, name=ku).\\n\",\"ordered_polymer[complex[dna[ptet]:protein[RNAP]-forward]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]] --> dna[dna[ptet-forward]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]]+rna[rna[UTR1-forward]:rna[GFP-forward]:rna[t16-forward]]+protein[RNAP]\\n Kf=k_forward * ordered_polymer_dna_ptet_protein_RNAP_f_UTR1_f_GFP_f_t16_f\\n k_forward=0.05\\n found_key=(mech=None, partid=None, name=ktx).\\n search_key=(mech=transcription_mm, partid=ptet_leak, name=ktx).\\n\",\"2protein[tetr]+dna[dna[ptet-forward]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]] <--> ordered_polymer[[dna[ptet]:2x_protein[tetr]-forward]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]]\\n Kf=k_forward * protein_tetr^2 * dna_ptet_f_UTR1_f_GFP_f_t16_f\\n Kr=k_reverse * ordered_polymer_dna_ptet_protein_tetr_2x_f_UTR1_f_GFP_f_t16_f\\n k_forward=100\\n found_key=(mech=None, partid=None, name=kb).\\n search_key=(mech=one_step_cooperative_binding, partid=ptet_tetr, name=kb).\\n k_reverse=10\\n found_key=(mech=None, partid=None, name=ku).\\n search_key=(mech=one_step_cooperative_binding, partid=ptet_tetr, name=ku).\\n\",\"ordered_polymer[[dna[ptet]:2x_protein[tetr]-forward]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]]+protein[RNAP] <--> ordered_polymer[complex[[dna[ptet]:2x_protein[tetr]]:protein[RNAP]-forward]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]]\\n Kf=k_forward * ordered_polymer_dna_ptet_protein_tetr_2x_f_UTR1_f_GFP_f_t16_f * protein_RNAP\\n Kr=k_reverse * ordered_polymer_dna_ptet_protein_tetr_2x_protein_RNAP_f_UTR1_f_GFP_f_t16_f\\n k_forward=100\\n found_key=(mech=None, partid=None, name=kb).\\n search_key=(mech=transcription_mm, partid=ptet_tetr, name=kb).\\n k_reverse=10\\n found_key=(mech=None, partid=None, name=ku).\\n search_key=(mech=transcription_mm, partid=ptet_tetr, name=ku).\\n\",\"ordered_polymer[complex[[dna[ptet]:2x_protein[tetr]]:protein[RNAP]-forward]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]] --> ordered_polymer[[dna[ptet]:2x_protein[tetr]-forward]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]]+rna[rna[UTR1-forward]:rna[GFP-forward]:rna[t16-forward]]+protein[RNAP]\\n Kf=k_forward * ordered_polymer_dna_ptet_protein_tetr_2x_protein_RNAP_f_UTR1_f_GFP_f_t16_f\\n k_forward=0.05\\n found_key=(mech=None, partid=None, name=ktx).\\n search_key=(mech=transcription_mm, partid=ptet_tetr, name=ktx).\\n\",\"rna[rna[UTR1-forward]:rna[GFP-forward]:rna[t16-forward]]+protein[Ribo] <--> ordered_polymer[complex[protein[Ribo]:rna[UTR1]-forward]:rna[GFP-forward]:rna[t16-forward]]\\n Kf=k_forward * rna_UTR1_f_GFP_f_t16_f * protein_Ribo\\n Kr=k_reverse * ordered_polymer_protein_Ribo_rna_UTR1_f_GFP_f_t16_f\\n k_forward=100\\n found_key=(mech=None, partid=None, name=kb).\\n search_key=(mech=translation_mm, partid=UTR1, name=kb).\\n k_reverse=10\\n found_key=(mech=None, partid=None, name=ku).\\n search_key=(mech=translation_mm, partid=UTR1, name=ku).\\n\",\"ordered_polymer[complex[protein[Ribo]:rna[UTR1]-forward]:rna[GFP-forward]:rna[t16-forward]] --> rna[rna[UTR1-forward]:rna[GFP-forward]:rna[t16-forward]]+protein[GFP]+protein[Ribo]\\n Kf=k_forward * ordered_polymer_protein_Ribo_rna_UTR1_f_GFP_f_t16_f\\n k_forward=0.2\\n found_key=(mech=None, partid=None, name=ktl).\\n search_key=(mech=translation_mm, partid=UTR1, name=ktl).\\n\",\"dna[dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:dna[pconst-reverse]]+protein[RNAP] <--> ordered_polymer[dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:complex[dna[pconst]:protein[RNAP]-reverse]]\\n Kf=k_forward * dna_t16_r_RFP_r_UTR1_r_pconst_r * protein_RNAP\\n Kr=k_reverse * ordered_polymer_t16_r_RFP_r_UTR1_r_dna_pconst_protein_RNAP_r\\n k_forward=100\\n found_key=(mech=None, partid=None, name=kb).\\n search_key=(mech=transcription_mm, partid=pconst, name=kb).\\n k_reverse=10\\n found_key=(mech=None, partid=None, name=ku).\\n search_key=(mech=transcription_mm, partid=pconst, name=ku).\\n\",\"ordered_polymer[dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:complex[dna[pconst]:protein[RNAP]-reverse]] --> dna[dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:dna[pconst-reverse]]+rna[rna[UTR1-forward]:rna[RFP-forward]:rna[t16-forward]]+protein[RNAP]\\n Kf=k_forward * ordered_polymer_t16_r_RFP_r_UTR1_r_dna_pconst_protein_RNAP_r\\n k_forward=0.05\\n found_key=(mech=None, partid=None, name=ktx).\\n search_key=(mech=transcription_mm, partid=pconst, name=ktx).\\n\",\"rna[rna[UTR1-forward]:rna[RFP-forward]:rna[t16-forward]]+protein[Ribo] <--> ordered_polymer[complex[protein[Ribo]:rna[UTR1]-forward]:rna[RFP-forward]:rna[t16-forward]]\\n Kf=k_forward * rna_UTR1_f_RFP_f_t16_f * protein_Ribo\\n Kr=k_reverse * ordered_polymer_protein_Ribo_rna_UTR1_f_RFP_f_t16_f\\n k_forward=100\\n found_key=(mech=None, partid=None, name=kb).\\n search_key=(mech=translation_mm, partid=UTR1, name=kb).\\n k_reverse=10\\n found_key=(mech=None, partid=None, name=ku).\\n search_key=(mech=translation_mm, partid=UTR1, name=ku).\\n\",\"ordered_polymer[complex[protein[Ribo]:rna[UTR1]-forward]:rna[RFP-forward]:rna[t16-forward]] --> rna[rna[UTR1-forward]:rna[RFP-forward]:rna[t16-forward]]+protein[RFP]+protein[Ribo]\\n Kf=k_forward * ordered_polymer_protein_Ribo_rna_UTR1_f_RFP_f_t16_f\\n k_forward=0.2\\n found_key=(mech=None, partid=None, name=ktl).\\n search_key=(mech=translation_mm, partid=UTR1, name=ktl).\\n\"],\"type\":[\"nothing\",\"ordered_polymer\",\"ordered_polymer\",\"ordered_polymer\",\"protein\",\"ordered_polymer\",\"protein\",\"dna\",\"protein\",\"protein\",\"rna\",\"protein\",\"ordered_polymer\",\"rna\",\"ordered_polymer\",\"dna\",\"protein\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\"]},\"selected\":{\"id\":\"1167\",\"type\":\"Selection\"},\"selection_policy\":{\"id\":\"1166\",\"type\":\"UnionRenderers\"}},\"id\":\"1043\",\"type\":\"ColumnDataSource\"},{\"attributes\":{\"bottom_units\":\"screen\",\"fill_alpha\":{\"value\":0.5},\"fill_color\":{\"value\":\"lightgrey\"},\"left_units\":\"screen\",\"level\":\"overlay\",\"line_alpha\":{\"value\":1.0},\"line_color\":{\"value\":\"black\"},\"line_dash\":[4,4],\"line_width\":{\"value\":2},\"render_mode\":\"css\",\"right_units\":\"screen\",\"top_units\":\"screen\"},\"id\":\"1165\",\"type\":\"BoxAnnotation\"},{\"attributes\":{\"callback\":null,\"end\":204.24146228842204,\"start\":-115.3869682995951},\"id\":\"1084\",\"type\":\"Range1d\"},{\"attributes\":{\"callback\":null,\"data\":{\"end\":[],\"start\":[]},\"selected\":{\"id\":\"1173\",\"type\":\"Selection\"},\"selection_policy\":{\"id\":\"1172\",\"type\":\"UnionRenderers\"}},\"id\":\"1015\",\"type\":\"ColumnDataSource\"},{\"attributes\":{\"fill_color\":{\"value\":\"#abdda4\"},\"size\":{\"units\":\"screen\",\"value\":15}},\"id\":\"1110\",\"type\":\"Circle\"},{\"attributes\":{},\"id\":\"1173\",\"type\":\"Selection\"},{\"attributes\":{\"data_source\":{\"id\":\"1043\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"1055\",\"type\":\"Circle\"},\"hover_glyph\":null,\"muted_glyph\":null,\"view\":{\"id\":\"1045\",\"type\":\"CDSView\"}},\"id\":\"1044\",\"type\":\"GlyphRenderer\"},{\"attributes\":{},\"id\":\"1159\",\"type\":\"NodesOnly\"},{\"attributes\":{\"line_color\":{\"value\":\"#abdda4\"},\"line_join\":\"round\",\"line_width\":{\"value\":5}},\"id\":\"1070\",\"type\":\"MultiLine\"},{\"attributes\":{\"callback\":null,\"data\":{\"end\":[],\"start\":[]},\"selected\":{\"id\":\"1177\",\"type\":\"Selection\"},\"selection_policy\":{\"id\":\"1176\",\"type\":\"UnionRenderers\"}},\"id\":\"1031\",\"type\":\"ColumnDataSource\"},{\"attributes\":{\"data_source\":{\"id\":\"1015\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"1014\",\"type\":\"MultiLine\"},\"hover_glyph\":null,\"muted_glyph\":null,\"view\":{\"id\":\"1017\",\"type\":\"CDSView\"}},\"id\":\"1016\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"attachment\":\"right\",\"callback\":null,\"renderers\":[{\"id\":\"1009\",\"type\":\"GraphRenderer\"}],\"tooltips\":[[\"reaction\",\"@species\"],[\"type\",\"@type\"],[\"k_f\",\"@k\"],[\"k_r\",\"@k_r\"]]},\"id\":\"1117\",\"type\":\"HoverTool\"},{\"attributes\":{\"source\":{\"id\":\"1043\",\"type\":\"ColumnDataSource\"}},\"id\":\"1045\",\"type\":\"CDSView\"},{\"attributes\":{\"source\":{\"id\":\"1011\",\"type\":\"ColumnDataSource\"}},\"id\":\"1013\",\"type\":\"CDSView\"},{\"attributes\":{},\"id\":\"1030\",\"type\":\"MultiLine\"},{\"attributes\":{},\"id\":\"1166\",\"type\":\"UnionRenderers\"},{\"attributes\":{},\"id\":\"1171\",\"type\":\"Selection\"},{\"attributes\":{\"edge_renderer\":{\"id\":\"1032\",\"type\":\"GlyphRenderer\"},\"inspection_policy\":{\"id\":\"1159\",\"type\":\"NodesOnly\"},\"layout_provider\":{\"id\":\"1038\",\"type\":\"StaticLayoutProvider\"},\"node_renderer\":{\"id\":\"1028\",\"type\":\"GlyphRenderer\"},\"selection_policy\":{\"id\":\"1160\",\"type\":\"NodesOnly\"}},\"id\":\"1025\",\"type\":\"GraphRenderer\"},{\"attributes\":{},\"id\":\"1133\",\"type\":\"LinearScale\"},{\"attributes\":{},\"id\":\"1168\",\"type\":\"UnionRenderers\"},{\"attributes\":{},\"id\":\"1160\",\"type\":\"NodesOnly\"},{\"attributes\":{\"text\":\"\"},\"id\":\"1136\",\"type\":\"Title\"},{\"attributes\":{\"callback\":null,\"overlay\":{\"id\":\"1165\",\"type\":\"BoxAnnotation\"}},\"id\":\"1119\",\"type\":\"BoxSelectTool\"},{\"attributes\":{\"source\":{\"id\":\"1015\",\"type\":\"ColumnDataSource\"}},\"id\":\"1017\",\"type\":\"CDSView\"},{\"attributes\":{\"attachment\":\"right\",\"callback\":null,\"renderers\":[{\"id\":\"1025\",\"type\":\"GraphRenderer\"}],\"tooltips\":[[\"name\",\"@species\"],[\"type\",\"@type\"]]},\"id\":\"1116\",\"type\":\"HoverTool\"},{\"attributes\":{\"callback\":null,\"data\":{\"end\":[26,27,19,20,17,18,24,25,17,20,24,24,19,22,22,26,22,23,26,20,21,17,19,15,6,3,15,10,6,9,15,2,2,6,14,2,10,6,10,11,12,10,16,11,7,6,5,7,13,6,13,11,1,13,8,11],\"start\":[1,1,2,2,3,3,5,5,6,6,6,7,9,10,11,11,12,12,13,14,14,15,15,17,17,17,18,18,18,19,19,19,20,20,20,21,21,21,22,22,22,23,23,23,24,24,24,25,25,25,26,26,26,27,27,27],\"weight\":[1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1],\"xs\":[[-11.89522601096093,-3.3234285231042198,-4.469877185083626,0.14718314441926156,-3.8232932996378715,-3.3234285231042198],[-11.89522601096093,-19.186973279496844,-17.962785747711873,-22.64073464551613,-18.772840453086253,-19.186973279496844],[1.2800142819200682,-5.04446845339734,-6.337724911381675,-7.396780225787725,-2.63537339016157,-5.04446845339734],[1.2800142819200682,11.614126042808676,11.589172235373875,14.946092667408605,10.058533838113545,11.614126042808676],[5.362376885529334,5.3519109258513,7.852716831162404,5.348508068168215,2.852719194314068,5.3519109258513],[5.362376885529334,5.735844983600691,3.1893749737659958,5.9518691887886765,8.17984211945382,5.735844983600691],[3.7850159419912757,4.8174936606569005,2.2363457374757303,5.234833175270173,7.200673122612728,4.8174936606569005],[3.7850159419912757,3.3100461114635666,5.858521385908957,3.083574335094869,0.8689996030678673,3.3100461114635666],[6.8032987752017995,5.539195458288513,3.088135664120079,5.348508068168215,8.080709398003584,5.539195458288513],[6.8032987752017995,12.440792390853298,10.100824235895349,14.946092667408605,13.592350574335931,12.440792390853298],[6.8032987752017995,5.513270459120904,8.07138646942879,5.234833175270173,3.08723348447005,5.513270459120904],[10.049649863022143,8.294199352369498,7.805472975365131,5.234833175270173,10.23416145759492,8.294199352369498],[-14.105474786929317,-10.844463242341483,-11.23154281187581,-7.396780225787725,-12.092820715504557,-10.844463242341483],[30.954792338955897,30.57339320297138,33.164330799974195,30.088213885352243,28.2126044405845,30.57339320297138],[13.707254782839785,26.702597984199876,25.265692553194082,30.088213885352243,26.53350842364042,26.702597984199876],[13.707254782839785,3.537416487245969,4.962698704346631,0.14718314441926156,3.7203195834775107,3.537416487245969],[46.19400639623356,33.58654247870979,34.33902099310128,30.088213885352243,34.493525156554966,33.58654247870979],[46.19400639623356,54.32562318515069,53.393609766602175,57.82267527927593,53.5987809294639,54.32562318515069],[-1.2585990671302145,-0.7473404772766363,-3.376473808249645,0.14718314441926156,1.4574681523055728,-0.7473404772766363],[33.14736664748288,18.445542648405844,19.231219926909244,14.946092667408605,19.319858501669625,18.445542648405844],[33.14736664748288,44.36334753146113,43.8144117020661,47.84193533719448,43.262186375008994,44.36334753146113],[-1.6491455633414476,2.086660729022064,2.2194445758724517,5.348508068168215,0.40659253484328417,2.086660729022064],[-1.6491455633414476,-5.265488784258045,-2.776950970874144,-7.396780225787725,-6.74303082003542,-5.265488784258045],[5.348508068168215,1.612701775804704,1.4799179289543156,-1.6491455633414476,3.2927699699834823,1.612701775804704],[5.348508068168215,6.612611385081501,9.063671179249933,6.8032987752017995,4.07109744536643,6.612611385081501],[5.348508068168215,5.358974027846249,2.858168122535145,5.362376885529334,7.858165759383481,5.358974027846249],[5.9518691887886765,-0.4616905673993901,2.1716690181995317,-1.6491455633414476,-2.5317710239207996,-0.4616905673993901],[5.9518691887886765,30.039082865730553,27.408975923917613,30.954792338955897,32.23481542171071,30.039082865730553],[5.9518691887886765,6.74425033660066,9.22988946534504,6.8032987752017995,4.230601091108866,6.74425033660066],[-7.396780225787725,-10.657791770375558,-10.270712200841231,-14.105474786929317,-9.409434297212487,-10.657791770375558],[-7.396780225787725,-3.7804370048711284,-6.268974818255028,-1.6491455633414476,-2.302894969093753,-3.7804370048711284],[-7.396780225787725,-1.0722974904703166,0.22095896751401733,1.2800142819200682,-3.481392553706087,-1.0722974904703166],[14.946092667408605,4.611980906519996,4.636934713954798,1.2800142819200682,6.167573111215128,4.611980906519996],[14.946092667408605,9.308599051757106,11.648567206715054,6.8032987752017995,8.157040868274473,9.308599051757106],[14.946092667408605,29.647916666485642,28.862239387982243,33.14736664748288,28.77360081322186,29.647916666485642],[47.84193533719448,4.747911471368122,5.232597370884104,1.2800142819200682,5.9082513751693755,4.747911471368122],[47.84193533719448,31.383874229186702,29.004501495330988,30.954792338955897,33.966785517562876,31.383874229186702],[47.84193533719448,10.2666241271472,11.449016181341714,6.8032987752017995,10.727089187220166,10.2666241271472],[30.088213885352243,30.46961302133676,27.878675424333945,30.954792338955897,32.830401783723644,30.46961302133676],[30.088213885352243,17.092870683992153,18.529776114997947,13.707254782839785,17.26196024455161,17.092870683992153],[30.088213885352243,42.69567780287601,41.94319928848452,46.19400639623356,41.78869512503084,42.69567780287601],[57.82267527927593,34.364853806278965,34.6105489030329,30.954792338955897,35.736749658216645,34.364853806278965],[57.82267527927593,-128.9831303054886,-126.50785354100627,-131.1558954013456,-130.42773792034697,-128.9831303054886],[57.82267527927593,17.190946801475036,18.258260054052087,13.707254782839785,17.776151760482396,17.190946801475036],[5.234833175270173,6.990283685922819,7.479010062927185,10.049649863022143,5.050321580697395,6.990283685922819],[5.234833175270173,6.524861491351067,3.9667454810431826,6.8032987752017995,8.950898466001924,6.524861491351067],[5.234833175270173,4.202355456604547,6.783503379785717,3.7850159419912757,1.8191759946487207,4.202355456604547],[3.083574335094869,8.909316594529525,6.275264727704823,10.049649863022143,11.00244191463904,8.909316594529525],[3.083574335094869,-1.167055770339056,-3.644488342963757,-1.2585990671302145,1.3538011246099613,-1.167055770339056],[3.083574335094869,6.498442201507992,3.9356380561122455,6.8032987752017995,8.916635101921297,6.498442201507992],[0.14718314441926156,-0.36407544543431636,2.265057885538693,-1.2585990671302145,-2.568884075016525,-0.36407544543431636],[0.14718314441926156,10.317021440013077,8.891739222912415,13.707254782839785,10.134118343781534,10.317021440013077],[0.14718314441926156,-8.424614343437447,-7.278165681458042,-11.89522601096093,-7.924749566903797,-8.424614343437447],[-22.64073464551613,-4.743643109806129,-5.33935493712398,-1.2585990671302145,-5.801090837893482,-4.743643109806129],[-22.64073464551613,50.692765513769466,52.90548495698756,51.56862724048126,48.064573793875205,50.692765513769466],[-22.64073464551613,10.267165475346866,8.990666339054464,13.707254782839785,9.911829707836292,10.267165475346866]],\"ys\":[[-92.2429232861185,-93.3607868384632,-95.73244582174691,-93.81339555827523,-90.77442915385622,-93.3607868384632],[-92.2429232861185,-91.04576474170511,-88.71328199695289,-90.47872644794305,-93.64722680555187,-91.04576474170511],[22.581579997071117,15.613617252674027,17.908524353501086,13.021971187819954,14.548078964371966,15.613617252674027],[22.581579997071117,25.90467804439518,23.270577026013548,26.97612492247741,28.030529346870587,25.90467804439518],[-6.007338556858005,4.757390671271189,3.9296946573229787,8.257389017065025,3.924833432061429,4.757390671271189],[-6.007338556858005,-12.046690444467213,-11.37244912523712,-15.54001744644869,-11.063843117825712,-12.046690444467213],[66.64535349915812,58.048299868505396,58.57440467384572,54.573270698909496,59.170603980436105,58.048299868505396],[66.64535349915812,73.97037495448738,73.30375314034902,77.46304020247615,72.98022203125088,73.97037495448738],[34.9199014535514,11.75219063078348,12.717289979532426,8.257389017065025,12.444879422217713,11.75219063078348],[34.9199014535514,29.420193359385816,28.210375232009916,26.97612492247741,31.789375627088923,29.420193359385816],[34.9199014535514,51.08436360943838,50.45575137176628,54.573270698909496,50.057983823408094,51.08436360943838],[57.248851982636275,56.27335263647035,58.86183817747011,54.573270698909496,54.49131506732822,56.27335263647035],[11.848825265769133,12.41907665527983,9.813451917449427,13.021971187819954,14.738713369669082,12.41907665527983],[-107.77676757130897,-105.05198343364329,-105.52753914644877,-101.5857749820705,-106.22065245733326,-105.05198343364329],[-97.2918360442955,-100.69830387275807,-102.90611130319459,-101.5857749820705,-98.06951715869121,-100.69830387275807],[-97.2918360442955,-94.68306094288361,-92.46773219320305,-93.81339555827523,-97.31092268295549,-94.68306094288361],[-101.0878548031702,-101.47762206765293,-98.95316431341662,-101.5857749820705,-103.95077658964168,-101.47762206765293],[-101.0878548031702,-101.42181073500535,-103.8856414627929,-101.56543054900855,-98.88985275689971,-101.42181073500535],[-88.49567267371968,-90.42963618588658,-90.26602446408336,-93.81339555827523,-88.98813357594636,-90.42963618588658],[27.29884263389619,27.038171924809678,29.55249530925889,26.97612492247741,24.553281050691407,27.038171924809678],[27.29884263389619,28.545217410234706,25.968828401806235,28.93177513917468,30.938239552853876,28.545217410234706],[5.535006101948979,6.988392588344608,4.3575221396983315,8.257389017065025,9.01730405276426,6.988392588344608],[5.535006101948979,10.245715293407061,11.10959631467279,13.021971187819954,8.064894255344676,10.245715293407061],[8.257389017065025,6.804002530669396,9.434872979315672,5.535006101948979,4.775091066249742,6.804002530669396],[8.257389017065025,31.425099839832942,30.460000491083996,34.9199014535514,30.732411048398706,31.425099839832942],[8.257389017065025,-2.507340211064169,-1.6796441971159588,-6.007338556858005,-1.6747829718544098,-2.507340211064169],[-15.54001744644869,2.2425980724647463,2.3098896802544333,5.535006101948979,0.6135254003372088,2.2425980724647463],[-15.54001744644869,-104.3986799228538,-104.25154616679477,-107.77676757130897,-102.94338977647284,-104.3986799228538],[-15.54001744644869,31.420399591586072,30.54821326447499,34.9199014535514,30.632568176762334,31.420399591586072],[13.021971187819954,12.451719798309254,15.05734453613966,11.848825265769133,10.132083083920003,12.451719798309254],[13.021971187819954,8.311261996361873,7.447380975096142,5.535006101948979,10.492083034424258,8.311261996361873],[13.021971187819954,19.989933932217042,17.695026831389985,22.581579997071117,21.055472220519103,19.989933932217042],[26.97612492247741,23.653026875153348,26.28712789353498,22.581579997071117,21.52717557267794,23.653026875153348],[26.97612492247741,32.47583301664299,33.68565114401889,34.9199014535514,30.106650748939884,32.47583301664299],[26.97612492247741,27.236795631563922,24.72247224711471,27.29884263389619,29.721686505682193,27.236795631563922],[28.93177513917468,23.054537800070808,25.643782949985166,22.581579997071117,20.689644107916518,23.054537800070808],[28.93177513917468,-104.30316875574664,-103.17281648281195,-107.77676757130897,-103.7857906117131,-104.30316875574664],[28.93177513917468,34.41455255766631,36.76849815978254,34.9199014535514,31.820890514146253,34.41455255766631],[-101.5857749820705,-104.31055911973618,-103.8350034069307,-107.77676757130897,-103.14189009604621,-104.31055911973618],[-101.5857749820705,-98.17930715360794,-95.9714997231714,-97.2918360442955,-100.8080938676748,-98.17930715360794],[-101.5857749820705,-101.19600771758778,-103.72046547182408,-101.0878548031702,-98.72285319559903,-101.19600771758778],[-101.56543054900855,-106.98842704268034,-104.36569091661357,-107.77676757130897,-109.23720729850368,-106.98842704268034],[-101.56543054900855,134.34594913704106,135.24712381864197,137.08986820257954,132.14317368170342,134.34594913704106],[-101.56543054900855,-97.62931184979428,-95.22100263201969,-97.2918360442955,-100.19770551578434,-97.62931184979428],[54.573270698909496,55.54877004507542,52.96028450407566,57.248851982636275,57.33080761421755,55.54877004507542],[54.573270698909496,38.408808543022516,39.03742078069461,34.9199014535514,39.4351883290528,38.408808543022516],[54.573270698909496,63.17032432956222,62.644219524221896,66.64535349915812,62.04802021763151,63.17032432956222],[77.46304020247615,60.55787601349023,60.52818375150255,57.248851982636275,62.15723127792058,60.55787601349023],[77.46304020247615,-84.99687004641808,-84.1016389501961,-88.49567267371968,-84.23241508846918,-84.99687004641808],[77.46304020247615,38.40659938561773,39.0158167359017,34.9199014535514,39.45132612689285,38.40659938561773],[-93.81339555827523,-91.87943204610833,-92.04304376791156,-88.49567267371968,-93.32093465604855,-91.87943204610833],[-93.81339555827523,-96.42217065968711,-98.63749940936768,-97.2918360442955,-93.79430891961523,-96.42217065968711],[-93.81339555827523,-92.69553200593053,-90.32387302264682,-92.2429232861185,-95.28188969053751,-92.69553200593053],[-90.47872644794305,-88.81888780425834,-91.3848648669653,-88.49567267371968,-86.40623052028542,-88.81888780425834],[-90.47872644794305,193.24262374595725,191.81329399633708,196.6312615601359,193.06452503449677,193.24262374595725],[-90.47872644794305,-96.64702168614821,-98.951291814104,-97.2918360442955,-94.03687851768555,-96.64702168614821]]},\"selected\":{\"id\":\"1169\",\"type\":\"Selection\"},\"selection_policy\":{\"id\":\"1168\",\"type\":\"UnionRenderers\"}},\"id\":\"1047\",\"type\":\"ColumnDataSource\"},{\"attributes\":{\"source\":{\"id\":\"1031\",\"type\":\"ColumnDataSource\"}},\"id\":\"1033\",\"type\":\"CDSView\"},{\"attributes\":{},\"id\":\"1175\",\"type\":\"Selection\"},{\"attributes\":{\"edge_renderer\":{\"id\":\"1016\",\"type\":\"GlyphRenderer\"},\"inspection_policy\":{\"id\":\"1149\",\"type\":\"NodesOnly\"},\"layout_provider\":{\"id\":\"1022\",\"type\":\"StaticLayoutProvider\"},\"node_renderer\":{\"id\":\"1012\",\"type\":\"GlyphRenderer\"},\"selection_policy\":{\"id\":\"1150\",\"type\":\"NodesOnly\"}},\"id\":\"1009\",\"type\":\"GraphRenderer\"},{\"attributes\":{\"callback\":null},\"id\":\"1118\",\"type\":\"TapTool\"},{\"attributes\":{},\"id\":\"1014\",\"type\":\"MultiLine\"},{\"attributes\":{},\"id\":\"1135\",\"type\":\"LinearScale\"},{\"attributes\":{\"data_source\":{\"id\":\"1047\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"1060\",\"type\":\"MultiLine\"},\"hover_glyph\":{\"id\":\"1070\",\"type\":\"MultiLine\"},\"muted_glyph\":null,\"selection_glyph\":{\"id\":\"1065\",\"type\":\"MultiLine\"},\"view\":{\"id\":\"1049\",\"type\":\"CDSView\"}},\"id\":\"1048\",\"type\":\"GlyphRenderer\"},{\"attributes\":{},\"id\":\"1169\",\"type\":\"Selection\"},{\"attributes\":{},\"id\":\"1120\",\"type\":\"PanTool\"},{\"attributes\":{},\"id\":\"1121\",\"type\":\"WheelZoomTool\"},{\"attributes\":{\"source\":{\"id\":\"1047\",\"type\":\"ColumnDataSource\"}},\"id\":\"1049\",\"type\":\"CDSView\"},{\"attributes\":{},\"id\":\"1170\",\"type\":\"UnionRenderers\"},{\"attributes\":{\"active_drag\":\"auto\",\"active_inspect\":\"auto\",\"active_multi\":null,\"active_scroll\":\"auto\",\"active_tap\":\"auto\",\"tools\":[{\"id\":\"1115\",\"type\":\"HoverTool\"},{\"id\":\"1116\",\"type\":\"HoverTool\"},{\"id\":\"1117\",\"type\":\"HoverTool\"},{\"id\":\"1118\",\"type\":\"TapTool\"},{\"id\":\"1119\",\"type\":\"BoxSelectTool\"},{\"id\":\"1120\",\"type\":\"PanTool\"},{\"id\":\"1121\",\"type\":\"WheelZoomTool\"}]},\"id\":\"1122\",\"type\":\"Toolbar\"},{\"attributes\":{\"callback\":null,\"data\":{\"color\":[\"purple\",\"grey\",\"grey\",\"grey\",\"green\",\"grey\",\"green\",\"white\",\"red\",\"green\",\"orange\",\"green\",\"grey\",\"orange\",\"grey\",\"white\",\"lightgreen\"],\"index\":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16],\"species\":[\"nothing\",\"ordered_polymer[complex[protein[Ribo]:rna[UTR1]-forward]:rna[RFP-forward]:rna[t16-forward]]\",\"ordered_polymer[[dna[ptet]:2x_protein[tetr]-forward]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]]\",\"ordered_polymer[complex[dna[ptet]:protein[RNAP]-forward]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]]\",\"protein[RNAase]\",\"ordered_polymer[dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:complex[dna[pconst]:protein[RNAP]-reverse]]\",\"protein[RNAP]\",\"dna[dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:dna[pconst-reverse]]\",\"protein[RFP]\",\"protein[tetr]\",\"rna[rna[UTR1-forward]:rna[GFP-forward]:rna[t16-forward]]\",\"protein[Ribo]\",\"ordered_polymer[complex[protein[Ribo]:rna[UTR1]-forward]:rna[GFP-forward]:rna[t16-forward]]\",\"rna[rna[UTR1-forward]:rna[RFP-forward]:rna[t16-forward]]\",\"ordered_polymer[complex[[dna[ptet]:2x_protein[tetr]]:protein[RNAP]-forward]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]]\",\"dna[dna[ptet-forward]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]]\",\"protein[GFP]\"],\"type\":[\"nothing\",\"ordered_polymer\",\"ordered_polymer\",\"ordered_polymer\",\"protein\",\"ordered_polymer\",\"protein\",\"dna\",\"protein\",\"protein\",\"rna\",\"protein\",\"ordered_polymer\",\"rna\",\"ordered_polymer\",\"dna\",\"protein\"]},\"selected\":{\"id\":\"1175\",\"type\":\"Selection\"},\"selection_policy\":{\"id\":\"1174\",\"type\":\"UnionRenderers\"}},\"id\":\"1027\",\"type\":\"ColumnDataSource\"},{\"attributes\":{},\"id\":\"1167\",\"type\":\"Selection\"},{\"attributes\":{\"graph_layout\":{\"0\":[113.92869696557855,-143.32282000883893],\"1\":[-11.89522601096093,-92.2429232861185],\"10\":[30.954792338955897,-107.77676757130897],\"11\":[13.707254782839785,-97.2918360442955],\"12\":[46.19400639623356,-101.0878548031702],\"13\":[-1.2585990671302145,-88.49567267371968],\"14\":[33.14736664748288,27.29884263389619],\"15\":[-1.6491455633414476,5.535006101948979],\"16\":[-131.1558954013456,137.08986820257954],\"17\":[5.348508068168215,8.257389017065025],\"18\":[5.9518691887886765,-15.54001744644869],\"19\":[-7.396780225787725,13.021971187819954],\"2\":[1.2800142819200682,22.581579997071117],\"20\":[14.946092667408605,26.97612492247741],\"21\":[47.84193533719448,28.93177513917468],\"22\":[30.088213885352243,-101.5857749820705],\"23\":[57.82267527927593,-101.56543054900855],\"24\":[5.234833175270173,54.573270698909496],\"25\":[3.083574335094869,77.46304020247615],\"26\":[0.14718314441926156,-93.81339555827523],\"27\":[-22.64073464551613,-90.47872644794305],\"3\":[5.362376885529334,-6.007338556858005],\"4\":[180.00375083109702,-61.47420596314111],\"5\":[3.7850159419912757,66.64535349915812],\"6\":[6.8032987752017995,34.9199014535514],\"7\":[10.049649863022143,57.248851982636275],\"8\":[51.56862724048126,196.6312615601359],\"9\":[-14.105474786929317,11.848825265769133]}},\"id\":\"1038\",\"type\":\"StaticLayoutProvider\"},{\"attributes\":{},\"id\":\"1129\",\"type\":\"NodesAndLinkedEdges\"},{\"attributes\":{},\"id\":\"1176\",\"type\":\"UnionRenderers\"},{\"attributes\":{\"fill_color\":{\"value\":\"#fdae61\"},\"size\":{\"units\":\"screen\",\"value\":8}},\"id\":\"1090\",\"type\":\"Square\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"size\":{\"units\":\"screen\",\"value\":12}},\"id\":\"1100\",\"type\":\"Circle\"},{\"attributes\":{\"graph_layout\":{\"0\":[113.92869696557855,-143.32282000883893],\"1\":[-11.89522601096093,-92.2429232861185],\"10\":[30.954792338955897,-107.77676757130897],\"11\":[13.707254782839785,-97.2918360442955],\"12\":[46.19400639623356,-101.0878548031702],\"13\":[-1.2585990671302145,-88.49567267371968],\"14\":[33.14736664748288,27.29884263389619],\"15\":[-1.6491455633414476,5.535006101948979],\"16\":[-131.1558954013456,137.08986820257954],\"17\":[5.348508068168215,8.257389017065025],\"18\":[5.9518691887886765,-15.54001744644869],\"19\":[-7.396780225787725,13.021971187819954],\"2\":[1.2800142819200682,22.581579997071117],\"20\":[14.946092667408605,26.97612492247741],\"21\":[47.84193533719448,28.93177513917468],\"22\":[30.088213885352243,-101.5857749820705],\"23\":[57.82267527927593,-101.56543054900855],\"24\":[5.234833175270173,54.573270698909496],\"25\":[3.083574335094869,77.46304020247615],\"26\":[0.14718314441926156,-93.81339555827523],\"27\":[-22.64073464551613,-90.47872644794305],\"3\":[5.362376885529334,-6.007338556858005],\"4\":[180.00375083109702,-61.47420596314111],\"5\":[3.7850159419912757,66.64535349915812],\"6\":[6.8032987752017995,34.9199014535514],\"7\":[10.049649863022143,57.248851982636275],\"8\":[51.56862724048126,196.6312615601359],\"9\":[-14.105474786929317,11.848825265769133]}},\"id\":\"1022\",\"type\":\"StaticLayoutProvider\"},{\"attributes\":{\"graph_layout\":{\"0\":[113.92869696557855,-143.32282000883893],\"1\":[-11.89522601096093,-92.2429232861185],\"10\":[30.954792338955897,-107.77676757130897],\"11\":[13.707254782839785,-97.2918360442955],\"12\":[46.19400639623356,-101.0878548031702],\"13\":[-1.2585990671302145,-88.49567267371968],\"14\":[33.14736664748288,27.29884263389619],\"15\":[-1.6491455633414476,5.535006101948979],\"16\":[-131.1558954013456,137.08986820257954],\"17\":[5.348508068168215,8.257389017065025],\"18\":[5.9518691887886765,-15.54001744644869],\"19\":[-7.396780225787725,13.021971187819954],\"2\":[1.2800142819200682,22.581579997071117],\"20\":[14.946092667408605,26.97612492247741],\"21\":[47.84193533719448,28.93177513917468],\"22\":[30.088213885352243,-101.5857749820705],\"23\":[57.82267527927593,-101.56543054900855],\"24\":[5.234833175270173,54.573270698909496],\"25\":[3.083574335094869,77.46304020247615],\"26\":[0.14718314441926156,-93.81339555827523],\"27\":[-22.64073464551613,-90.47872644794305],\"3\":[5.362376885529334,-6.007338556858005],\"4\":[180.00375083109702,-61.47420596314111],\"5\":[3.7850159419912757,66.64535349915812],\"6\":[6.8032987752017995,34.9199014535514],\"7\":[10.049649863022143,57.248851982636275],\"8\":[51.56862724048126,196.6312615601359],\"9\":[-14.105474786929317,11.848825265769133]}},\"id\":\"1054\",\"type\":\"StaticLayoutProvider\"},{\"attributes\":{\"line_alpha\":{\"value\":0.2},\"line_join\":\"round\",\"line_width\":{\"value\":4}},\"id\":\"1060\",\"type\":\"MultiLine\"},{\"attributes\":{\"fill_color\":{\"value\":\"#abdda4\"},\"size\":{\"units\":\"screen\",\"value\":8}},\"id\":\"1095\",\"type\":\"Square\"},{\"attributes\":{},\"id\":\"1149\",\"type\":\"NodesOnly\"},{\"attributes\":{\"source\":{\"id\":\"1027\",\"type\":\"ColumnDataSource\"}},\"id\":\"1029\",\"type\":\"CDSView\"},{\"attributes\":{\"callback\":null,\"data\":{\"color\":[\"blue\",\"blue\",\"blue\",\"blue\",\"blue\",\"blue\",\"blue\",\"blue\",\"blue\",\"blue\",\"blue\"],\"index\":[17,18,19,20,21,22,23,24,25,26,27],\"k\":[\"100\",\"0.05\",\"100\",\"100\",\"0.05\",\"100\",\"0.2\",\"100\",\"0.05\",\"100\",\"0.2\"],\"k_r\":[\"10\",\"None\",\"10\",\"10\",\"None\",\"10\",\"None\",\"10\",\"None\",\"10\",\"None\"],\"species\":[\"dna[dna[ptet-forward]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]]+protein[RNAP] <--> ordered_polymer[complex[dna[ptet]:protein[RNAP]-forward]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]]\\n Kf=k_forward * dna_ptet_f_UTR1_f_GFP_f_t16_f * protein_RNAP\\n Kr=k_reverse * ordered_polymer_dna_ptet_protein_RNAP_f_UTR1_f_GFP_f_t16_f\\n k_forward=100\\n found_key=(mech=None, partid=None, name=kb).\\n search_key=(mech=transcription_mm, partid=ptet_leak, name=kb).\\n k_reverse=10\\n found_key=(mech=None, partid=None, name=ku).\\n search_key=(mech=transcription_mm, partid=ptet_leak, name=ku).\\n\",\"ordered_polymer[complex[dna[ptet]:protein[RNAP]-forward]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]] --> dna[dna[ptet-forward]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]]+rna[rna[UTR1-forward]:rna[GFP-forward]:rna[t16-forward]]+protein[RNAP]\\n Kf=k_forward * ordered_polymer_dna_ptet_protein_RNAP_f_UTR1_f_GFP_f_t16_f\\n k_forward=0.05\\n found_key=(mech=None, partid=None, name=ktx).\\n search_key=(mech=transcription_mm, partid=ptet_leak, name=ktx).\\n\",\"2protein[tetr]+dna[dna[ptet-forward]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]] <--> ordered_polymer[[dna[ptet]:2x_protein[tetr]-forward]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]]\\n Kf=k_forward * protein_tetr^2 * dna_ptet_f_UTR1_f_GFP_f_t16_f\\n Kr=k_reverse * ordered_polymer_dna_ptet_protein_tetr_2x_f_UTR1_f_GFP_f_t16_f\\n k_forward=100\\n found_key=(mech=None, partid=None, name=kb).\\n search_key=(mech=one_step_cooperative_binding, partid=ptet_tetr, name=kb).\\n k_reverse=10\\n found_key=(mech=None, partid=None, name=ku).\\n search_key=(mech=one_step_cooperative_binding, partid=ptet_tetr, name=ku).\\n\",\"ordered_polymer[[dna[ptet]:2x_protein[tetr]-forward]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]]+protein[RNAP] <--> ordered_polymer[complex[[dna[ptet]:2x_protein[tetr]]:protein[RNAP]-forward]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]]\\n Kf=k_forward * ordered_polymer_dna_ptet_protein_tetr_2x_f_UTR1_f_GFP_f_t16_f * protein_RNAP\\n Kr=k_reverse * ordered_polymer_dna_ptet_protein_tetr_2x_protein_RNAP_f_UTR1_f_GFP_f_t16_f\\n k_forward=100\\n found_key=(mech=None, partid=None, name=kb).\\n search_key=(mech=transcription_mm, partid=ptet_tetr, name=kb).\\n k_reverse=10\\n found_key=(mech=None, partid=None, name=ku).\\n search_key=(mech=transcription_mm, partid=ptet_tetr, name=ku).\\n\",\"ordered_polymer[complex[[dna[ptet]:2x_protein[tetr]]:protein[RNAP]-forward]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]] --> ordered_polymer[[dna[ptet]:2x_protein[tetr]-forward]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]]+rna[rna[UTR1-forward]:rna[GFP-forward]:rna[t16-forward]]+protein[RNAP]\\n Kf=k_forward * ordered_polymer_dna_ptet_protein_tetr_2x_protein_RNAP_f_UTR1_f_GFP_f_t16_f\\n k_forward=0.05\\n found_key=(mech=None, partid=None, name=ktx).\\n search_key=(mech=transcription_mm, partid=ptet_tetr, name=ktx).\\n\",\"rna[rna[UTR1-forward]:rna[GFP-forward]:rna[t16-forward]]+protein[Ribo] <--> ordered_polymer[complex[protein[Ribo]:rna[UTR1]-forward]:rna[GFP-forward]:rna[t16-forward]]\\n Kf=k_forward * rna_UTR1_f_GFP_f_t16_f * protein_Ribo\\n Kr=k_reverse * ordered_polymer_protein_Ribo_rna_UTR1_f_GFP_f_t16_f\\n k_forward=100\\n found_key=(mech=None, partid=None, name=kb).\\n search_key=(mech=translation_mm, partid=UTR1, name=kb).\\n k_reverse=10\\n found_key=(mech=None, partid=None, name=ku).\\n search_key=(mech=translation_mm, partid=UTR1, name=ku).\\n\",\"ordered_polymer[complex[protein[Ribo]:rna[UTR1]-forward]:rna[GFP-forward]:rna[t16-forward]] --> rna[rna[UTR1-forward]:rna[GFP-forward]:rna[t16-forward]]+protein[GFP]+protein[Ribo]\\n Kf=k_forward * ordered_polymer_protein_Ribo_rna_UTR1_f_GFP_f_t16_f\\n k_forward=0.2\\n found_key=(mech=None, partid=None, name=ktl).\\n search_key=(mech=translation_mm, partid=UTR1, name=ktl).\\n\",\"dna[dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:dna[pconst-reverse]]+protein[RNAP] <--> ordered_polymer[dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:complex[dna[pconst]:protein[RNAP]-reverse]]\\n Kf=k_forward * dna_t16_r_RFP_r_UTR1_r_pconst_r * protein_RNAP\\n Kr=k_reverse * ordered_polymer_t16_r_RFP_r_UTR1_r_dna_pconst_protein_RNAP_r\\n k_forward=100\\n found_key=(mech=None, partid=None, name=kb).\\n search_key=(mech=transcription_mm, partid=pconst, name=kb).\\n k_reverse=10\\n found_key=(mech=None, partid=None, name=ku).\\n search_key=(mech=transcription_mm, partid=pconst, name=ku).\\n\",\"ordered_polymer[dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:complex[dna[pconst]:protein[RNAP]-reverse]] --> dna[dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:dna[pconst-reverse]]+rna[rna[UTR1-forward]:rna[RFP-forward]:rna[t16-forward]]+protein[RNAP]\\n Kf=k_forward * ordered_polymer_t16_r_RFP_r_UTR1_r_dna_pconst_protein_RNAP_r\\n k_forward=0.05\\n found_key=(mech=None, partid=None, name=ktx).\\n search_key=(mech=transcription_mm, partid=pconst, name=ktx).\\n\",\"rna[rna[UTR1-forward]:rna[RFP-forward]:rna[t16-forward]]+protein[Ribo] <--> ordered_polymer[complex[protein[Ribo]:rna[UTR1]-forward]:rna[RFP-forward]:rna[t16-forward]]\\n Kf=k_forward * rna_UTR1_f_RFP_f_t16_f * protein_Ribo\\n Kr=k_reverse * ordered_polymer_protein_Ribo_rna_UTR1_f_RFP_f_t16_f\\n k_forward=100\\n found_key=(mech=None, partid=None, name=kb).\\n search_key=(mech=translation_mm, partid=UTR1, name=kb).\\n k_reverse=10\\n found_key=(mech=None, partid=None, name=ku).\\n search_key=(mech=translation_mm, partid=UTR1, name=ku).\\n\",\"ordered_polymer[complex[protein[Ribo]:rna[UTR1]-forward]:rna[RFP-forward]:rna[t16-forward]] --> rna[rna[UTR1-forward]:rna[RFP-forward]:rna[t16-forward]]+protein[RFP]+protein[Ribo]\\n Kf=k_forward * ordered_polymer_protein_Ribo_rna_UTR1_f_RFP_f_t16_f\\n k_forward=0.2\\n found_key=(mech=None, partid=None, name=ktl).\\n search_key=(mech=translation_mm, partid=UTR1, name=ktl).\\n\"],\"type\":[\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\"]},\"selected\":{\"id\":\"1171\",\"type\":\"Selection\"},\"selection_policy\":{\"id\":\"1170\",\"type\":\"UnionRenderers\"}},\"id\":\"1011\",\"type\":\"ColumnDataSource\"},{\"attributes\":{\"fill_alpha\":{\"value\":0},\"fill_color\":{\"field\":\"color\"},\"line_alpha\":{\"value\":0},\"size\":{\"units\":\"screen\",\"value\":12}},\"id\":\"1055\",\"type\":\"Circle\"},{\"attributes\":{},\"id\":\"1174\",\"type\":\"UnionRenderers\"}],\"root_ids\":[\"1004\"]},\"title\":\"Bokeh Application\",\"version\":\"1.4.0\"}};\n var render_items = [{\"docid\":\"df083da7-2a52-4c4c-a210-d31408d268ad\",\"roots\":{\"1004\":\"7e1b449d-00d1-4213-80de-da31129e6aea\"}}];\n root.Bokeh.embed.embed_items_notebook(docs_json, render_items);\n\n }\n if (root.Bokeh !== undefined) {\n embed_document(root);\n } else {\n var attempts = 0;\n var timer = setInterval(function(root) {\n if (root.Bokeh !== undefined) {\n clearInterval(timer);\n embed_document(root);\n } else {\n attempts++;\n if (attempts > 100) {\n clearInterval(timer);\n console.log(\"Bokeh: ERROR: Unable to run BokehJS code because BokehJS library is missing\");\n }\n }\n }, 10, root)\n }\n})(window);", + "application/vnd.bokehjs_exec.v0+json": "" + }, + "metadata": { + "application/vnd.bokehjs_exec.v0+json": { + "id": "1004" + } + } + }, + { + "output_type": "stream", + "name": "stderr", + "text": "D:\\anaconda3\\lib\\site-packages\\html5lib\\_trie\\_base.py:3: DeprecationWarning: Using or importing the ABCs from 'collections' instead of from 'collections.abc' is deprecated since Python 3.3,and in 3.9 it will stop working\n from collections import Mapping\nD:\\anaconda3\\lib\\importlib\\_bootstrap.py:219: RuntimeWarning: numpy.ufunc size changed, may indicate binary incompatibility. Expected 192 from C header, got 216 from PyObject\n return f(*args, **kwds)\nD:\\anaconda3\\lib\\site-packages\\bioscrape\\sbmlutil.py:208: UserWarning: Compartments, UnitDefintions, Events, and some other SBML model components are not recognized by bioscrape. Refer to the bioscrape wiki for more information.\n warnings.warn('Compartments, UnitDefintions, Events, and some other SBML model components are not recognized by bioscrape. ' +\n" + }, + { + "output_type": "display_data", + "data": { + "text/plain": "
", + "image/svg+xml": "\r\n\r\n\r\n\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n\r\n", + "image/png": "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\n" + }, + "metadata": { + "needs_background": "light" + } + } + ], + "source": [ + "#here we are plotting the network diagram and simulating the system with some basic parameters\n", + "\n", + "plotNetwork(myCRN)\n", + "try:\n", + " import numpy as np\n", + " import matplotlib as plt\n", + " timepoints = np.linspace(0, 200, 1000)\n", + " x0 = {str(construct_1.get_species()):5.0,\n", + " str(construct_2.get_species()):2.0, \"protein_RNAP\":10., \"protein_Ribo\":50.}\n", + " Re1 = myCRN.simulate_with_bioscrape_via_sbml(timepoints, initial_condition_dict = x0)\n", + " if(Re1 is not None):\n", + " plt.plot(timepoints,Re1[\"protein_GFP\"], label = \"protein_GFP\")\n", + " plt.plot(timepoints,Re1[\"protein_RFP\"], label = \"protein_RFP\")\n", + " plt.title(\"Time trace of two DNA system\")\n", + " plt.xlabel(\"time\")\n", + " plt.ylabel(\"protein\")\n", + " plt.legend()\n", + "except ModuleNotFoundError:\n", + " print('please install the plotting libraries: pip install biocrnpyler[all]')\n", + "\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "That seems pretty straightforward but now let's see what happens if we put both on the same piece of DNA:\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": { + "tags": [] + }, + "outputs": [ + { + "output_type": "display_data", + "data": { + "text/plain": "
", + "image/svg+xml": "\r\n\r\n\r\n\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n\r\n", + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAfQAAABtCAYAAABXyJO1AAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADh0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uMy4xLjMsIGh0dHA6Ly9tYXRwbG90bGliLm9yZy+AADFEAAAdh0lEQVR4nO3deXhU9dn/8feHEAi7AioQwqIgrnWtogUFt5/FitparVXR1larta1PS22rFgLF9vdYba2PVtxbt9aFVp+KUhFBpLJURcRSQa1gGEBA1gAJIbmfP86ZMIQsM8lkzmRyv66L62K+8z3n3DNncu7zXc45MjOcc84517K1iToA55xzzjWdJ3TnnHMuB3hCd84553KAJ3TnnHMuB3hCd84553KAJ3TnnHMuB3hCr4ekP0iaFHUc6Sapg6S/Sdos6Zmo40mVAo9I2ihpQdTx1CTpAkklkkolHZMF8QyRtFDSVknfjzoe51zz8ISepSQVS3o8hfpXSpqTZPULgQOAHmb21VRjkGSSBkn6V5i0SiVVSipLeH1TGFNl+HqLpEWSvlRjXfdLWiqpStKVScY/DDgT6GtmJ9RXUVIXSb+RtFzSNkmfSHpW0gkJdSx8Lx77prB8RBhXaZgMl0r6RhLx3Q5cb2adzWxhPbEtl3RGjbJ6vw9JB0p6IYxnvaTbkojnRmCWmXUxs7vqiWevE1hJ10t6U1K5pD/UskxHSb8PY9ksaXYS8SQtjGlnuA82SJou6ZCE9xN/Y/F/dyezbJpiq/l9DQh/T21rxFQlaUfC60vDv6+K+G9O0huSTkpYV7vwt7o8XOeIdMWejcK/t5VRx9GSeUJvnfoDy8xsV1NWYmaHh0mrM/A6u5NYZzP7ZVhtbvj+PsDvgT9L2idhNYuA64C3U4x/uZltq6+SpPbAq8CRwJeArsChwJ+BUTWqH5UQe2J8q8L4uwI/AR6QdFgS8f0r6U+zpzq/D0ntgOkEn6kX0BdI5qSvKfGsAiYBD9fx/v1Ad4LvtTvwX6luQFJeA1VuC/dBIRADHqrx/tyEfdfZzK6vZdm+wFrgDynG1jaV+okSYwI+Ac5NKHsirPZU+H5PYCZQs8dsDnAZsKaxcSTx/bZ4TdlPucQTegJJx0h6O2z9PAUUhOUjJK2U9CNJayWtTmypSTpHQZfmFgVdrcVJbCt+Jn+1pFXhOn8Uvnc2cBNwcXj2vigs7ybpobBuTNIkSXmSDgUmAycltjDr2O4EYFzCuq9q/DeWPDOrAh4DOgGDE8rvMbMZQFky6wnjfZDdn3VCPdUvJziQn29m75lZpZltM7Nnzaw4xfjNzJ4DNgK1JnRJ7SWVAnnAIkkf1fM5HgP6AX8LP8eN4Xbq+z6uJDjB+E34OcrM7N364pb0KjASuDvczsF11LsauBS4Maz3tzCev4Sf+7NalhkCjAauNrN14ff7Vn3xhMv9QdK9kl6UtC2Mr0FmtgN4Gjg6mfo1lt0OPAkc0UBsxWGr+HFJWwi+82YXnlw/ARRK2i8s22lmd5rZHKAy2XWl8v2GdSeHvRdbJb0mqX/C+4eH722Q9Kmkm8Ly9pLuDI9dq8L/tw/fa+h4OUrSknB7MUljJXUCXgL6JPRi9Kkn7kj2U7bzhB4KWz/PESSd7gRnyl9JqNIL6EbQSrgKuEfSvuF724AxBK3Qc4BrJZ2f5KZHEiS4s4CfSjrDzKYBvyQ8ezezo8K6fwR2AYOAY8JlvmVm/wa+w+6Wyj57bSVkZuNrrLtma6dZhK2EbwAVwIrGrieMN/Gzjq+n+hnA3xtqySdDUhtJFxDs48V1xFYetrYgaPEfVNf6zOxy9my1JdN1PhRYLuklBV3csyQdWd8CZnYae/aeLKuj3v0ECeW2sN65ScRzIsG+nBDGs1jSVxpaKPR14FagC0ErtEHhQf8S4MMkt5G4bGeCE5Y6h0ASnAc8S7Cvn2igblqEx58xBCdOG9OwylS+30uBXxD0ErxD+JkldQFeAaYBfQiOOzPCZW4m+D0eDRwFnADckrDO+o6XDwHXmFkXghOsV8O/0S8S9oiF/1Y1EHfG91O284S+21AgH7jTzCrM7FngnwnvVwATw/deBEqBIQBmNsvMFptZVdhi+hNwapLbnRC2thYDjxAcsPYi6QCCH/wNYf21wG+Br6X+UTNqaNhjUEYwtnxZGHsm9CShq1LS0QrGKrdIWlqj7tvhe5skJY4z9wnjXw+MBy43s5rLZkpfgv19F8EBdirwfJgMoornCGBzGM/1wB/DHqOGPG9m/wj/ZhrqnRkb7oOtBPMnLq/x/tCEfbdJ0tBalv0Q6ExyLbm5ZvZcGNuOJOo3xUVhfDuAbwMXNnUoLJTK9zvVzGabWTlBoj5JUhHBMNUaM7sj7A3aambzw2UuJTgerjWzdcAE9twvdR4vw/cOk9TVzDaaWSrDbYkyuZ9aBE/ou/UBYmZ7PK0msSX5WY0/tO0EBwgknShppqR1kjYTtCB7Jrndkhrbq6ubqT/BCcfq+IELuA/YP8ntNMaucJvVJMVfVyS5jnlhj8G+wP8Cw9MXXoM+A3rHX5jZO2EsXwba16h7rJntE/5LnAm+KizrbmZHm9mfMxB3XXYAc8zsJTPbSXCC1INg/DqqeCqASWH38GsE48BnJbFsScNVqt0e7rcB4TaH1Hh/XsK+28fM5tVc1sx6mdloM6tzGKQRse319xG+rgr/JePp8LMdALwHHJfkcg1J5futrmtmpcAGguNQEVDX99WHPY+PNY9ddR4vCXo+RwErwi7+k2icVD5jq+AJfbfVBONXSijrl+SyTxIkqyIz60Ywnq36F6lWVGN78W6mmo/BKwHKgZ4JB66uZnZ4HfXT4ROCg2iigQTjebFUVhQeKK4DLlfmLuWaAZwVdtVmo1T32buNWCYVjYknU9vCzD4BfgD8TlKHJmy7wU0lWa+uv48SC+aMJL9Bs/XANUCxpN4N1U9mlSnUrT4GhUMT3QmOQyVAXcNGqwgaGXGJx676AzP7p5mdR9AYeY5gXkSqMTemfs7zhL7bXIIz7u8ruOTkywTjQsnoAmwwszIFl0N9PYXt/lzBpT+HE4wxPxWWfwoMkNQGwMxWAy8Dd0jqGo7pHiTp1IT6fdPc/ToNGCLpckn5kroTjL8/25huQTP7jGBC27h4mYJLcwoIToDyJRXEP3MaPEpwovZXSUcomEBYAByfpvU31afAgYkFDXwfjxN0L58Rzkm4gWAo4N/NGE/bMJ48IC+MJz6jeDZBUvtZWO8LwAjg72mKZy9mNp0gcVzdXNtIwRTgHElnhb+tPgTjyI3qxTGz9wm+uxvjZeHks4LwZbvw+0+2sZCsUZKGhceOXwDzzawEeAHoJemGMI4ukk4Ml/kTcIuk/ST1JPibbvCKi/D3famkbmZWAWxh94S/T4Eekrql+fO1Gp7QQ2EX5pcJxtg2AhcDf0ly8euAiZK2Evywn26gfqLXCMb3ZhB0D74clscvX/lMUnyMaQzQDlgSxvgsu7uUXyW4NGmNpPUpbL9O4Vj3KIKWw1qCLsHNwLVNWO2dBAeQz4WvXyboRj2Z4BKoHcApTVh/tXDscCTB9zWV4OCxFPg8cFE6ttFEvyI4KG6SNDYsq/P7CMfuLyPoAdpIMClodPjbTYeHCMY2N0l6Liy7JYzhp+G2d4RlhAfk8wh+I5uBB4AxYWJqTr8mmI1fc9gko8zsXwRzXn5F0E09F5hPMJ7cWL8GrpYUH0pbSvCdFxIk+x3s2TJOhycJ5odsIOjyvxTAzLYS3O/hXIK5KB+we8b8JOBNgl6axQSXWSZ7E67LCSZ3biEYnrws3N77BCcK/wl/g3XOcne1055Dxi5TJA0APgby0zQJxjnnUqLgZkErzeyWhuq67OctdOeccy4HeEJvRuFYUWkt/xp7165Utv2vOrZ9aY16k+uoN7m5Y6yPgmuta4vrphr1bqqj3kvNGFtS+1VSvzrqlUpKdsJlMvEkvZ1kfxdpiCnp7WQqpoTtJfXbSrVuJmXz95su2frdZzPvcnfOOedygLfQnXPOuRzgCd0555zLAZ7QnXPOuRzgCd0555zLAZ7QnXPOuRzgCd0555zLAZ7QnXPOuRzQtuEqzS9WWHQUwf2q/1gYK9kSdTzOOedcS5MtLfSewF1ALFZYdHessOiQqANyzjnnWpKsuFNcrLDodOCVGsWvAP8DTC2MlVTuvZRzzjnn4rKlhV6bM4DngQ9jhUU/jhUW9Yg6IOeccy5bZXNCjxsA3AasjBUWPRgrLDo64nicc865rNMSEnpcAXAVsDBWWPR6rLDo4lhhUX7UQTnnnHPZoCUl9ETDgD8DK2KFReNihUW9og7I5RZJijoGl338d+GyWZMnxcUKi6KfVQcVwDPAzYWxkuURx+JygKTBwGgzuyPqWADuO+/xjP6dXfP8ZZ64apC0P/A9M/t51LE4V5uW2kJPVAk8B9wHrIg4Fpdbbpc03ltlTlIh8Brgc3hc1sqKG8s00lrgfuC+wljJyqiDcTmrGOgs6UbLhms8XcZJGgjMAAYCH0YcjnN1SmtCL4yVNKolU8d16HWZD9wNPFMYKylvzPacS9FYoJOk682sKooAUu0CT+yi9+7zxpM0hCCZF0Ydi3MNaSkt9J0Ek+DuLoyV/DPqYFyrdC1BUr/KzHZFHYxrfpI+B0wH9o86FueSke0JfSVwL/BgYaxkbdTBuFZvDNBR0qVmtjPqYFzzkXQCMA3YN+pYnEtWtib0WQTd6s8Xxkq8NeSyyYUESf1CM9sRdTAu/SSdAkwFOkcdi3OpyKZZ7tsJZqp/rjBWMrIwVjLFk7nLBh17dWTguQMSi0YBUyX5AT/HSPp/BC3zzgA9euRRXNw72qCcS1K2tNAXAX0LYyUbow7EuZokOPwbh9K2oC0fPFM9yXkk8LKkUWa2KcLwXJpIugB4CsgH6N07n1deGcxHH/ncW9cyZEULvTBWst6Tuctmkjjk6wdz6OVDEotPAmZK2i+isFyaSLqU4OZU+QD9+rVj9uyDOeywDtEG5lwKsiKhO9dSDPryQRzx7cMSi44GXpPUJ6KQXBNJ+jbwGJAHMHhwe15/fQiDBhVEG5hzKfKE7lyKBo4awFHXH5n413Mo8LqkAVHF5BpH0g0EN6gSwBFHFDB79hD69WsXbWDONUK2jKG7GiTlAwcDhxM8QrYAMGAb8AHwHrAiXTc6kfQ14JB0rCtH9KjvzX6nF5HXPo+Fdy7CKg3gQIKkfrqZLctIhK7Rwtv53gz8Il523HEd+fvfB9OjR72HxSGSips5vJbmETPz225nAU/oWUTSvsBXgK8Dw2l4/5RKegn4E/CSmZU1YfMXA+c3YflWp3BYH/La5/HWrxdSVVEF0BeYLelMM1sccXiuDmEy/xXwk3jZsGGdeeGFQXTrltfQ4oOB8c0YXks0A3+ORlbwLvcsIOkASfcBnwIPEMygTuZkqzPwVeAvwGpJN0nyWTwZ1OvzB3DCzceT1746ERwAzJJ0fIRhuTpIagPcRUIyP/PMLkybllQydy6reQs9QpLaEtwn/GZquYlFu27703G//hT06EubdgVgxq6yUsrWl7B97XJ2bd+cWH0f4FbgGkljzeyZxsbV5wu96dy3U2MXzzn5nesfT93vqJ4MHf955k96k13bdwF0B14NL2mbk4kYXcMk5QEPAlfGy0aP7sZTTx1IQUHdbZuDDy5g/Hi/Fj3Rww+vp6SkIuowXA2e0CMiqQfwNHBaYnmnPoPpccRp9Dj8FNp1qXcYl+3rVvDZe7P4bPFMyjetiRf3A56WdA9wQ2PuO95nWG96D+2V6mKtWvdDu3PSxBOZV7yAitIKgC4E16mfZ2bTIw6v1ZPUjmAm+0Xxsq99bV8efXQg+fn1P7tmyJACiov9IoZEM2Zs9YSehTyhR0BSEfAyCZPQOuzXj35nXs0+g5Lvqe24X386jryCvqdextq3p7Fy1qOJrfbvAgMkfdVvUZoZ+xzUjZMnDWXehAWUbywH6AC8EO6D/404vFZLUgHBNeZfipd985s9uP/+/uTl+YPoXO7wMfQMC8e4n6c6mYvCUy/jyGvuTSmZ77HONnkccPw5HHX9w3Q/bHjiW+cAvw8nAbkM6Nq/CydPGkpBz+prmNsBfwmvInAZFt6e9wUSkvn3v78/DzzgydzlnlbVQo8VFhXnH3nkgLb9+w3oft/kWU1Z14ZrvjNi14pPllcsXry8MFZSnMwyYWK9FzgGQG3actAFN9Lj8FOaEkq1tgWdGPSVmyjZ9xFW/+PpePGVBM+Qn5yWjbgGde7TiS/cehLziuezbfV2CG5Y8qSkjmb2cMThtRqSugEvAifHy372s17cemsf/BzX5aJWldCB8RWLF1OxeDHAqU1Z0Y4XpiauozjJxUYDV8Rf9D/7O2lL5nGSKDrtG1Rs3cD6d1+JF/9O0otm9klaN+bq1HH/Dpw8aShzixdQWlIKwY1LHpLU2czuiji8nCepJ/B34Nh42a239uGmm3xym8td3uWeIWHrfFz8dc/Pnc7+x53TXNti4Dnfo+MBA+NF7Ui4TMdlRkH3Ak6eNJRuB3ZNLP6dpJ9FFVNrIKk3wSOYq5P5nXf29WTucp4n9Mw5m/AAo7btKDrjqmbt9muT356iM76VWPQtv9945rXv2o6TJp7Ivofsm1j8S0m3+tyG9JPUH5hNcIdFJHjwwf784AcHRBuYcxngCT1zLoz/Z/9jz6Zd5+7NvsFuBx5Lpz7VTwdrRzBJzmVYfqd8ho77PD2P3OMyxJuAOz2pp4+kwcDrwCCAvDx44omBXHVVz2gDcy5DPKFnzrD4f3oclt5x87pIosees96H1VXXNa+2Hdpywi3Hs/9xezxp9fvAA+ENT1wTSDqCoGVeBNCunZgy5SAuuaT5T5ydyxatbVJcJMIJOgfHX+8s3cDGpfMysu1dZaWJL7+QkY26WuW1y+PzPzmOt+98h9VvVN8I6Cqgo6QrzMzv1NEIko4jmADXA6BDB/Hcc4M466yu9S/omlXYY5IND3zaZGavRx1EJiSV0CVZXe+t7NM3qXrZIDHWdEr1c3/47C+bJY4kHJTt+yjXtclvw3E/PIZFBe9S8mosXnwJcEk6e98nj36s+v/Zss8t4ZEmmtA82+jSpQ1Tpw5i+PAuzbMBV5vZ2T5ylO3xAeyYMLP6/x3Gj6y1jpnV+0G8y925DFOeKBzeJ3wCt0unI4/swLHHdow6DOci4V3uzmXYmn9+ylu/Xhg83d6l1RtvbOPssz9k6tRBdO3qUxOyyTG9M/fAp4Wrt2VsW9kkqYTeUDO/ul7TYml2scKiZgkx2e8nm0n6K/489Ga36h+refu372CV1T/FlcDpZrasubZ5DZc116pTU7y76z+dfzPhlQI3A78AmDOnlNNPX8a0aYPp0cPbLBlwSm1j1OFExcUAXdvnMXZY34x1fT/01hpmfLQp/nK8mU3MyIaboGzirCb/fXiXu3MZ8smMEt76zcLEZP4fYHhzJvPWwAKTgB/Gy958czsjRixlzRqfZxihJcAmgC3llZRsLs/IRs2MJWu3Jxa1mkcYe0J3LgM+fnE5i+5eDFXVRf8mSObLIwsqx5jZb4FrCDsL33uvjFNOWUpJyc5oA2ulzKwKqJ7p9eKyDRnZ7turSlm9tXqfbyd4lkWr4AnduWb24V8+4r0HliQWvQOcamarIgopZ5nZ/cAYoBLggw/KGT58KR99lJnWodvL7fH/zFmxhdiW5t0PlVXGlCXrE4vuNbNWM6DuCd25ZmJmvP/kMv792NLE4nnASDNbF1FYOc/MHge+ClQArFixk+HDl7JkyY5oA2uFzOwN4FWAKoO75q6ibFdVA0s13p8Xr2P5xuqThjISTihag1Y7YyRWWBR1CC6HmRlLHvk3//nb8sTimcBoMyutfSmXLmb2V0mjgb8CBatXV3Dqqct4+eXBHHOMX9aWYWOBuUD7ks3lTF6wmu8N7UNem/ROkJu9fDNTl+7RrT/JzNbUVT8XeQvduTSzSuPde9+rmcxfBM7xZJ45ZjaN4KFIpQDr1+9i5MhlzJ3ruyCTzGwhcG389YKVW7l9zkq276xM1/p54f3PuG/B6sTivwG/SssGWhBP6M6lUVVlFQvvWsQn00sSi6cAF5iZ9/lmmJm9BpxBONt68+ZKzjzzA2bO3BptYK2MmT0C/E/89aI12/jZ9OUsWLkVs8ZfTRzbUs5tr6/kyXfXJV42vQQYE07Ka1VaVZd7YaykxV8v7rJXZUUlb9/xDmvmf5pY/ChwlZntiiisVs/M5ksaAUwH9tu2rYpRoz5gypSDGDWqW8TRtSo/ALYQ3DOAddsquPONGIfs14EvHtydo3t1Ij+v4TammfHxxnJm/mcTMz/eRNWe5wNvEAxrbap96dzWqhK6S05FaQVlG8qiDiNrqI1ov0/7euvsKq/kzf9+i3UL95hhOxn4bmtsKWQbM1sk6RTgFaCwrMw4//yPePLJgVx44b71LltWVsWGDX4+lqi8PPWftAVN8VskvUvwt7EvwPvrdvD+uhgd89twbJ/ODNingL7d2rN/p3zy80RllbG5vJKVm8tZubmcd9ZsS7wsrXr1wN3AWDNrtdcpekJ3e1l0z+KoQ8gqnXp35LTfj6jz/V07djF/0ptsWLLHhJzbgRutKf2JLq3M7H1Jw4EZwMCKCuPii//DI48MYMyYHnUuN336FkaP/ihjceY6M3ta0ivAOOC7hHloe0UVc1ZsYc6KLamucibwQzN7J72Rtjw+hu5cE+zcupO54+fXTObFeDLPSmb2MXAKsBSgqgquuGI5997rVxFmkpltMLMbgEOBW4GPU1xFKcFw1pkEt05u9ckcvIXudtsIrG6wVuvRFtivvgrlm8qZN2EBW5bvMcFqrJnd0ayRuSYxs5Vh9/t04HMA1133Cdu2VTJ2bK+GFt8JfNbMIbY0je7iNrMPCbrhfw6cAAwFjgAOB3oB7QnuJ7CFYLLbv4BFwHSfZLo3T+gOADP7ZtQxZBNJg4E677G+Y/0O5hYvYFtsj5tQXWtmk5s9ONdkZrZW0kjgJYJEwo9/HKO0tIrx43vX9xCRl83s3EzF2VqEvVnzaUW3aW0O3uXuXIq2rdnOP26el5jMq4ArPJm3LGa2geCSttnxsgkTVvPjH8eadCmVc1HxhO5cCrauLOWNW+axY211b18FcJGZPRphWK6RzGwr8EVgWrzsjjs+5brrPqGqypO6a1k8oTuXpM0fb+GNm+dR9ln1JX1lwPlmNiXCsFwTmdl24HyC28QCMHnyeq68cjm7dnlSdy2Hj6E7l4SNyzYxf+ICKrZVX4+8DTjXzGbWs5hrIcysXNJFwB+ASwEee2wD27dXcckl3SONzWWvsomzugNXAT0Lxo34SdTxeEJ3rgHlm4JL0yrLqu89vRn4opnNjTAsl2ZmtkvSGIKTtasBpkzZxLx5rebpmy5JZRNnHQV8j+DkrwB4OtqIAp7QnWvArh173CVsPXBW+MAJl2PMrErSdwiS+n8BxGIV0QblskLZxFn5wAUEiXxYxOHUyhO6c8lbDZxhZkuiDsQ1HzMzST8CthLczcy1YmUTZ/UCvg18B+gTcTj18oTuXHJWENyRyu8B2gqE10WPl7QN+O+o43GZVTZxloATgeuBi4D8aCNKjid05xq2jKBlXtJgTZdTzOw2SaXAPVHH4ppf2cRZBcDFBIn8+IjDSZkndOfq9x5BMv+0wZouJ5nZ78OW+sNRx+KaR9nEWUXAtQRd6z0jDqfR5HdEcm5v4a1fnwTONjO/d3dtipXZg0ex1Xk/1kyQ9FXgEjP7cpRxuPQpmzgrD/j/wA/JovuyFIwb0ajfetZ8AOeyzFqCMXNP5g4AM3sG+EHUcbj0KRg3ohL4KXAe8HLE4TSZd7k7Vwsz2xx1DC77+DyK3BMm9ReAF8omzhpC8Iz2K4EuUcbVGN7l7pxzziUomzirCzCGYHLcIUks8nTBuBEXN29UDfMud+eccy5BwbgRWwvGjbgHOAw4E3ie4KmKWc273J1zzrlaFIwbYcArwCtlE2cNIJgJ/y0gK2/w7y1055xzrgEF40YsDx/A0pfggSzvRBzSXnwM3TnnnEtReDe5kwnG2SsLxo24LOKQPKE755xzTVE2cVb7gnEjyqOOwxO6c845lwN8DN0555zLAZ7QnXPOuRzgCd0555zLAZ7QnXPOuRzgCd0555zLAZ7QnXPOuRzgCd0555zLAZ7QnXPOuRzgCd0555zLAZ7QnXPOuRzgCd0555zLAf8HuU/RYluOLooAAAAASUVORK5CYII=\n" + }, + "metadata": { + "needs_background": "light" + } + }, + { + "output_type": "display_data", + "data": { + "text/plain": "
", + "image/svg+xml": "\r\n\r\n\r\n\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n\r\n", + "image/png": "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\n" + }, + "metadata": { + "needs_background": "light" + } + }, + { + "output_type": "display_data", + "data": { + "text/plain": "
", + "image/svg+xml": "\r\n\r\n\r\n\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n\r\n", + "image/png": "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\n" + }, + "metadata": { + "needs_background": "light" + } + }, + { + "output_type": "stream", + "name": "stdout", + "text": "ptet_UTR1_GFP_t16_t16_r_RFP_r_UTR1_r_pconst_r\n\tptet_0\n\trna = UTR1_GFP_t16\n\tUTR1_0\n\tprotein = GFP_1\n\tpconst_7_r\n\trna = UTR1_RFP_t16\n\tUTR1_0\n\tprotein = RFP_1\nD:\\anaconda3\\lib\\site-packages\\bioscrape\\sbmlutil.py:208: UserWarning: Compartments, UnitDefintions, Events, and some other SBML model components are not recognized by bioscrape. Refer to the bioscrape wiki for more information.\n warnings.warn('Compartments, UnitDefintions, Events, and some other SBML model components are not recognized by bioscrape. ' +\nd:\\documents\\github\\biocrnpyler\\biocrnpyler\\chemical_reaction_network.py:342: UserWarning: Trying to set species that is not in model: protein_arac\n m.set_species(initial_condition_dict)\n" + }, + { + "output_type": "display_data", + "data": { + "text/plain": "
", + "image/svg+xml": "\r\n\r\n\r\n\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n\r\n", + "image/png": "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\n" + }, + "metadata": { + "needs_background": "light" + } + } + ], + "source": [ + "construct_3 = DNA_construct([[ptet,\"forward\"],[utr1,\"forward\"],[gfp,\"forward\"],[t16,\"forward\"],[t16,\"reverse\"],[rfp,\"reverse\"],[utr1,\"reverse\"],[pconst,\"reverse\"]])\n", + "#now, we are using dnaplotlib to plot the constructs\n", + "\n", + "if(dpl_enabled):\n", + " plotConstruct(construct_3,debug=False,plot_rnas=True)\n", + " print(construct_3.show())\n", + "\n", + "#some very basic parameters are defined\n", + "parameters={\"cooperativity\":2,\"kb\":100, \"ku\":10, \"ktx\":.05, \"ktl\":.2, \"kdeg\":2,\"kint\":.05}\n", + "\n", + "components = [construct_3]\n", + "myMixture = TxTlExtract(name = \"txtl\", parameters = parameters, components = components)\n", + "myCRN = myMixture.compile_crn()\n", + "try:\n", + " import numpy as np\n", + " timepoints = np.linspace(0, 200, 1000)\n", + " x0 = {str(construct_3.get_species()):5.0, \"protein_GFP\":20,\"protein_RNAP\":10., \"protein_Ribo\":50.,\"protein_arac\":20}\n", + " #I started the GFP at a slightly elevated value so you can see the two lines on top of each other in the graph\n", + " Re1 = myCRN.simulate_with_bioscrape_via_sbml(timepoints, initial_condition_dict = x0)\n", + " if(Re1 is not None):\n", + " plt.plot(timepoints,Re1[\"protein_GFP\"], label = \"protein_GFP\")\n", + " plt.plot(timepoints,Re1[\"protein_RFP\"], label = \"protein_RFP\")\n", + " #plt.plot(timepoints,Re1[\"rna_mydna\"], label = \"rna_mydna\")\n", + " #plt.gca().set_yscale(\"log\")\n", + " plt.title(\"Time trace of single DNA system\")\n", + " plt.xlabel(\"time\")\n", + " plt.ylabel(\"protein\")\n", + " plt.legend()\n", + " #'''\n", + "except ModuleNotFoundError:\n", + " print('please install the plotting libraries: pip install biocrnpyler[all]')\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The same RNAs and proteins are made, but the network diagram should be a bit more complicated, owing to the combinatorial binding to the DNA molecule" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": { + "tags": [] + }, + "outputs": [ + { + "output_type": "display_data", + "data": { + "text/html": "\n
\n \n Loading BokehJS ...\n
" + }, + "metadata": {} + }, + { + "output_type": "display_data", + "data": { + "application/javascript": "\n(function(root) {\n function now() {\n return new Date();\n }\n\n var force = true;\n\n if (typeof root._bokeh_onload_callbacks === \"undefined\" || force === true) {\n root._bokeh_onload_callbacks = [];\n root._bokeh_is_loading = undefined;\n }\n\n var JS_MIME_TYPE = 'application/javascript';\n var HTML_MIME_TYPE = 'text/html';\n var EXEC_MIME_TYPE = 'application/vnd.bokehjs_exec.v0+json';\n var CLASS_NAME = 'output_bokeh rendered_html';\n\n /**\n * Render data to the DOM node\n */\n function render(props, node) {\n var script = document.createElement(\"script\");\n node.appendChild(script);\n }\n\n /**\n * Handle when an output is cleared or removed\n */\n function handleClearOutput(event, handle) {\n var cell = handle.cell;\n\n var id = cell.output_area._bokeh_element_id;\n var server_id = cell.output_area._bokeh_server_id;\n // Clean up Bokeh references\n if (id != null && id in Bokeh.index) {\n Bokeh.index[id].model.document.clear();\n delete Bokeh.index[id];\n }\n\n if (server_id !== undefined) {\n // Clean up Bokeh references\n var cmd = \"from bokeh.io.state import curstate; print(curstate().uuid_to_server['\" + server_id + \"'].get_sessions()[0].document.roots[0]._id)\";\n cell.notebook.kernel.execute(cmd, {\n iopub: {\n output: function(msg) {\n var id = msg.content.text.trim();\n if (id in Bokeh.index) {\n Bokeh.index[id].model.document.clear();\n delete Bokeh.index[id];\n }\n }\n }\n });\n // Destroy server and session\n var cmd = \"import bokeh.io.notebook as ion; ion.destroy_server('\" + server_id + \"')\";\n cell.notebook.kernel.execute(cmd);\n }\n }\n\n /**\n * Handle when a new output is added\n */\n function handleAddOutput(event, handle) {\n var output_area = handle.output_area;\n var output = handle.output;\n\n // limit handleAddOutput to display_data with EXEC_MIME_TYPE content only\n if ((output.output_type != \"display_data\") || (!output.data.hasOwnProperty(EXEC_MIME_TYPE))) {\n return\n }\n\n var toinsert = output_area.element.find(\".\" + CLASS_NAME.split(' ')[0]);\n\n if (output.metadata[EXEC_MIME_TYPE][\"id\"] !== undefined) {\n toinsert[toinsert.length - 1].firstChild.textContent = output.data[JS_MIME_TYPE];\n // store reference to embed id on output_area\n output_area._bokeh_element_id = output.metadata[EXEC_MIME_TYPE][\"id\"];\n }\n if (output.metadata[EXEC_MIME_TYPE][\"server_id\"] !== undefined) {\n var bk_div = document.createElement(\"div\");\n bk_div.innerHTML = output.data[HTML_MIME_TYPE];\n var script_attrs = bk_div.children[0].attributes;\n for (var i = 0; i < script_attrs.length; i++) {\n toinsert[toinsert.length - 1].firstChild.setAttribute(script_attrs[i].name, script_attrs[i].value);\n }\n // store reference to server id on output_area\n output_area._bokeh_server_id = output.metadata[EXEC_MIME_TYPE][\"server_id\"];\n }\n }\n\n function register_renderer(events, OutputArea) {\n\n function append_mime(data, metadata, element) {\n // create a DOM node to render to\n var toinsert = this.create_output_subarea(\n metadata,\n CLASS_NAME,\n EXEC_MIME_TYPE\n );\n this.keyboard_manager.register_events(toinsert);\n // Render to node\n var props = {data: data, metadata: metadata[EXEC_MIME_TYPE]};\n render(props, toinsert[toinsert.length - 1]);\n element.append(toinsert);\n return toinsert\n }\n\n /* Handle when an output is cleared or removed */\n events.on('clear_output.CodeCell', handleClearOutput);\n events.on('delete.Cell', handleClearOutput);\n\n /* Handle when a new output is added */\n events.on('output_added.OutputArea', handleAddOutput);\n\n /**\n * Register the mime type and append_mime function with output_area\n */\n OutputArea.prototype.register_mime_type(EXEC_MIME_TYPE, append_mime, {\n /* Is output safe? */\n safe: true,\n /* Index of renderer in `output_area.display_order` */\n index: 0\n });\n }\n\n // register the mime type if in Jupyter Notebook environment and previously unregistered\n if (root.Jupyter !== undefined) {\n var events = require('base/js/events');\n var OutputArea = require('notebook/js/outputarea').OutputArea;\n\n if (OutputArea.prototype.mime_types().indexOf(EXEC_MIME_TYPE) == -1) {\n register_renderer(events, OutputArea);\n }\n }\n\n \n if (typeof (root._bokeh_timeout) === \"undefined\" || force === true) {\n root._bokeh_timeout = Date.now() + 5000;\n root._bokeh_failed_load = false;\n }\n\n var NB_LOAD_WARNING = {'data': {'text/html':\n \"
\\n\"+\n \"

\\n\"+\n \"BokehJS does not appear to have successfully loaded. If loading BokehJS from CDN, this \\n\"+\n \"may be due to a slow or bad network connection. Possible fixes:\\n\"+\n \"

\\n\"+\n \"
    \\n\"+\n \"
  • re-rerun `output_notebook()` to attempt to load from CDN again, or
  • \\n\"+\n \"
  • use INLINE resources instead, as so:
  • \\n\"+\n \"
\\n\"+\n \"\\n\"+\n \"from bokeh.resources import INLINE\\n\"+\n \"output_notebook(resources=INLINE)\\n\"+\n \"\\n\"+\n \"
\"}};\n\n function display_loaded() {\n var el = document.getElementById(\"1492\");\n if (el != null) {\n el.textContent = \"BokehJS is loading...\";\n }\n if (root.Bokeh !== undefined) {\n if (el != null) {\n el.textContent = \"BokehJS \" + root.Bokeh.version + \" successfully loaded.\";\n }\n } else if (Date.now() < root._bokeh_timeout) {\n setTimeout(display_loaded, 100)\n }\n }\n\n\n function run_callbacks() {\n try {\n root._bokeh_onload_callbacks.forEach(function(callback) {\n if (callback != null)\n callback();\n });\n } finally {\n delete root._bokeh_onload_callbacks\n }\n console.debug(\"Bokeh: all callbacks have finished\");\n }\n\n function load_libs(css_urls, js_urls, callback) {\n if (css_urls == null) css_urls = [];\n if (js_urls == null) js_urls = [];\n\n root._bokeh_onload_callbacks.push(callback);\n if (root._bokeh_is_loading > 0) {\n console.debug(\"Bokeh: BokehJS is being loaded, scheduling callback at\", now());\n return null;\n }\n if (js_urls == null || js_urls.length === 0) {\n run_callbacks();\n return null;\n }\n console.debug(\"Bokeh: BokehJS not loaded, scheduling load and callback at\", now());\n root._bokeh_is_loading = css_urls.length + js_urls.length;\n\n function on_load() {\n root._bokeh_is_loading--;\n if (root._bokeh_is_loading === 0) {\n console.debug(\"Bokeh: all BokehJS libraries/stylesheets loaded\");\n run_callbacks()\n }\n }\n\n function on_error() {\n console.error(\"failed to load \" + url);\n }\n\n for (var i = 0; i < css_urls.length; i++) {\n var url = css_urls[i];\n const element = document.createElement(\"link\");\n element.onload = on_load;\n element.onerror = on_error;\n element.rel = \"stylesheet\";\n element.type = \"text/css\";\n element.href = url;\n console.debug(\"Bokeh: injecting link tag for BokehJS stylesheet: \", url);\n document.body.appendChild(element);\n }\n\n for (var i = 0; i < js_urls.length; i++) {\n var url = js_urls[i];\n var element = document.createElement('script');\n element.onload = on_load;\n element.onerror = on_error;\n element.async = false;\n element.src = url;\n console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n document.head.appendChild(element);\n }\n };var element = document.getElementById(\"1492\");\n if (element == null) {\n console.error(\"Bokeh: ERROR: autoload.js configured with elementid '1492' but no matching script tag was found. \")\n return false;\n }\n\n function inject_raw_css(css) {\n const element = document.createElement(\"style\");\n element.appendChild(document.createTextNode(css));\n document.body.appendChild(element);\n }\n\n \n var js_urls = [\"https://cdn.pydata.org/bokeh/release/bokeh-1.4.0.min.js\", \"https://cdn.pydata.org/bokeh/release/bokeh-widgets-1.4.0.min.js\", \"https://cdn.pydata.org/bokeh/release/bokeh-tables-1.4.0.min.js\", \"https://cdn.pydata.org/bokeh/release/bokeh-gl-1.4.0.min.js\"];\n var css_urls = [];\n \n\n var inline_js = [\n function(Bokeh) {\n Bokeh.set_log_level(\"info\");\n },\n function(Bokeh) {\n \n \n }\n ];\n\n function run_inline_js() {\n \n if (root.Bokeh !== undefined || force === true) {\n \n for (var i = 0; i < inline_js.length; i++) {\n inline_js[i].call(root, root.Bokeh);\n }\n if (force === true) {\n display_loaded();\n }} else if (Date.now() < root._bokeh_timeout) {\n setTimeout(run_inline_js, 100);\n } else if (!root._bokeh_failed_load) {\n console.log(\"Bokeh: BokehJS failed to load within specified timeout.\");\n root._bokeh_failed_load = true;\n } else if (force !== true) {\n var cell = $(document.getElementById(\"1492\")).parents('.cell').data().cell;\n cell.output_area.append_execute_result(NB_LOAD_WARNING)\n }\n\n }\n\n if (root._bokeh_is_loading === 0) {\n console.debug(\"Bokeh: BokehJS loaded, going straight to plotting\");\n run_inline_js();\n } else {\n load_libs(css_urls, js_urls, function() {\n console.debug(\"Bokeh: BokehJS plotting callback run at\", now());\n run_inline_js();\n });\n }\n}(window));", + "application/vnd.bokehjs_load.v0+json": "\n(function(root) {\n function now() {\n return new Date();\n }\n\n var force = true;\n\n if (typeof root._bokeh_onload_callbacks === \"undefined\" || force === true) {\n root._bokeh_onload_callbacks = [];\n root._bokeh_is_loading = undefined;\n }\n\n \n\n \n if (typeof (root._bokeh_timeout) === \"undefined\" || force === true) {\n root._bokeh_timeout = Date.now() + 5000;\n root._bokeh_failed_load = false;\n }\n\n var NB_LOAD_WARNING = {'data': {'text/html':\n \"
\\n\"+\n \"

\\n\"+\n \"BokehJS does not appear to have successfully loaded. If loading BokehJS from CDN, this \\n\"+\n \"may be due to a slow or bad network connection. Possible fixes:\\n\"+\n \"

\\n\"+\n \"
    \\n\"+\n \"
  • re-rerun `output_notebook()` to attempt to load from CDN again, or
  • \\n\"+\n \"
  • use INLINE resources instead, as so:
  • \\n\"+\n \"
\\n\"+\n \"\\n\"+\n \"from bokeh.resources import INLINE\\n\"+\n \"output_notebook(resources=INLINE)\\n\"+\n \"\\n\"+\n \"
\"}};\n\n function display_loaded() {\n var el = document.getElementById(\"1492\");\n if (el != null) {\n el.textContent = \"BokehJS is loading...\";\n }\n if (root.Bokeh !== undefined) {\n if (el != null) {\n el.textContent = \"BokehJS \" + root.Bokeh.version + \" successfully loaded.\";\n }\n } else if (Date.now() < root._bokeh_timeout) {\n setTimeout(display_loaded, 100)\n }\n }\n\n\n function run_callbacks() {\n try {\n root._bokeh_onload_callbacks.forEach(function(callback) {\n if (callback != null)\n callback();\n });\n } finally {\n delete root._bokeh_onload_callbacks\n }\n console.debug(\"Bokeh: all callbacks have finished\");\n }\n\n function load_libs(css_urls, js_urls, callback) {\n if (css_urls == null) css_urls = [];\n if (js_urls == null) js_urls = [];\n\n root._bokeh_onload_callbacks.push(callback);\n if (root._bokeh_is_loading > 0) {\n console.debug(\"Bokeh: BokehJS is being loaded, scheduling callback at\", now());\n return null;\n }\n if (js_urls == null || js_urls.length === 0) {\n run_callbacks();\n return null;\n }\n console.debug(\"Bokeh: BokehJS not loaded, scheduling load and callback at\", now());\n root._bokeh_is_loading = css_urls.length + js_urls.length;\n\n function on_load() {\n root._bokeh_is_loading--;\n if (root._bokeh_is_loading === 0) {\n console.debug(\"Bokeh: all BokehJS libraries/stylesheets loaded\");\n run_callbacks()\n }\n }\n\n function on_error() {\n console.error(\"failed to load \" + url);\n }\n\n for (var i = 0; i < css_urls.length; i++) {\n var url = css_urls[i];\n const element = document.createElement(\"link\");\n element.onload = on_load;\n element.onerror = on_error;\n element.rel = \"stylesheet\";\n element.type = \"text/css\";\n element.href = url;\n console.debug(\"Bokeh: injecting link tag for BokehJS stylesheet: \", url);\n document.body.appendChild(element);\n }\n\n for (var i = 0; i < js_urls.length; i++) {\n var url = js_urls[i];\n var element = document.createElement('script');\n element.onload = on_load;\n element.onerror = on_error;\n element.async = false;\n element.src = url;\n console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n document.head.appendChild(element);\n }\n };var element = document.getElementById(\"1492\");\n if (element == null) {\n console.error(\"Bokeh: ERROR: autoload.js configured with elementid '1492' but no matching script tag was found. \")\n return false;\n }\n\n function inject_raw_css(css) {\n const element = document.createElement(\"style\");\n element.appendChild(document.createTextNode(css));\n document.body.appendChild(element);\n }\n\n \n var js_urls = [\"https://cdn.pydata.org/bokeh/release/bokeh-1.4.0.min.js\", \"https://cdn.pydata.org/bokeh/release/bokeh-widgets-1.4.0.min.js\", \"https://cdn.pydata.org/bokeh/release/bokeh-tables-1.4.0.min.js\", \"https://cdn.pydata.org/bokeh/release/bokeh-gl-1.4.0.min.js\"];\n var css_urls = [];\n \n\n var inline_js = [\n function(Bokeh) {\n Bokeh.set_log_level(\"info\");\n },\n function(Bokeh) {\n \n \n }\n ];\n\n function run_inline_js() {\n \n if (root.Bokeh !== undefined || force === true) {\n \n for (var i = 0; i < inline_js.length; i++) {\n inline_js[i].call(root, root.Bokeh);\n }\n if (force === true) {\n display_loaded();\n }} else if (Date.now() < root._bokeh_timeout) {\n setTimeout(run_inline_js, 100);\n } else if (!root._bokeh_failed_load) {\n console.log(\"Bokeh: BokehJS failed to load within specified timeout.\");\n root._bokeh_failed_load = true;\n } else if (force !== true) {\n var cell = $(document.getElementById(\"1492\")).parents('.cell').data().cell;\n cell.output_area.append_execute_result(NB_LOAD_WARNING)\n }\n\n }\n\n if (root._bokeh_is_loading === 0) {\n console.debug(\"Bokeh: BokehJS loaded, going straight to plotting\");\n run_inline_js();\n } else {\n load_libs(css_urls, js_urls, function() {\n console.debug(\"Bokeh: BokehJS plotting callback run at\", now());\n run_inline_js();\n });\n }\n}(window));" + }, + "metadata": {} + }, + { + "output_type": "stream", + "name": "stderr", + "text": "D:\\anaconda3\\lib\\site-packages\\bokeh\\models\\graphs.py:164: UserWarning: Node keys in 'layout_function' don't match node keys in the graph. These nodes may not be displayed correctly.\n warn(\"Node keys in 'layout_function' don't match node keys in the graph. \"\n" + }, + { + "output_type": "display_data", + "data": { + "text/html": "\n\n\n\n\n\n
\n" + }, + "metadata": {} + }, + { + "output_type": "display_data", + "data": { + "application/javascript": "(function(root) {\n function embed_document(root) {\n \n var docs_json = {\"d2bf46f9-7fc1-4914-8741-9975303e6e0b\":{\"roots\":{\"references\":[{\"attributes\":{\"plot_height\":500,\"plot_width\":500,\"renderers\":[{\"id\":\"1532\",\"type\":\"GraphRenderer\"},{\"id\":\"1500\",\"type\":\"GraphRenderer\"},{\"id\":\"1516\",\"type\":\"GraphRenderer\"}],\"title\":{\"id\":\"1672\",\"type\":\"Title\"},\"toolbar\":{\"id\":\"1613\",\"type\":\"Toolbar\"},\"x_range\":{\"id\":\"1574\",\"type\":\"Range1d\"},\"x_scale\":{\"id\":\"1671\",\"type\":\"LinearScale\"},\"y_range\":{\"id\":\"1575\",\"type\":\"Range1d\"},\"y_scale\":{\"id\":\"1669\",\"type\":\"LinearScale\"}},\"id\":\"1495\",\"type\":\"Plot\"},{\"attributes\":{\"callback\":null,\"overlay\":{\"id\":\"1701\",\"type\":\"BoxAnnotation\"}},\"id\":\"1610\",\"type\":\"BoxSelectTool\"},{\"attributes\":{\"line_alpha\":{\"value\":0.2},\"line_join\":\"round\",\"line_width\":{\"value\":4}},\"id\":\"1551\",\"type\":\"MultiLine\"},{\"attributes\":{},\"id\":\"1505\",\"type\":\"MultiLine\"},{\"attributes\":{},\"id\":\"1622\",\"type\":\"EdgesAndLinkedNodes\"},{\"attributes\":{},\"id\":\"1703\",\"type\":\"Selection\"},{\"attributes\":{},\"id\":\"1706\",\"type\":\"UnionRenderers\"},{\"attributes\":{\"callback\":null},\"id\":\"1609\",\"type\":\"TapTool\"},{\"attributes\":{\"callback\":null,\"data\":{\"end\":[39,40,19,30,31,30,32,35,19,20,25,26,19,21,23,25,28,30,33,35,27,32,37,37,39,37,38,21,32,33,39,21,22,27,28,23,24,28,29,25,27,35,36,23,33,34,3,7,6,3,14,7,13,7,15,13,14,7,18,7,16,18,14,7,17,7,6,17,10,7,9,17,15,15,7,16,15,10,7,4,7,3,4,10,7,9,4,13,13,7,18,13,10,7,4,7,17,4,14,7,10,11,12,10,5,11,14,11,1,14,8,11],\"start\":[1,1,3,3,3,4,4,4,6,6,6,6,7,7,7,7,7,7,7,7,9,9,10,11,11,12,12,13,13,13,14,15,15,15,15,16,16,16,16,17,17,17,17,18,18,18,19,19,19,20,20,20,21,21,21,22,22,22,23,23,23,24,24,24,25,25,25,26,26,26,27,27,27,28,28,28,29,29,29,30,30,30,31,31,31,32,32,32,33,33,33,34,34,34,35,35,35,36,36,36,37,37,37,38,38,38,39,39,39,40,40,40],\"weight\":[1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1],\"xs\":[[132.03573345539652,137.48571551830955,135.23197468429638,140.14899161905018,138.47610923799442,137.48571551830955],[132.03573345539652,127.27675598448872,129.55660111479048,124.65816325015204,126.23906204294478,127.27675598448872],[55.37320691609743,50.02349772839256,47.92888164373186,48.886251192130366,52.6575761427258,50.02349772839256],[55.37320691609743,35.488555025426884,37.324340226000736,32.33770424277019,35.14740203472472,35.488555025426884],[55.37320691609743,71.88028325263481,71.44407519751749,75.33873507217703,70.67594599401349,71.88028325263481],[14.953201438630577,28.893121267990654,28.51925321889611,32.33770424277019,27.633022804922984,28.893121267990654],[14.953201438630577,-3.918316195499258,-3.056652218581606,-7.418036529321104,-3.1198587965443885,-3.918316195499258],[14.953201438630577,11.275678178896838,9.276610491714836,9.94954472387104,13.9038082727723,11.275678178896838],[56.84426959995666,49.640507154548374,52.260659602009184,48.886251192130366,47.378142280565484,49.640507154548374],[56.84426959995666,74.51973305841916,72.368266199359,77.33719537503133,75.33471329244226,74.51973305841916],[56.84426959995666,28.62390979854623,30.753623031226596,25.777306584499808,27.844506417369114,28.62390979854623],[56.84426959995666,61.7738796287991,59.15178547248106,62.55342839535837,64.02618836015239,61.7738796287991],[0.04069251554409696,46.08933061745672,43.923031062844075,48.886251192130366,46.92888769274593,46.08933061745672],[0.04069251554409696,-22.28375935763042,-20.402176115395527,-25.39627415162268,-22.688895384272154,-22.28375935763042],[0.04069251554409696,-54.61654620677044,-53.28258592252564,-58.03935844755277,-54.32686710714607,-54.61654620677044],[0.04069251554409696,24.190108556693588,21.58549870065425,25.777306584499808,26.041817860011808,24.190108556693588],[0.04069251554409696,-42.563770301917096,-40.51280838184761,-45.506998465856284,-43.218587523850196,-42.563770301917096],[0.04069251554409696,28.911183617715437,27.58890451236131,32.33770424277019,28.608064236354075,28.911183617715437],[0.04069251554409696,-32.64408758813847,-32.258836666935615,-36.09134666156681,-31.394102567582724,-32.64408758813847],[0.04069251554409696,8.516345666633363,5.895629109223213,9.94954472387104,10.457212360668189,8.516345666633363],[-11.180744283387114,-15.141185700754612,-15.74076443231963,-18.124619009412104,-13.12639062709301,-15.141185700754612],[-11.180744283387114,-9.704205506124369,-8.353454451246671,-7.418036529321104,-12.139419782411263,-9.704205506124369],[162.0928482698882,163.03313138438057,164.4906987937537,165.18968390928575,160.55258539292248,163.03313138438057],[153.46703847320822,162.0196513291495,160.20811366917897,165.18968390928575,162.32745773447158,162.0196513291495],[153.46703847320822,143.3627785310952,145.11517061933347,140.14899161905018,143.13487292785524,143.3627785310952],[179.01811297167205,168.52696821682778,170.07190747532397,165.18968390928575,168.5650974574834,168.52696821682778],[179.01811297167205,186.00185613935238,184.44067231513458,189.3309902751563,185.9838375660005,186.00185613935238],[-24.382793002770676,-25.12025997969024,-22.5625811572922,-25.39627415162268,-27.54700918967311,-25.12025997969024],[-24.382793002770676,-10.445402055435622,-12.418025253589484,-7.418036529321104,-9.908834811213909,-10.445402055435622],[-24.382793002770676,-33.04403499100526,-33.550987383134306,-36.09134666156681,-31.091565025841895,-33.04403499100526],[136.34159815391814,137.75108154444413,139.0034294936812,140.14899161905018,135.36126505699207,137.75108154444413],[-40.93392405496524,-28.86332498637266,-29.343406689401224,-25.39627415162268,-30.027867611288496,-28.86332498637266],[-40.93392405496524,-70.40572548458901,-69.47430118827627,-73.90281181788369,-69.67827786503236,-70.40572548458901],[-40.93392405496524,-20.282480482135117,-22.762605148666367,-18.124619009412104,-18.825955307945932,-20.282480482135117],[-40.93392405496524,-44.66179151036543,-42.035316344978305,-45.506998465856284,-46.88733574413318,-44.66179151036543],[-73.84182523293367,-59.76455453158061,-62.34893133915876,-58.03935844755277,-57.99853879959689,-59.76455453158061],[-73.84182523293367,-89.46140956766538,-87.89067520354479,-92.78563945472774,-89.45526790529505,-89.46140956766538],[-73.84182523293367,-48.77026508965301,-50.44805976181296,-45.506998465856284,-48.64042801427059,-48.77026508965301],[-73.84182523293367,-90.59643259521008,-88.15037839298485,-92.85347895877348,-91.97183812923299,-90.59643259521008],[4.072716776001942,22.455226201870726,20.880356778725407,25.777306584499808,22.45423923378646,22.455226201870726],[4.072716776001942,-15.81066097453994,-13.386161873155405,-18.124619009412104,-17.137514884267627,-15.81066097453994],[4.072716776001942,9.018948555378712,11.208242697426629,9.94954472387104,6.388218400090251,9.018948555378712],[4.072716776001942,0.7198227018210331,-1.5735121321395704,0.0457860875360908,3.332892395930647,0.7198227018210331],[-61.44792512437408,-58.62696705502862,-56.30182044798803,-58.03935844755277,-61.230850680136044,-58.62696705502862],[-61.44792512437408,-39.5869926297507,-40.29142565641749,-36.09134666156681,-40.540748269812994,-39.5869926297507],[-61.44792512437408,-77.89322022593349,-78.68138769006264,-80.73270969198812,-75.75811737568038,-77.89322022593349],[48.886251192130366,54.235960379835234,56.330576464495934,55.37320691609743,51.601881965501995,54.235960379835234],[48.886251192130366,2.837613090217748,5.003912644830385,0.04069251554409696,1.9980560149285311,2.837613090217748],[48.886251192130366,56.090013637538654,53.46986119007784,56.84426959995666,58.35237851152154,56.090013637538654],[77.33719537503133,56.420425921635946,59.05427622973534,55.37320691609743,54.28333263709447,56.420425921635946],[77.33719537503133,135.43198824009843,137.63034428393814,136.34159815391814,132.80215118703518,135.43198824009843],[77.33719537503133,2.351808130232011,4.7774201985448554,0.04069251554409696,1.0224929279794017,2.351808130232011],[-25.39627415162268,-24.658807174703117,-27.216485997101156,-24.382793002770676,-22.23205796472025,-24.658807174703117],[-25.39627415162268,-3.071822278448165,-4.953405520683055,0.04069251554409696,-2.6666862518064307,-3.071822278448165],[-25.39627415162268,-37.46687322021526,-36.986791517186695,-40.93392405496524,-36.30233059529942,-37.46687322021526],[-73.90281181788369,-27.784182179216522,-29.180174735995045,-24.382793002770676,-28.001666798002113,-27.784182179216522],[-73.90281181788369,133.29594285985127,133.80537995477198,136.34159815391814,131.34177390782867,133.29594285985127],[-73.90281181788369,-3.4120135122320363,-4.640515696700918,0.04069251554409696,-3.821331077507435,-3.4120135122320363],[-58.03935844755277,-60.86031651689823,-63.185463123938824,-61.44792512437408,-58.25643289179081,-60.86031651689823],[-58.03935844755277,-3.3821197252382387,-4.716080009483036,0.04069251554409696,-3.6717988248626034,-3.3821197252382387],[-58.03935844755277,-72.11662914890584,-69.53225234132769,-73.84182523293367,-73.88264488088956,-72.11662914890584],[-92.78563945472774,-63.20104038600919,-65.78062004222815,-61.44792512437408,-61.4530654989149,-63.20104038600919],[-92.78563945472774,133.05912679399603,133.14820227746003,136.34159815391814,131.4129837878408,133.05912679399603],[-92.78563945472774,-3.088099170526875,-4.950647549403883,0.04069251554409696,-2.7097190860422313,-3.088099170526875],[25.777306584499808,7.394797158631023,8.969666581776345,4.072716776001942,7.395784126715288,7.394797158631023],[25.777306584499808,1.6278905433503157,4.232500399389655,0.04069251554409696,-0.22381875996790263,1.6278905433503157],[25.777306584499808,53.99766638591024,51.86795315322988,56.84426959995666,54.777069767087355,53.99766638591024],[62.55342839535837,6.635135354604422,8.945827899174915,4.072716776001942,5.5399473219688575,6.635135354604422],[62.55342839535837,160.63900266266634,162.5682956703021,162.0928482698882,158.0200659293756,160.63900266266634],[62.55342839535837,1.9257494476415926,4.4792692952154125,0.04069251554409696,0.2664219952338935,1.9257494476415926],[-18.124619009412104,-14.164177592044606,-13.56459886047959,-11.180744283387114,-16.17897266570621,-14.164177592044606],[-18.124619009412104,1.7587587411297774,-0.6657403602547571,4.072716776001942,3.085612650857462,1.7587587411297774],[-18.124619009412104,-38.776062582242226,-36.29593791571098,-40.93392405496524,-40.232587756431414,-38.776062582242226],[-45.506998465856284,-41.77913101045609,-44.40560617584322,-40.93392405496524,-39.55358677668834,-41.77913101045609],[-45.506998465856284,-2.9025356483950917,-4.953497568464576,0.04069251554409696,-2.247718426461995,-2.9025356483950917],[-45.506998465856284,-70.57855860913695,-68.900763936977,-73.84182523293367,-70.70839568451937,-70.57855860913695],[-92.85347895877348,-43.40936139608874,-45.763847801094585,-40.93392405496524,-42.22911923137749,-43.40936139608874],[-92.85347895877348,158.67819028870096,158.41700943325836,162.0928482698882,157.31959980096536,158.67819028870096],[-92.85347895877348,-2.858440542305954,-4.94667885923253,0.04069251554409696,-2.1454300441061465,-2.858440542305954],[32.33770424277019,18.39778441341011,18.771652462504655,14.953201438630577,19.65788287647778,18.39778441341011],[32.33770424277019,3.4672131405988456,4.7894922459529745,0.04069251554409696,3.7703325219602073,3.4672131405988456],[32.33770424277019,52.222356133440734,50.38657093286688,55.37320691609743,52.5635091241429,52.222356133440734],[75.33873507217703,18.441708215832953,19.471544035134638,14.953201438630577,19.06667452878777,18.441708215832953],[75.33873507217703,160.20014912736306,161.8541647001615,162.0928482698882,157.64831601347834,160.20014912736306],[75.33873507217703,3.475319215487818,4.77087309233263,0.04069251554409696,3.80900900923435,3.475319215487818],[-7.418036529321104,-8.89457530658385,-10.245326361461546,-11.180744283387114,-6.459361030296954,-8.89457530658385],[-7.418036529321104,11.45348110480873,10.591817127891078,14.953201438630577,10.65502370585386,11.45348110480873],[-7.418036529321104,-21.355427476656157,-19.3828042785023,-24.382793002770676,-21.891994720877868,-21.355427476656157],[-36.09134666156681,-27.430104673332224,-26.923152281203183,-24.382793002770676,-29.38257463849559,-27.430104673332224],[-36.09134666156681,-3.4065665578842412,-3.7918174790870944,0.04069251554409696,-4.656551578439989,-3.4065665578842412],[-36.09134666156681,-57.95227915619019,-57.2478461295234,-61.44792512437408,-56.9985235161279,-57.95227915619019],[-80.73270969198812,-27.647452496167382,-27.52051580667918,-24.382793002770676,-29.323007501683836,-27.647452496167382],[-80.73270969198812,159.06986571486314,159.61285308714693,162.0928482698882,157.0929014873469,159.06986571486314],[-80.73270969198812,-3.3414571303355913,-3.5003533661997954,0.04069251554409696,-4.786911639090164,-3.3414571303355913],[9.94954472387104,13.62706798360478,15.626135670786784,14.953201438630577,10.998937889729318,13.62706798360478],[9.94954472387104,1.473891572781776,4.094608130191925,0.04069251554409696,-0.4669751212530506,1.473891572781776],[9.94954472387104,5.00331294449427,2.8140188024463515,4.072716776001942,7.634043099782731,5.00331294449427],[0.0457860875360908,14.022578337862008,16.211860786153494,14.953201438630577,11.391847100781295,14.022578337862008],[0.0457860875360908,134.33807585857866,135.91275750563298,136.34159815391814,131.8130067884533,134.33807585857866],[0.0457860875360908,0.04097149463394395,2.541037654715089,0.04069251554409696,-2.4589623294013743,0.04097149463394395],[165.18968390928575,164.2494007947934,162.79183338542026,162.0928482698882,166.72994678625147,164.2494007947934],[165.18968390928575,156.63707105334447,158.448608713315,153.46703847320822,156.3292646480224,156.63707105334447],[165.18968390928575,175.68082866413002,174.13588940563383,179.01811297167205,175.6426994234744,175.68082866413002],[189.3309902751563,165.56000161852532,166.72403827033122,162.0928482698882,166.04063792297669,165.56000161852532],[189.3309902751563,227.42091682166406,224.91169570598004,229.4826153772355,228.95215412257508,227.42091682166406],[189.3309902751563,156.7515410629196,158.39423487030933,153.46703847320822,156.66687830892377,156.7515410629196],[140.14899161905018,138.7395082285242,137.4871602792871,136.34159815391814,141.12932471597625,138.7395082285242],[140.14899161905018,150.2532515611632,148.50085947292493,153.46703847320822,150.48115716440316,150.2532515611632],[140.14899161905018,134.69900955613716,136.95275039015033,132.03573345539652,133.70861583645228,134.69900955613716],[124.65816325015204,134.39889086690263,131.85859413225688,136.34159815391814,136.01764828222917,134.39889086690263],[124.65816325015204,-32.632546293932855,-30.55982794130896,-35.550380516396345,-33.321165775240885,-32.632546293932855],[124.65816325015204,150.55482719626596,148.47739868060268,153.46703847320822,151.25082413147229,150.55482719626596]],\"ys\":[[142.29992410862027,137.6528908604753,136.2891595377265,135.3819966728867,140.09383968164167,137.6528908604753],[142.29992410862027,146.52038399393294,147.84001161162814,148.84266134422492,144.09916484829003,146.52038399393294],[-17.857314064199937,-33.428254682918556,-31.83085231487683,-36.73834083221431,-33.45549022382283,-33.428254682918556],[-17.857314064199937,-8.240431902877276,-6.351251243200004,-6.716575168984064,-10.852466646995282,-8.240431902877276],[-17.857314064199937,-15.290935336920226,-17.88878702633504,-14.753244894467425,-12.948141569846154,-15.290935336920226],[-9.847483223963055,-7.336936458765253,-9.944489631648,-6.716575168984064,-5.023656810534383,-7.336936458765253],[-9.847483223963055,-9.608903350204816,-7.119597009388745,-9.564658745630869,-12.119197486277095,-9.608903350204816],[-9.847483223963055,-18.829715880801736,-17.114245318649928,-22.068754327541964,-19.008721682972496,-18.829715880801736],[-72.79853161574077,-40.1561029572249,-40.4279706081321,-36.73834083221431,-41.505479125872114,-40.1561029572249],[-72.79853161574077,-85.82561943880435,-87.34558694566442,-87.90213240396263,-83.32064077907562,-85.82561943880435],[-72.79853161574077,-52.61046255168819,-51.060161802126736,-50.57408092198795,-55.12673782219305,-52.61046255168819],[-72.79853161574077,-94.37541618451317,-94.12296202442182,-97.7874982058831,-93.00932092933716,-94.37541618451317],[0.007758933055522639,-34.63424119128302,-36.132993041066605,-36.73834083221431,-32.137392220104246,-34.63424119128302],[0.007758933055522639,11.488773595161817,13.332344958056535,13.089477083375455,8.885895252353304,11.488773595161817],[0.007758933055522639,11.680694925472721,13.95218360640472,12.411691754707025,9.062451833858526,11.680694925472721],[0.007758933055522639,-47.45465751043766,-47.848508199617434,-50.57408092198795,-45.58108244560855,-47.45465751043766],[0.007758933055522639,27.424860937609814,29.077938694392458,29.318906337011622,24.87332703162219,27.424860937609814],[0.007758933055522639,-6.0031633621891265,-8.281471689674353,-6.716575168984064,-3.386442225310428,-6.0031633621891265],[0.007758933055522639,-5.731453089723418,-3.1255573521205116,-6.336766959270443,-8.050213171303852,-5.731453089723418],[0.007758933055522639,-18.87564605153048,-19.142020962625622,-22.068754327541964,-17.094593738000366,-18.87564605153048],[-13.926469651525597,-16.35583584116285,-13.79075958260843,-18.185897504821483,-18.05280716640485,-16.35583584116285],[-13.926469651525597,-12.214834477446084,-14.476378740840332,-9.564658745630869,-11.210423059692813,-12.214834477446084],[120.19280405820047,121.3947497765151,119.20052824834663,124.15142915709694,122.28131756963974,121.3947497765151],[129.6375000047943,125.63497000280178,123.72252597118853,124.15142915709694,128.25114394281175,125.63497000280178],[129.6375000047943,133.99578828885194,135.96257064504303,135.3819966728867,131.37144648497872,133.99578828885194],[119.78087829435556,123.09666214460853,125.23026790835728,124.15142915709694,120.46271889758295,123.09666214460853],[119.78087829435556,117.51483897710412,115.3930906568396,116.43462330149798,120.14899656513089,117.51483897710412],[0.2780454482461787,9.60037746070882,8.969988763950049,13.089477083375455,8.575682804046561,9.60037746070882],[0.2780454482461787,-7.808225435967968,-9.554040026825163,-9.564658745630869,-5.229232132375854,-7.808225435967968],[0.2780454482461787,-4.615171309165756,-2.0301935259615593,-6.336766959270443,-6.3834959124780575,-4.615171309165756],[131.33388525476965,132.83248156720427,130.51499683552075,135.3819966728867,133.94058265638654,132.83248156720427],[10.942280437411275,12.610354438054365,10.020251655159091,13.089477083375455,14.97318141908763,12.610354438054365],[10.942280437411275,12.145594190199423,14.60964768957458,12.288377863928684,9.613810070582192,12.145594190199423],[10.942280437411275,-15.43024261631718,-16.317988360327202,-18.185897504821483,-13.235329113580041,-15.43024261631718],[10.942280437411275,25.922492757603205,25.720653531610623,29.318906337011622,24.513215023766552,25.922492757603205],[40.30582736768835,15.456966532400333,14.946959293239164,12.411691754707025,17.41152512756464,15.456966532400333],[40.30582736768835,45.45192193374828,47.566609718012266,46.54713682497346,42.81770987935175,45.45192193374828],[40.30582736768835,30.584248560291282,28.553456619787198,29.318906337011622,33.21526608235395,30.584248560291282],[40.30582736768835,60.16316876999366,61.14088534821095,62.838190585367364,57.91653340026323,60.16316876999366],[-43.37608195400387,-49.47236320344521,-51.583973292355225,-50.57408092198795,-46.83814417431368,-49.47236320344521],[-43.37608195400387,-20.811844612600037,-19.78183734324208,-18.185897504821483,-23.087491678773745,-20.811844612600037],[-43.37608195400387,-25.442771335677428,-26.907729364816596,-22.068754327541964,-25.578306266970415,-25.442771335677428],[-43.37608195400387,-60.46040352250944,-59.16436100511754,-63.89488669215859,-60.12727045409603,-60.46040352250944],[-7.602735517487976,8.96137059220341,7.723305923734008,12.411691754707025,8.562746791556652,8.96137059220341],[-7.602735517487976,-6.511292788647296,-9.049576653483086,-6.336766959270443,-4.055796698934666,-6.511292788647296],[-7.602735517487976,-19.454101930165354,-16.940558034381382,-21.50039115023293,-20.996971557316574,-19.454101930165354],[-36.73834083221431,-21.167400213495696,-22.76480258153742,-17.857314064199937,-21.14016467259142,-21.167400213495696],[-36.73834083221431,-2.096340707875775,-0.5975888580921834,0.007758933055522639,-4.593189679054541,-2.096340707875775],[-36.73834083221431,-69.38076949073019,-69.10890183982299,-72.79853161574077,-68.03139332208298,-69.38076949073019],[-87.90213240396263,-21.196974579048554,-21.24105884006488,-17.857314064199937,-22.73708599083419,-21.196974579048554],[-87.90213240396263,127.95415008693757,126.50282601146095,131.33388525476965,127.80226874548909,127.95415008693757],[-87.90213240396263,-2.620690156340295,-1.5933066049829008,0.007758933055522639,-4.89490034025135,-2.620690156340295],[13.089477083375455,3.7671450709128127,4.397533767671585,0.2780454482461787,4.791839727575071,3.7671450709128127],[13.089477083375455,1.60846242126916,-0.2351089416255568,0.007758933055522639,4.211340764077673,1.60846242126916],[13.089477083375455,11.421403082732365,14.011505865627639,10.942280437411275,9.0585761016991,11.421403082732365],[12.288377863928684,1.103001004841233,-1.1309004363516408,0.2780454482461787,3.7282269585709935,1.103001004841233],[12.288377863928684,129.60936102190934,127.02487176600917,131.33388525476965,131.3758079003904,129.60936102190934],[12.288377863928684,0.5811881664909605,-1.749024967602106,0.007758933055522639,3.1834122149352257,0.5811881664909605],[12.411691754707025,-4.152414354984362,-2.91434968651496,-7.602735517487976,-3.7537905543376024,-4.152414354984362],[12.411691754707025,0.7387557622898258,-1.5327329186421712,0.007758933055522639,3.3569988539040216,0.7387557622898258],[12.411691754707025,37.260552589995044,37.77055982915621,40.30582736768835,35.305993994830736,37.260552589995044],[46.54713682497346,-4.573447337168703,-5.107188533598162,-7.602735517487976,-2.6027381598337156,-4.573447337168703],[46.54713682497346,130.11923231203622,127.48651956169859,131.33388525476965,132.1757643615873,130.11923231203622],[46.54713682497346,1.5764088574086796,-0.2863912939460678,0.007758933055522639,4.183311114726748,1.5764088574086796],[-50.57408092198795,-44.47779967254661,-42.3661895836366,-43.37608195400387,-47.11201870167814,-44.47779967254661],[-50.57408092198795,-3.111664478494767,-2.7178137893149943,0.007758933055522639,-4.985239543323878,-3.111664478494767],[-50.57408092198795,-70.76214998604054,-72.31245073560198,-72.79853161574077,-68.24587471553568,-70.76214998604054],[-97.7874982058831,-45.760198358048115,-44.495362071404266,-43.37608195400387,-48.15596004083638,-45.760198358048115],[-97.7874982058831,117.00904323955191,115.21546041229458,120.19280405820047,117.29238270832583,117.00904323955191],[-97.7874982058831,-2.9412341769315415,-2.294204613780659,0.007758933055522639,-4.987143088205652,-2.9412341769315415],[-18.185897504821483,-15.75653131518423,-18.321607573738646,-13.926469651525597,-14.05955998994223,-15.75653131518423],[-18.185897504821483,-40.75013484622532,-41.780142115583274,-43.37608195400387,-38.47448778005161,-40.75013484622532],[-18.185897504821483,8.18662554890697,9.074371292916997,10.942280437411275,5.991712046169834,8.18662554890697],[29.318906337011622,14.33869401681969,14.540533242812275,10.942280437411275,15.747971750656344,14.33869401681969],[29.318906337011622,1.9018043324573302,0.24872657567468695,0.007758933055522639,4.453338238444955,1.9018043324573302],[29.318906337011622,39.04048514440869,41.07127708491278,40.30582736768835,36.40946762234602,39.04048514440869],[62.838190585367364,13.416590436213244,12.235275644894989,10.942280437411275,15.771614703642847,13.416590436213244],[62.838190585367364,119.42461731559537,116.80337802314324,120.19280405820047,121.68146085341074,119.42461731559537],[62.838190585367364,1.9686331036439912,0.36290224224027995,0.007758933055522639,4.50452089631178,1.9686331036439912],[-6.716575168984064,-9.227121934181866,-6.619568761299118,-9.847483223963055,-11.540401582412738,-9.227121934181866],[-6.716575168984064,-0.7056528737394145,1.5726554537458117,0.007758933055522639,-3.322374010618114,-0.7056528737394145],[-6.716575168984064,-16.333457330306725,-18.222637989983998,-17.857314064199937,-13.72142258618872,-16.333457330306725],[-14.753244894467425,-10.13089187840586,-7.706319946532549,-9.847483223963055,-12.68990105682166,-10.13089187840586],[-14.753244894467425,117.24870997752224,115.19850429211289,120.19280405820047,117.90236021000594,117.24870997752224],[-14.753244894467425,-0.6655459251132743,1.6280649877786708,0.007758933055522639,-3.2785445835695017,-0.6655459251132743],[-9.564658745630869,-11.276293919710382,-9.014749656316134,-13.926469651525597,-12.280705337463655,-11.276293919710382],[-9.564658745630869,-9.803238619389106,-12.292544960205177,-9.847483223963055,-7.292944483316828,-9.803238619389106],[-9.564658745630869,-1.4783878614167218,0.2674267294404743,0.2780454482461787,-4.057381165008836,-1.4783878614167218],[-6.336766959270443,-1.4435502018585085,-4.028527985062706,0.2780454482461787,0.3247744014537916,-1.4435502018585085],[-6.336766959270443,-0.5975549364915032,-3.2034506740944098,0.007758933055522639,1.7212051450889292,-0.5975549364915032],[-6.336766959270443,-7.428209688111123,-4.889925823275331,-7.602735517487976,-9.883705777823753,-7.428209688111123],[-21.50039115023293,-0.9836987382570799,-3.6148577878788277,0.2780454482461787,1.0489414884021775,-0.9836987382570799],[-21.50039115023293,118.42883793834044,115.85118870287705,120.19280405820047,120.16973521005573,118.42883793834044],[-21.50039115023293,-0.8928318579677351,-3.5222543903449166,0.007758933055522639,1.3093879609117796,-0.8928318579677351],[-22.068754327541964,-13.08652167070328,-14.80199223285509,-9.847483223963055,-12.907515868532524,-13.08652167070328],[-22.068754327541964,-3.185349342955961,-2.918974431860818,0.007758933055522639,-4.966401656486074,-3.185349342955961],[-22.068754327541964,-40.002064945868405,-38.537106916729236,-43.37608195400387,-39.86653001457542,-40.002064945868405],[-63.89488669215859,-13.221492803723594,-14.686468308347298,-9.847483223963055,-13.35700673582077,-13.221492803723594],[-63.89488669215859,128.46405975274385,126.35230963069463,131.33388525476965,129.21448433832248,128.46405975274385],[-63.89488669215859,-3.4922410558260015,-4.322168801332662,0.007758933055522639,-4.322567342889585,-3.4922410558260015],[124.15142915709694,122.94948343878231,125.14370496695078,120.19280405820047,122.06291564565767,122.94948343878231],[124.15142915709694,128.15395915908948,130.06640319070272,129.6375000047943,125.5377852190795,128.15395915908948],[124.15142915709694,120.83564530684397,118.70203954309522,119.78087829435556,123.46958855386956,120.83564530684397],[116.43462330149798,119.7144238150523,122.0775001026057,120.19280405820047,117.12442389026697,119.7144238150523],[116.43462330149798,64.1813320914418,63.37950900612305,61.35301119982526,66.32479265693941,64.1813320914418],[116.43462330149798,128.42835041182443,130.48763861960597,129.6375000047943,125.79549206287543,128.42835041182443],[135.3819966728867,133.88340036045207,136.2008850921356,131.33388525476965,132.7752992712698,133.88340036045207],[135.3819966728867,131.02370838882905,129.05692603263796,129.6375000047943,133.64805019270227,131.02370838882905],[135.3819966728867,140.02902992103165,141.39276124378046,142.29992410862027,137.5880810998653,140.02902992103165],[148.84266134422492,134.24522315975025,133.5480837422068,131.33388525476965,136.3233798665147,134.24522315975025],[148.84266134422492,253.04081924243636,254.6665343153322,254.9737557261887,250.49819971181293,253.04081924243636],[148.84266134422492,131.57889782040303,129.95920598864808,129.6375000047943,134.1195078128513,131.57889782040303]]},\"selected\":{\"id\":\"1705\",\"type\":\"Selection\"},\"selection_policy\":{\"id\":\"1704\",\"type\":\"UnionRenderers\"}},\"id\":\"1538\",\"type\":\"ColumnDataSource\"},{\"attributes\":{\"data_source\":{\"id\":\"1506\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"1505\",\"type\":\"MultiLine\"},\"hover_glyph\":null,\"muted_glyph\":null,\"view\":{\"id\":\"1508\",\"type\":\"CDSView\"}},\"id\":\"1507\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"source\":{\"id\":\"1534\",\"type\":\"ColumnDataSource\"}},\"id\":\"1536\",\"type\":\"CDSView\"},{\"attributes\":{\"callback\":null,\"end\":263.7927870744905,\"start\":-106.60652955418487},\"id\":\"1575\",\"type\":\"Range1d\"},{\"attributes\":{\"source\":{\"id\":\"1518\",\"type\":\"ColumnDataSource\"}},\"id\":\"1520\",\"type\":\"CDSView\"},{\"attributes\":{},\"id\":\"1707\",\"type\":\"Selection\"},{\"attributes\":{},\"id\":\"1686\",\"type\":\"NodesOnly\"},{\"attributes\":{\"callback\":null,\"data\":{\"color\":[\"purple\",\"grey\",\"green\",\"grey\",\"white\",\"lightgreen\",\"grey\",\"green\",\"red\",\"green\",\"orange\",\"green\",\"grey\",\"grey\",\"orange\",\"grey\",\"grey\",\"grey\",\"grey\"],\"index\":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18],\"species\":[\"nothing\",\"ordered_polymer[complex[protein[Ribo]:rna[UTR1]-forward]:rna[RFP-forward]:rna[t16-forward]]\",\"protein[RNAase]\",\"ordered_polymer[complex[dna[ptet]:protein[RNAP]-forward]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]:dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:dna[pconst-reverse]]\",\"dna[dna[ptet-forward]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]:dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:dna[pconst-reverse]]\",\"protein[GFP]\",\"ordered_polymer[complex[dna[ptet]:protein[RNAP]-forward]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]:dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:complex[dna[pconst]:protein[RNAP]-reverse]]\",\"protein[RNAP]\",\"protein[RFP]\",\"protein[tetr]\",\"rna[rna[UTR1-forward]:rna[GFP-forward]:rna[t16-forward]]\",\"protein[Ribo]\",\"ordered_polymer[complex[protein[Ribo]:rna[UTR1]-forward]:rna[GFP-forward]:rna[t16-forward]]\",\"ordered_polymer[[dna[ptet]:2x_protein[tetr]-forward]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]:dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:dna[pconst-reverse]]\",\"rna[rna[UTR1-forward]:rna[RFP-forward]:rna[t16-forward]]\",\"ordered_polymer[[dna[ptet]:2x_protein[tetr]-forward]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]:dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:complex[dna[pconst]:protein[RNAP]-reverse]]\",\"ordered_polymer[complex[[dna[ptet]:2x_protein[tetr]]:protein[RNAP]-forward]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]:dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:complex[dna[pconst]:protein[RNAP]-reverse]]\",\"ordered_polymer[dna[ptet-forward]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]:dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:complex[dna[pconst]:protein[RNAP]-reverse]]\",\"ordered_polymer[complex[[dna[ptet]:2x_protein[tetr]]:protein[RNAP]-forward]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]:dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:dna[pconst-reverse]]\"],\"type\":[\"nothing\",\"ordered_polymer\",\"protein\",\"ordered_polymer\",\"dna\",\"protein\",\"ordered_polymer\",\"protein\",\"protein\",\"protein\",\"rna\",\"protein\",\"ordered_polymer\",\"ordered_polymer\",\"rna\",\"ordered_polymer\",\"ordered_polymer\",\"ordered_polymer\",\"ordered_polymer\"]},\"selected\":{\"id\":\"1711\",\"type\":\"Selection\"},\"selection_policy\":{\"id\":\"1710\",\"type\":\"UnionRenderers\"}},\"id\":\"1518\",\"type\":\"ColumnDataSource\"},{\"attributes\":{\"graph_layout\":{\"0\":[88.27152306903504,-253.1274824878269],\"1\":[132.03573345539652,142.29992410862027],\"10\":[162.0928482698882,120.19280405820047],\"11\":[153.46703847320822,129.6375000047943],\"12\":[179.01811297167205,119.78087829435556],\"13\":[-24.382793002770676,0.2780454482461787],\"14\":[136.34159815391814,131.33388525476965],\"15\":[-40.93392405496524,10.942280437411275],\"16\":[-73.84182523293367,40.30582736768835],\"17\":[4.072716776001942,-43.37608195400387],\"18\":[-61.44792512437408,-7.602735517487976],\"19\":[48.886251192130366,-36.73834083221431],\"2\":[-280.2646995413965,4.497423062199457],\"20\":[77.33719537503133,-87.90213240396263],\"21\":[-25.39627415162268,13.089477083375455],\"22\":[-73.90281181788369,12.288377863928684],\"23\":[-58.03935844755277,12.411691754707025],\"24\":[-92.78563945472774,46.54713682497346],\"25\":[25.777306584499808,-50.57408092198795],\"26\":[62.55342839535837,-97.7874982058831],\"27\":[-18.124619009412104,-18.185897504821483],\"28\":[-45.506998465856284,29.318906337011622],\"29\":[-92.85347895877348,62.838190585367364],\"3\":[55.37320691609743,-17.857314064199937],\"30\":[32.33770424277019,-6.716575168984064],\"31\":[75.33873507217703,-14.753244894467425],\"32\":[-7.418036529321104,-9.564658745630869],\"33\":[-36.09134666156681,-6.336766959270443],\"34\":[-80.73270969198812,-21.50039115023293],\"35\":[9.94954472387104,-22.068754327541964],\"36\":[0.0457860875360908,-63.89488669215859],\"37\":[165.18968390928575,124.15142915709694],\"38\":[189.3309902751563,116.43462330149798],\"39\":[140.14899161905018,135.3819966728867],\"4\":[14.953201438630577,-9.847483223963055],\"40\":[124.65816325015204,148.84266134422492],\"5\":[229.4826153772355,61.35301119982526],\"6\":[56.84426959995666,-72.79853161574077],\"7\":[0.04069251554409696,0.007758933055522639],\"8\":[-35.550380516396345,254.9737557261887],\"9\":[-11.180744283387114,-13.926469651525597]}},\"id\":\"1545\",\"type\":\"StaticLayoutProvider\"},{\"attributes\":{\"active_drag\":\"auto\",\"active_inspect\":\"auto\",\"active_multi\":null,\"active_scroll\":\"auto\",\"active_tap\":\"auto\",\"tools\":[{\"id\":\"1606\",\"type\":\"HoverTool\"},{\"id\":\"1607\",\"type\":\"HoverTool\"},{\"id\":\"1608\",\"type\":\"HoverTool\"},{\"id\":\"1609\",\"type\":\"TapTool\"},{\"id\":\"1610\",\"type\":\"BoxSelectTool\"},{\"id\":\"1611\",\"type\":\"PanTool\"},{\"id\":\"1612\",\"type\":\"WheelZoomTool\"}]},\"id\":\"1613\",\"type\":\"Toolbar\"},{\"attributes\":{\"fill_color\":{\"value\":\"#2b83ba\"},\"size\":{\"units\":\"screen\",\"value\":8}},\"id\":\"1576\",\"type\":\"Square\"},{\"attributes\":{\"callback\":null,\"data\":{\"color\":[\"blue\",\"blue\",\"blue\",\"blue\",\"blue\",\"blue\",\"blue\",\"blue\",\"blue\",\"blue\",\"blue\",\"blue\",\"blue\",\"blue\",\"blue\",\"blue\",\"blue\",\"blue\",\"blue\",\"blue\",\"blue\",\"blue\"],\"index\":[19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40],\"k\":[\"100\",\"0.05\",\"100\",\"0.05\",\"100\",\"0.05\",\"100\",\"0.05\",\"100\",\"100\",\"0.05\",\"100\",\"0.05\",\"100\",\"100\",\"0.05\",\"100\",\"0.05\",\"100\",\"0.2\",\"100\",\"0.2\"],\"k_r\":[\"10\",\"None\",\"10\",\"None\",\"10\",\"None\",\"10\",\"None\",\"10\",\"10\",\"None\",\"10\",\"None\",\"10\",\"10\",\"None\",\"10\",\"None\",\"10\",\"None\",\"10\",\"None\"],\"species\":[\"ordered_polymer[complex[dna[ptet]:protein[RNAP]-forward]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]:dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:dna[pconst-reverse]]+protein[RNAP] <--> ordered_polymer[complex[dna[ptet]:protein[RNAP]-forward]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]:dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:complex[dna[pconst]:protein[RNAP]-reverse]]\\n Kf=k_forward * ordered_polymer_dna_ptet_protein_RNAP_f_UTR1_f_GFP_f_t16_f_t16_r_RFP_r_UTR1_r_pconst_r * protein_RNAP\\n Kr=k_reverse * ordered_polymer_dna_ptet_protein_RNAP_f_UTR1_f_GFP_f_t16_f_t16_r_RFP_r_UTR1_r_dna_pconst_protein_RNAP_r\\n k_forward=100\\n found_key=(mech=None, partid=None, name=kb).\\n search_key=(mech=transcription_mm, partid=pconst, name=kb).\\n k_reverse=10\\n found_key=(mech=None, partid=None, name=ku).\\n search_key=(mech=transcription_mm, partid=pconst, name=ku).\\n\",\"ordered_polymer[complex[dna[ptet]:protein[RNAP]-forward]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]:dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:complex[dna[pconst]:protein[RNAP]-reverse]] --> ordered_polymer[complex[dna[ptet]:protein[RNAP]-forward]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]:dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:dna[pconst-reverse]]+rna[rna[UTR1-forward]:rna[RFP-forward]:rna[t16-forward]]+protein[RNAP]\\n Kf=k_forward * ordered_polymer_dna_ptet_protein_RNAP_f_UTR1_f_GFP_f_t16_f_t16_r_RFP_r_UTR1_r_dna_pconst_protein_RNAP_r\\n k_forward=0.05\\n found_key=(mech=None, partid=None, name=ktx).\\n search_key=(mech=transcription_mm, partid=pconst, name=ktx).\\n\",\"ordered_polymer[[dna[ptet]:2x_protein[tetr]-forward]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]:dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:dna[pconst-reverse]]+protein[RNAP] <--> ordered_polymer[[dna[ptet]:2x_protein[tetr]-forward]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]:dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:complex[dna[pconst]:protein[RNAP]-reverse]]\\n Kf=k_forward * ordered_polymer_dna_ptet_protein_tetr_2x_f_UTR1_f_GFP_f_t16_f_t16_r_RFP_r_UTR1_r_pconst_r * protein_RNAP\\n Kr=k_reverse * ordered_polymer_dna_ptet_protein_tetr_2x_f_UTR1_f_GFP_f_t16_f_t16_r_RFP_r_UTR1_r_dna_pconst_protein_RNAP_r\\n k_forward=100\\n found_key=(mech=None, partid=None, name=kb).\\n search_key=(mech=transcription_mm, partid=pconst, name=kb).\\n k_reverse=10\\n found_key=(mech=None, partid=None, name=ku).\\n search_key=(mech=transcription_mm, partid=pconst, name=ku).\\n\",\"ordered_polymer[[dna[ptet]:2x_protein[tetr]-forward]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]:dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:complex[dna[pconst]:protein[RNAP]-reverse]] --> ordered_polymer[[dna[ptet]:2x_protein[tetr]-forward]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]:dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:dna[pconst-reverse]]+rna[rna[UTR1-forward]:rna[RFP-forward]:rna[t16-forward]]+protein[RNAP]\\n Kf=k_forward * ordered_polymer_dna_ptet_protein_tetr_2x_f_UTR1_f_GFP_f_t16_f_t16_r_RFP_r_UTR1_r_dna_pconst_protein_RNAP_r\\n k_forward=0.05\\n found_key=(mech=None, partid=None, name=ktx).\\n search_key=(mech=transcription_mm, partid=pconst, name=ktx).\\n\",\"ordered_polymer[complex[[dna[ptet]:2x_protein[tetr]]:protein[RNAP]-forward]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]:dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:dna[pconst-reverse]]+protein[RNAP] <--> ordered_polymer[complex[[dna[ptet]:2x_protein[tetr]]:protein[RNAP]-forward]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]:dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:complex[dna[pconst]:protein[RNAP]-reverse]]\\n Kf=k_forward * ordered_polymer_dna_ptet_protein_tetr_2x_protein_RNAP_f_UTR1_f_GFP_f_t16_f_t16_r_RFP_r_UTR1_r_pconst_r * protein_RNAP\\n Kr=k_reverse * ordered_polymer_dna_ptet_protein_tetr_2x_protein_RNAP_f_UTR1_f_GFP_f_t16_f_t16_r_RFP_r_UTR1_r_dna_pconst_protein_RNAP_r\\n k_forward=100\\n found_key=(mech=None, partid=None, name=kb).\\n search_key=(mech=transcription_mm, partid=pconst, name=kb).\\n k_reverse=10\\n found_key=(mech=None, partid=None, name=ku).\\n search_key=(mech=transcription_mm, partid=pconst, name=ku).\\n\",\"ordered_polymer[complex[[dna[ptet]:2x_protein[tetr]]:protein[RNAP]-forward]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]:dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:complex[dna[pconst]:protein[RNAP]-reverse]] --> ordered_polymer[complex[[dna[ptet]:2x_protein[tetr]]:protein[RNAP]-forward]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]:dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:dna[pconst-reverse]]+rna[rna[UTR1-forward]:rna[RFP-forward]:rna[t16-forward]]+protein[RNAP]\\n Kf=k_forward * ordered_polymer_dna_ptet_protein_tetr_2x_protein_RNAP_f_UTR1_f_GFP_f_t16_f_t16_r_RFP_r_UTR1_r_dna_pconst_protein_RNAP_r\\n k_forward=0.05\\n found_key=(mech=None, partid=None, name=ktx).\\n search_key=(mech=transcription_mm, partid=pconst, name=ktx).\\n\",\"ordered_polymer[dna[ptet-forward]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]:dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:complex[dna[pconst]:protein[RNAP]-reverse]]+protein[RNAP] <--> ordered_polymer[complex[dna[ptet]:protein[RNAP]-forward]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]:dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:complex[dna[pconst]:protein[RNAP]-reverse]]\\n Kf=k_forward * ordered_polymer_ptet_f_UTR1_f_GFP_f_t16_f_t16_r_RFP_r_UTR1_r_dna_pconst_protein_RNAP_r * protein_RNAP\\n Kr=k_reverse * ordered_polymer_dna_ptet_protein_RNAP_f_UTR1_f_GFP_f_t16_f_t16_r_RFP_r_UTR1_r_dna_pconst_protein_RNAP_r\\n k_forward=100\\n found_key=(mech=None, partid=None, name=kb).\\n search_key=(mech=transcription_mm, partid=ptet_leak, name=kb).\\n k_reverse=10\\n found_key=(mech=None, partid=None, name=ku).\\n search_key=(mech=transcription_mm, partid=ptet_leak, name=ku).\\n\",\"ordered_polymer[complex[dna[ptet]:protein[RNAP]-forward]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]:dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:complex[dna[pconst]:protein[RNAP]-reverse]] --> ordered_polymer[dna[ptet-forward]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]:dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:complex[dna[pconst]:protein[RNAP]-reverse]]+rna[rna[UTR1-forward]:rna[GFP-forward]:rna[t16-forward]]+protein[RNAP]\\n Kf=k_forward * ordered_polymer_dna_ptet_protein_RNAP_f_UTR1_f_GFP_f_t16_f_t16_r_RFP_r_UTR1_r_dna_pconst_protein_RNAP_r\\n k_forward=0.05\\n found_key=(mech=None, partid=None, name=ktx).\\n search_key=(mech=transcription_mm, partid=ptet_leak, name=ktx).\\n\",\"2protein[tetr]+ordered_polymer[dna[ptet-forward]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]:dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:complex[dna[pconst]:protein[RNAP]-reverse]] <--> ordered_polymer[[dna[ptet]:2x_protein[tetr]-forward]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]:dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:complex[dna[pconst]:protein[RNAP]-reverse]]\\n Kf=k_forward * protein_tetr^2 * ordered_polymer_ptet_f_UTR1_f_GFP_f_t16_f_t16_r_RFP_r_UTR1_r_dna_pconst_protein_RNAP_r\\n Kr=k_reverse * ordered_polymer_dna_ptet_protein_tetr_2x_f_UTR1_f_GFP_f_t16_f_t16_r_RFP_r_UTR1_r_dna_pconst_protein_RNAP_r\\n k_forward=100\\n found_key=(mech=None, partid=None, name=kb).\\n search_key=(mech=one_step_cooperative_binding, partid=ptet_tetr, name=kb).\\n k_reverse=10\\n found_key=(mech=None, partid=None, name=ku).\\n search_key=(mech=one_step_cooperative_binding, partid=ptet_tetr, name=ku).\\n\",\"ordered_polymer[[dna[ptet]:2x_protein[tetr]-forward]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]:dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:complex[dna[pconst]:protein[RNAP]-reverse]]+protein[RNAP] <--> ordered_polymer[complex[[dna[ptet]:2x_protein[tetr]]:protein[RNAP]-forward]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]:dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:complex[dna[pconst]:protein[RNAP]-reverse]]\\n Kf=k_forward * ordered_polymer_dna_ptet_protein_tetr_2x_f_UTR1_f_GFP_f_t16_f_t16_r_RFP_r_UTR1_r_dna_pconst_protein_RNAP_r * protein_RNAP\\n Kr=k_reverse * ordered_polymer_dna_ptet_protein_tetr_2x_protein_RNAP_f_UTR1_f_GFP_f_t16_f_t16_r_RFP_r_UTR1_r_dna_pconst_protein_RNAP_r\\n k_forward=100\\n found_key=(mech=None, partid=None, name=kb).\\n search_key=(mech=transcription_mm, partid=ptet_tetr, name=kb).\\n k_reverse=10\\n found_key=(mech=None, partid=None, name=ku).\\n search_key=(mech=transcription_mm, partid=ptet_tetr, name=ku).\\n\",\"ordered_polymer[complex[[dna[ptet]:2x_protein[tetr]]:protein[RNAP]-forward]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]:dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:complex[dna[pconst]:protein[RNAP]-reverse]] --> ordered_polymer[[dna[ptet]:2x_protein[tetr]-forward]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]:dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:complex[dna[pconst]:protein[RNAP]-reverse]]+rna[rna[UTR1-forward]:rna[GFP-forward]:rna[t16-forward]]+protein[RNAP]\\n Kf=k_forward * ordered_polymer_dna_ptet_protein_tetr_2x_protein_RNAP_f_UTR1_f_GFP_f_t16_f_t16_r_RFP_r_UTR1_r_dna_pconst_protein_RNAP_r\\n k_forward=0.05\\n found_key=(mech=None, partid=None, name=ktx).\\n search_key=(mech=transcription_mm, partid=ptet_tetr, name=ktx).\\n\",\"dna[dna[ptet-forward]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]:dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:dna[pconst-reverse]]+protein[RNAP] <--> ordered_polymer[complex[dna[ptet]:protein[RNAP]-forward]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]:dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:dna[pconst-reverse]]\\n Kf=k_forward * dna_ptet_f_UTR1_f_GFP_f_t16_f_t16_r_RFP_r_UTR1_r_pconst_r * protein_RNAP\\n Kr=k_reverse * ordered_polymer_dna_ptet_protein_RNAP_f_UTR1_f_GFP_f_t16_f_t16_r_RFP_r_UTR1_r_pconst_r\\n k_forward=100\\n found_key=(mech=None, partid=None, name=kb).\\n search_key=(mech=transcription_mm, partid=ptet_leak, name=kb).\\n k_reverse=10\\n found_key=(mech=None, partid=None, name=ku).\\n search_key=(mech=transcription_mm, partid=ptet_leak, name=ku).\\n\",\"ordered_polymer[complex[dna[ptet]:protein[RNAP]-forward]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]:dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:dna[pconst-reverse]] --> dna[dna[ptet-forward]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]:dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:dna[pconst-reverse]]+rna[rna[UTR1-forward]:rna[GFP-forward]:rna[t16-forward]]+protein[RNAP]\\n Kf=k_forward * ordered_polymer_dna_ptet_protein_RNAP_f_UTR1_f_GFP_f_t16_f_t16_r_RFP_r_UTR1_r_pconst_r\\n k_forward=0.05\\n found_key=(mech=None, partid=None, name=ktx).\\n search_key=(mech=transcription_mm, partid=ptet_leak, name=ktx).\\n\",\"2protein[tetr]+dna[dna[ptet-forward]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]:dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:dna[pconst-reverse]] <--> ordered_polymer[[dna[ptet]:2x_protein[tetr]-forward]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]:dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:dna[pconst-reverse]]\\n Kf=k_forward * protein_tetr^2 * dna_ptet_f_UTR1_f_GFP_f_t16_f_t16_r_RFP_r_UTR1_r_pconst_r\\n Kr=k_reverse * ordered_polymer_dna_ptet_protein_tetr_2x_f_UTR1_f_GFP_f_t16_f_t16_r_RFP_r_UTR1_r_pconst_r\\n k_forward=100\\n found_key=(mech=None, partid=None, name=kb).\\n search_key=(mech=one_step_cooperative_binding, partid=ptet_tetr, name=kb).\\n k_reverse=10\\n found_key=(mech=None, partid=None, name=ku).\\n search_key=(mech=one_step_cooperative_binding, partid=ptet_tetr, name=ku).\\n\",\"ordered_polymer[[dna[ptet]:2x_protein[tetr]-forward]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]:dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:dna[pconst-reverse]]+protein[RNAP] <--> ordered_polymer[complex[[dna[ptet]:2x_protein[tetr]]:protein[RNAP]-forward]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]:dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:dna[pconst-reverse]]\\n Kf=k_forward * ordered_polymer_dna_ptet_protein_tetr_2x_f_UTR1_f_GFP_f_t16_f_t16_r_RFP_r_UTR1_r_pconst_r * protein_RNAP\\n Kr=k_reverse * ordered_polymer_dna_ptet_protein_tetr_2x_protein_RNAP_f_UTR1_f_GFP_f_t16_f_t16_r_RFP_r_UTR1_r_pconst_r\\n k_forward=100\\n found_key=(mech=None, partid=None, name=kb).\\n search_key=(mech=transcription_mm, partid=ptet_tetr, name=kb).\\n k_reverse=10\\n found_key=(mech=None, partid=None, name=ku).\\n search_key=(mech=transcription_mm, partid=ptet_tetr, name=ku).\\n\",\"ordered_polymer[complex[[dna[ptet]:2x_protein[tetr]]:protein[RNAP]-forward]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]:dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:dna[pconst-reverse]] --> ordered_polymer[[dna[ptet]:2x_protein[tetr]-forward]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]:dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:dna[pconst-reverse]]+rna[rna[UTR1-forward]:rna[GFP-forward]:rna[t16-forward]]+protein[RNAP]\\n Kf=k_forward * ordered_polymer_dna_ptet_protein_tetr_2x_protein_RNAP_f_UTR1_f_GFP_f_t16_f_t16_r_RFP_r_UTR1_r_pconst_r\\n k_forward=0.05\\n found_key=(mech=None, partid=None, name=ktx).\\n search_key=(mech=transcription_mm, partid=ptet_tetr, name=ktx).\\n\",\"dna[dna[ptet-forward]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]:dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:dna[pconst-reverse]]+protein[RNAP] <--> ordered_polymer[dna[ptet-forward]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]:dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:complex[dna[pconst]:protein[RNAP]-reverse]]\\n Kf=k_forward * dna_ptet_f_UTR1_f_GFP_f_t16_f_t16_r_RFP_r_UTR1_r_pconst_r * protein_RNAP\\n Kr=k_reverse * ordered_polymer_ptet_f_UTR1_f_GFP_f_t16_f_t16_r_RFP_r_UTR1_r_dna_pconst_protein_RNAP_r\\n k_forward=100\\n found_key=(mech=None, partid=None, name=kb).\\n search_key=(mech=transcription_mm, partid=pconst, name=kb).\\n k_reverse=10\\n found_key=(mech=None, partid=None, name=ku).\\n search_key=(mech=transcription_mm, partid=pconst, name=ku).\\n\",\"ordered_polymer[dna[ptet-forward]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]:dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:complex[dna[pconst]:protein[RNAP]-reverse]] --> dna[dna[ptet-forward]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]:dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:dna[pconst-reverse]]+rna[rna[UTR1-forward]:rna[RFP-forward]:rna[t16-forward]]+protein[RNAP]\\n Kf=k_forward * ordered_polymer_ptet_f_UTR1_f_GFP_f_t16_f_t16_r_RFP_r_UTR1_r_dna_pconst_protein_RNAP_r\\n k_forward=0.05\\n found_key=(mech=None, partid=None, name=ktx).\\n search_key=(mech=transcription_mm, partid=pconst, name=ktx).\\n\",\"rna[rna[UTR1-forward]:rna[GFP-forward]:rna[t16-forward]]+protein[Ribo] <--> ordered_polymer[complex[protein[Ribo]:rna[UTR1]-forward]:rna[GFP-forward]:rna[t16-forward]]\\n Kf=k_forward * rna_UTR1_f_GFP_f_t16_f * protein_Ribo\\n Kr=k_reverse * ordered_polymer_protein_Ribo_rna_UTR1_f_GFP_f_t16_f\\n k_forward=100\\n found_key=(mech=None, partid=None, name=kb).\\n search_key=(mech=translation_mm, partid=UTR1, name=kb).\\n k_reverse=10\\n found_key=(mech=None, partid=None, name=ku).\\n search_key=(mech=translation_mm, partid=UTR1, name=ku).\\n\",\"ordered_polymer[complex[protein[Ribo]:rna[UTR1]-forward]:rna[GFP-forward]:rna[t16-forward]] --> rna[rna[UTR1-forward]:rna[GFP-forward]:rna[t16-forward]]+protein[GFP]+protein[Ribo]\\n Kf=k_forward * ordered_polymer_protein_Ribo_rna_UTR1_f_GFP_f_t16_f\\n k_forward=0.2\\n found_key=(mech=None, partid=None, name=ktl).\\n search_key=(mech=translation_mm, partid=UTR1, name=ktl).\\n\",\"rna[rna[UTR1-forward]:rna[RFP-forward]:rna[t16-forward]]+protein[Ribo] <--> ordered_polymer[complex[protein[Ribo]:rna[UTR1]-forward]:rna[RFP-forward]:rna[t16-forward]]\\n Kf=k_forward * rna_UTR1_f_RFP_f_t16_f * protein_Ribo\\n Kr=k_reverse * ordered_polymer_protein_Ribo_rna_UTR1_f_RFP_f_t16_f\\n k_forward=100\\n found_key=(mech=None, partid=None, name=kb).\\n search_key=(mech=translation_mm, partid=UTR1, name=kb).\\n k_reverse=10\\n found_key=(mech=None, partid=None, name=ku).\\n search_key=(mech=translation_mm, partid=UTR1, name=ku).\\n\",\"ordered_polymer[complex[protein[Ribo]:rna[UTR1]-forward]:rna[RFP-forward]:rna[t16-forward]] --> rna[rna[UTR1-forward]:rna[RFP-forward]:rna[t16-forward]]+protein[RFP]+protein[Ribo]\\n Kf=k_forward * ordered_polymer_protein_Ribo_rna_UTR1_f_RFP_f_t16_f\\n k_forward=0.2\\n found_key=(mech=None, partid=None, name=ktl).\\n search_key=(mech=translation_mm, partid=UTR1, name=ktl).\\n\"],\"type\":[\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\"]},\"selected\":{\"id\":\"1707\",\"type\":\"Selection\"},\"selection_policy\":{\"id\":\"1706\",\"type\":\"UnionRenderers\"}},\"id\":\"1502\",\"type\":\"ColumnDataSource\"},{\"attributes\":{\"graph_layout\":{\"0\":[88.27152306903504,-253.1274824878269],\"1\":[132.03573345539652,142.29992410862027],\"10\":[162.0928482698882,120.19280405820047],\"11\":[153.46703847320822,129.6375000047943],\"12\":[179.01811297167205,119.78087829435556],\"13\":[-24.382793002770676,0.2780454482461787],\"14\":[136.34159815391814,131.33388525476965],\"15\":[-40.93392405496524,10.942280437411275],\"16\":[-73.84182523293367,40.30582736768835],\"17\":[4.072716776001942,-43.37608195400387],\"18\":[-61.44792512437408,-7.602735517487976],\"19\":[48.886251192130366,-36.73834083221431],\"2\":[-280.2646995413965,4.497423062199457],\"20\":[77.33719537503133,-87.90213240396263],\"21\":[-25.39627415162268,13.089477083375455],\"22\":[-73.90281181788369,12.288377863928684],\"23\":[-58.03935844755277,12.411691754707025],\"24\":[-92.78563945472774,46.54713682497346],\"25\":[25.777306584499808,-50.57408092198795],\"26\":[62.55342839535837,-97.7874982058831],\"27\":[-18.124619009412104,-18.185897504821483],\"28\":[-45.506998465856284,29.318906337011622],\"29\":[-92.85347895877348,62.838190585367364],\"3\":[55.37320691609743,-17.857314064199937],\"30\":[32.33770424277019,-6.716575168984064],\"31\":[75.33873507217703,-14.753244894467425],\"32\":[-7.418036529321104,-9.564658745630869],\"33\":[-36.09134666156681,-6.336766959270443],\"34\":[-80.73270969198812,-21.50039115023293],\"35\":[9.94954472387104,-22.068754327541964],\"36\":[0.0457860875360908,-63.89488669215859],\"37\":[165.18968390928575,124.15142915709694],\"38\":[189.3309902751563,116.43462330149798],\"39\":[140.14899161905018,135.3819966728867],\"4\":[14.953201438630577,-9.847483223963055],\"40\":[124.65816325015204,148.84266134422492],\"5\":[229.4826153772355,61.35301119982526],\"6\":[56.84426959995666,-72.79853161574077],\"7\":[0.04069251554409696,0.007758933055522639],\"8\":[-35.550380516396345,254.9737557261887],\"9\":[-11.180744283387114,-13.926469651525597]}},\"id\":\"1529\",\"type\":\"StaticLayoutProvider\"},{\"attributes\":{},\"id\":\"1712\",\"type\":\"UnionRenderers\"},{\"attributes\":{},\"id\":\"1696\",\"type\":\"NodesOnly\"},{\"attributes\":{},\"id\":\"1710\",\"type\":\"UnionRenderers\"},{\"attributes\":{\"source\":{\"id\":\"1502\",\"type\":\"ColumnDataSource\"}},\"id\":\"1504\",\"type\":\"CDSView\"},{\"attributes\":{\"callback\":null,\"data\":{\"end\":[],\"start\":[]},\"selected\":{\"id\":\"1709\",\"type\":\"Selection\"},\"selection_policy\":{\"id\":\"1708\",\"type\":\"UnionRenderers\"}},\"id\":\"1506\",\"type\":\"ColumnDataSource\"},{\"attributes\":{\"data_source\":{\"id\":\"1534\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"1546\",\"type\":\"Circle\"},\"hover_glyph\":null,\"muted_glyph\":null,\"view\":{\"id\":\"1536\",\"type\":\"CDSView\"}},\"id\":\"1535\",\"type\":\"GlyphRenderer\"},{\"attributes\":{},\"id\":\"1521\",\"type\":\"MultiLine\"},{\"attributes\":{},\"id\":\"1671\",\"type\":\"LinearScale\"},{\"attributes\":{\"attachment\":\"right\",\"callback\":null,\"renderers\":[{\"id\":\"1516\",\"type\":\"GraphRenderer\"}],\"tooltips\":[[\"name\",\"@species\"],[\"type\",\"@type\"]]},\"id\":\"1607\",\"type\":\"HoverTool\"},{\"attributes\":{},\"id\":\"1612\",\"type\":\"WheelZoomTool\"},{\"attributes\":{\"callback\":null,\"data\":{\"color\":[\"purple\",\"grey\",\"green\",\"grey\",\"white\",\"lightgreen\",\"grey\",\"green\",\"red\",\"green\",\"orange\",\"green\",\"grey\",\"grey\",\"orange\",\"grey\",\"grey\",\"grey\",\"grey\",\"blue\",\"blue\",\"blue\",\"blue\",\"blue\",\"blue\",\"blue\",\"blue\",\"blue\",\"blue\",\"blue\",\"blue\",\"blue\",\"blue\",\"blue\",\"blue\",\"blue\",\"blue\",\"blue\",\"blue\",\"blue\",\"blue\"],\"index\":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40],\"k\":[null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,\"100\",\"0.05\",\"100\",\"0.05\",\"100\",\"0.05\",\"100\",\"0.05\",\"100\",\"100\",\"0.05\",\"100\",\"0.05\",\"100\",\"100\",\"0.05\",\"100\",\"0.05\",\"100\",\"0.2\",\"100\",\"0.2\"],\"k_r\":[null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,\"10\",\"None\",\"10\",\"None\",\"10\",\"None\",\"10\",\"None\",\"10\",\"10\",\"None\",\"10\",\"None\",\"10\",\"10\",\"None\",\"10\",\"None\",\"10\",\"None\",\"10\",\"None\"],\"species\":[\"nothing\",\"ordered_polymer[complex[protein[Ribo]:rna[UTR1]-forward]:rna[RFP-forward]:rna[t16-forward]]\",\"protein[RNAase]\",\"ordered_polymer[complex[dna[ptet]:protein[RNAP]-forward]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]:dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:dna[pconst-reverse]]\",\"dna[dna[ptet-forward]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]:dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:dna[pconst-reverse]]\",\"protein[GFP]\",\"ordered_polymer[complex[dna[ptet]:protein[RNAP]-forward]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]:dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:complex[dna[pconst]:protein[RNAP]-reverse]]\",\"protein[RNAP]\",\"protein[RFP]\",\"protein[tetr]\",\"rna[rna[UTR1-forward]:rna[GFP-forward]:rna[t16-forward]]\",\"protein[Ribo]\",\"ordered_polymer[complex[protein[Ribo]:rna[UTR1]-forward]:rna[GFP-forward]:rna[t16-forward]]\",\"ordered_polymer[[dna[ptet]:2x_protein[tetr]-forward]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]:dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:dna[pconst-reverse]]\",\"rna[rna[UTR1-forward]:rna[RFP-forward]:rna[t16-forward]]\",\"ordered_polymer[[dna[ptet]:2x_protein[tetr]-forward]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]:dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:complex[dna[pconst]:protein[RNAP]-reverse]]\",\"ordered_polymer[complex[[dna[ptet]:2x_protein[tetr]]:protein[RNAP]-forward]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]:dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:complex[dna[pconst]:protein[RNAP]-reverse]]\",\"ordered_polymer[dna[ptet-forward]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]:dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:complex[dna[pconst]:protein[RNAP]-reverse]]\",\"ordered_polymer[complex[[dna[ptet]:2x_protein[tetr]]:protein[RNAP]-forward]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]:dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:dna[pconst-reverse]]\",\"ordered_polymer[complex[dna[ptet]:protein[RNAP]-forward]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]:dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:dna[pconst-reverse]]+protein[RNAP] <--> ordered_polymer[complex[dna[ptet]:protein[RNAP]-forward]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]:dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:complex[dna[pconst]:protein[RNAP]-reverse]]\\n Kf=k_forward * ordered_polymer_dna_ptet_protein_RNAP_f_UTR1_f_GFP_f_t16_f_t16_r_RFP_r_UTR1_r_pconst_r * protein_RNAP\\n Kr=k_reverse * ordered_polymer_dna_ptet_protein_RNAP_f_UTR1_f_GFP_f_t16_f_t16_r_RFP_r_UTR1_r_dna_pconst_protein_RNAP_r\\n k_forward=100\\n found_key=(mech=None, partid=None, name=kb).\\n search_key=(mech=transcription_mm, partid=pconst, name=kb).\\n k_reverse=10\\n found_key=(mech=None, partid=None, name=ku).\\n search_key=(mech=transcription_mm, partid=pconst, name=ku).\\n\",\"ordered_polymer[complex[dna[ptet]:protein[RNAP]-forward]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]:dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:complex[dna[pconst]:protein[RNAP]-reverse]] --> ordered_polymer[complex[dna[ptet]:protein[RNAP]-forward]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]:dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:dna[pconst-reverse]]+rna[rna[UTR1-forward]:rna[RFP-forward]:rna[t16-forward]]+protein[RNAP]\\n Kf=k_forward * ordered_polymer_dna_ptet_protein_RNAP_f_UTR1_f_GFP_f_t16_f_t16_r_RFP_r_UTR1_r_dna_pconst_protein_RNAP_r\\n k_forward=0.05\\n found_key=(mech=None, partid=None, name=ktx).\\n search_key=(mech=transcription_mm, partid=pconst, name=ktx).\\n\",\"ordered_polymer[[dna[ptet]:2x_protein[tetr]-forward]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]:dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:dna[pconst-reverse]]+protein[RNAP] <--> ordered_polymer[[dna[ptet]:2x_protein[tetr]-forward]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]:dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:complex[dna[pconst]:protein[RNAP]-reverse]]\\n Kf=k_forward * ordered_polymer_dna_ptet_protein_tetr_2x_f_UTR1_f_GFP_f_t16_f_t16_r_RFP_r_UTR1_r_pconst_r * protein_RNAP\\n Kr=k_reverse * ordered_polymer_dna_ptet_protein_tetr_2x_f_UTR1_f_GFP_f_t16_f_t16_r_RFP_r_UTR1_r_dna_pconst_protein_RNAP_r\\n k_forward=100\\n found_key=(mech=None, partid=None, name=kb).\\n search_key=(mech=transcription_mm, partid=pconst, name=kb).\\n k_reverse=10\\n found_key=(mech=None, partid=None, name=ku).\\n search_key=(mech=transcription_mm, partid=pconst, name=ku).\\n\",\"ordered_polymer[[dna[ptet]:2x_protein[tetr]-forward]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]:dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:complex[dna[pconst]:protein[RNAP]-reverse]] --> ordered_polymer[[dna[ptet]:2x_protein[tetr]-forward]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]:dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:dna[pconst-reverse]]+rna[rna[UTR1-forward]:rna[RFP-forward]:rna[t16-forward]]+protein[RNAP]\\n Kf=k_forward * ordered_polymer_dna_ptet_protein_tetr_2x_f_UTR1_f_GFP_f_t16_f_t16_r_RFP_r_UTR1_r_dna_pconst_protein_RNAP_r\\n k_forward=0.05\\n found_key=(mech=None, partid=None, name=ktx).\\n search_key=(mech=transcription_mm, partid=pconst, name=ktx).\\n\",\"ordered_polymer[complex[[dna[ptet]:2x_protein[tetr]]:protein[RNAP]-forward]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]:dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:dna[pconst-reverse]]+protein[RNAP] <--> ordered_polymer[complex[[dna[ptet]:2x_protein[tetr]]:protein[RNAP]-forward]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]:dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:complex[dna[pconst]:protein[RNAP]-reverse]]\\n Kf=k_forward * ordered_polymer_dna_ptet_protein_tetr_2x_protein_RNAP_f_UTR1_f_GFP_f_t16_f_t16_r_RFP_r_UTR1_r_pconst_r * protein_RNAP\\n Kr=k_reverse * ordered_polymer_dna_ptet_protein_tetr_2x_protein_RNAP_f_UTR1_f_GFP_f_t16_f_t16_r_RFP_r_UTR1_r_dna_pconst_protein_RNAP_r\\n k_forward=100\\n found_key=(mech=None, partid=None, name=kb).\\n search_key=(mech=transcription_mm, partid=pconst, name=kb).\\n k_reverse=10\\n found_key=(mech=None, partid=None, name=ku).\\n search_key=(mech=transcription_mm, partid=pconst, name=ku).\\n\",\"ordered_polymer[complex[[dna[ptet]:2x_protein[tetr]]:protein[RNAP]-forward]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]:dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:complex[dna[pconst]:protein[RNAP]-reverse]] --> ordered_polymer[complex[[dna[ptet]:2x_protein[tetr]]:protein[RNAP]-forward]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]:dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:dna[pconst-reverse]]+rna[rna[UTR1-forward]:rna[RFP-forward]:rna[t16-forward]]+protein[RNAP]\\n Kf=k_forward * ordered_polymer_dna_ptet_protein_tetr_2x_protein_RNAP_f_UTR1_f_GFP_f_t16_f_t16_r_RFP_r_UTR1_r_dna_pconst_protein_RNAP_r\\n k_forward=0.05\\n found_key=(mech=None, partid=None, name=ktx).\\n search_key=(mech=transcription_mm, partid=pconst, name=ktx).\\n\",\"ordered_polymer[dna[ptet-forward]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]:dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:complex[dna[pconst]:protein[RNAP]-reverse]]+protein[RNAP] <--> ordered_polymer[complex[dna[ptet]:protein[RNAP]-forward]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]:dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:complex[dna[pconst]:protein[RNAP]-reverse]]\\n Kf=k_forward * ordered_polymer_ptet_f_UTR1_f_GFP_f_t16_f_t16_r_RFP_r_UTR1_r_dna_pconst_protein_RNAP_r * protein_RNAP\\n Kr=k_reverse * ordered_polymer_dna_ptet_protein_RNAP_f_UTR1_f_GFP_f_t16_f_t16_r_RFP_r_UTR1_r_dna_pconst_protein_RNAP_r\\n k_forward=100\\n found_key=(mech=None, partid=None, name=kb).\\n search_key=(mech=transcription_mm, partid=ptet_leak, name=kb).\\n k_reverse=10\\n found_key=(mech=None, partid=None, name=ku).\\n search_key=(mech=transcription_mm, partid=ptet_leak, name=ku).\\n\",\"ordered_polymer[complex[dna[ptet]:protein[RNAP]-forward]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]:dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:complex[dna[pconst]:protein[RNAP]-reverse]] --> ordered_polymer[dna[ptet-forward]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]:dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:complex[dna[pconst]:protein[RNAP]-reverse]]+rna[rna[UTR1-forward]:rna[GFP-forward]:rna[t16-forward]]+protein[RNAP]\\n Kf=k_forward * ordered_polymer_dna_ptet_protein_RNAP_f_UTR1_f_GFP_f_t16_f_t16_r_RFP_r_UTR1_r_dna_pconst_protein_RNAP_r\\n k_forward=0.05\\n found_key=(mech=None, partid=None, name=ktx).\\n search_key=(mech=transcription_mm, partid=ptet_leak, name=ktx).\\n\",\"2protein[tetr]+ordered_polymer[dna[ptet-forward]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]:dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:complex[dna[pconst]:protein[RNAP]-reverse]] <--> ordered_polymer[[dna[ptet]:2x_protein[tetr]-forward]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]:dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:complex[dna[pconst]:protein[RNAP]-reverse]]\\n Kf=k_forward * protein_tetr^2 * ordered_polymer_ptet_f_UTR1_f_GFP_f_t16_f_t16_r_RFP_r_UTR1_r_dna_pconst_protein_RNAP_r\\n Kr=k_reverse * ordered_polymer_dna_ptet_protein_tetr_2x_f_UTR1_f_GFP_f_t16_f_t16_r_RFP_r_UTR1_r_dna_pconst_protein_RNAP_r\\n k_forward=100\\n found_key=(mech=None, partid=None, name=kb).\\n search_key=(mech=one_step_cooperative_binding, partid=ptet_tetr, name=kb).\\n k_reverse=10\\n found_key=(mech=None, partid=None, name=ku).\\n search_key=(mech=one_step_cooperative_binding, partid=ptet_tetr, name=ku).\\n\",\"ordered_polymer[[dna[ptet]:2x_protein[tetr]-forward]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]:dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:complex[dna[pconst]:protein[RNAP]-reverse]]+protein[RNAP] <--> ordered_polymer[complex[[dna[ptet]:2x_protein[tetr]]:protein[RNAP]-forward]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]:dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:complex[dna[pconst]:protein[RNAP]-reverse]]\\n Kf=k_forward * ordered_polymer_dna_ptet_protein_tetr_2x_f_UTR1_f_GFP_f_t16_f_t16_r_RFP_r_UTR1_r_dna_pconst_protein_RNAP_r * protein_RNAP\\n Kr=k_reverse * ordered_polymer_dna_ptet_protein_tetr_2x_protein_RNAP_f_UTR1_f_GFP_f_t16_f_t16_r_RFP_r_UTR1_r_dna_pconst_protein_RNAP_r\\n k_forward=100\\n found_key=(mech=None, partid=None, name=kb).\\n search_key=(mech=transcription_mm, partid=ptet_tetr, name=kb).\\n k_reverse=10\\n found_key=(mech=None, partid=None, name=ku).\\n search_key=(mech=transcription_mm, partid=ptet_tetr, name=ku).\\n\",\"ordered_polymer[complex[[dna[ptet]:2x_protein[tetr]]:protein[RNAP]-forward]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]:dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:complex[dna[pconst]:protein[RNAP]-reverse]] --> ordered_polymer[[dna[ptet]:2x_protein[tetr]-forward]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]:dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:complex[dna[pconst]:protein[RNAP]-reverse]]+rna[rna[UTR1-forward]:rna[GFP-forward]:rna[t16-forward]]+protein[RNAP]\\n Kf=k_forward * ordered_polymer_dna_ptet_protein_tetr_2x_protein_RNAP_f_UTR1_f_GFP_f_t16_f_t16_r_RFP_r_UTR1_r_dna_pconst_protein_RNAP_r\\n k_forward=0.05\\n found_key=(mech=None, partid=None, name=ktx).\\n search_key=(mech=transcription_mm, partid=ptet_tetr, name=ktx).\\n\",\"dna[dna[ptet-forward]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]:dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:dna[pconst-reverse]]+protein[RNAP] <--> ordered_polymer[complex[dna[ptet]:protein[RNAP]-forward]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]:dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:dna[pconst-reverse]]\\n Kf=k_forward * dna_ptet_f_UTR1_f_GFP_f_t16_f_t16_r_RFP_r_UTR1_r_pconst_r * protein_RNAP\\n Kr=k_reverse * ordered_polymer_dna_ptet_protein_RNAP_f_UTR1_f_GFP_f_t16_f_t16_r_RFP_r_UTR1_r_pconst_r\\n k_forward=100\\n found_key=(mech=None, partid=None, name=kb).\\n search_key=(mech=transcription_mm, partid=ptet_leak, name=kb).\\n k_reverse=10\\n found_key=(mech=None, partid=None, name=ku).\\n search_key=(mech=transcription_mm, partid=ptet_leak, name=ku).\\n\",\"ordered_polymer[complex[dna[ptet]:protein[RNAP]-forward]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]:dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:dna[pconst-reverse]] --> dna[dna[ptet-forward]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]:dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:dna[pconst-reverse]]+rna[rna[UTR1-forward]:rna[GFP-forward]:rna[t16-forward]]+protein[RNAP]\\n Kf=k_forward * ordered_polymer_dna_ptet_protein_RNAP_f_UTR1_f_GFP_f_t16_f_t16_r_RFP_r_UTR1_r_pconst_r\\n k_forward=0.05\\n found_key=(mech=None, partid=None, name=ktx).\\n search_key=(mech=transcription_mm, partid=ptet_leak, name=ktx).\\n\",\"2protein[tetr]+dna[dna[ptet-forward]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]:dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:dna[pconst-reverse]] <--> ordered_polymer[[dna[ptet]:2x_protein[tetr]-forward]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]:dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:dna[pconst-reverse]]\\n Kf=k_forward * protein_tetr^2 * dna_ptet_f_UTR1_f_GFP_f_t16_f_t16_r_RFP_r_UTR1_r_pconst_r\\n Kr=k_reverse * ordered_polymer_dna_ptet_protein_tetr_2x_f_UTR1_f_GFP_f_t16_f_t16_r_RFP_r_UTR1_r_pconst_r\\n k_forward=100\\n found_key=(mech=None, partid=None, name=kb).\\n search_key=(mech=one_step_cooperative_binding, partid=ptet_tetr, name=kb).\\n k_reverse=10\\n found_key=(mech=None, partid=None, name=ku).\\n search_key=(mech=one_step_cooperative_binding, partid=ptet_tetr, name=ku).\\n\",\"ordered_polymer[[dna[ptet]:2x_protein[tetr]-forward]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]:dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:dna[pconst-reverse]]+protein[RNAP] <--> ordered_polymer[complex[[dna[ptet]:2x_protein[tetr]]:protein[RNAP]-forward]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]:dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:dna[pconst-reverse]]\\n Kf=k_forward * ordered_polymer_dna_ptet_protein_tetr_2x_f_UTR1_f_GFP_f_t16_f_t16_r_RFP_r_UTR1_r_pconst_r * protein_RNAP\\n Kr=k_reverse * ordered_polymer_dna_ptet_protein_tetr_2x_protein_RNAP_f_UTR1_f_GFP_f_t16_f_t16_r_RFP_r_UTR1_r_pconst_r\\n k_forward=100\\n found_key=(mech=None, partid=None, name=kb).\\n search_key=(mech=transcription_mm, partid=ptet_tetr, name=kb).\\n k_reverse=10\\n found_key=(mech=None, partid=None, name=ku).\\n search_key=(mech=transcription_mm, partid=ptet_tetr, name=ku).\\n\",\"ordered_polymer[complex[[dna[ptet]:2x_protein[tetr]]:protein[RNAP]-forward]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]:dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:dna[pconst-reverse]] --> ordered_polymer[[dna[ptet]:2x_protein[tetr]-forward]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]:dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:dna[pconst-reverse]]+rna[rna[UTR1-forward]:rna[GFP-forward]:rna[t16-forward]]+protein[RNAP]\\n Kf=k_forward * ordered_polymer_dna_ptet_protein_tetr_2x_protein_RNAP_f_UTR1_f_GFP_f_t16_f_t16_r_RFP_r_UTR1_r_pconst_r\\n k_forward=0.05\\n found_key=(mech=None, partid=None, name=ktx).\\n search_key=(mech=transcription_mm, partid=ptet_tetr, name=ktx).\\n\",\"dna[dna[ptet-forward]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]:dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:dna[pconst-reverse]]+protein[RNAP] <--> ordered_polymer[dna[ptet-forward]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]:dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:complex[dna[pconst]:protein[RNAP]-reverse]]\\n Kf=k_forward * dna_ptet_f_UTR1_f_GFP_f_t16_f_t16_r_RFP_r_UTR1_r_pconst_r * protein_RNAP\\n Kr=k_reverse * ordered_polymer_ptet_f_UTR1_f_GFP_f_t16_f_t16_r_RFP_r_UTR1_r_dna_pconst_protein_RNAP_r\\n k_forward=100\\n found_key=(mech=None, partid=None, name=kb).\\n search_key=(mech=transcription_mm, partid=pconst, name=kb).\\n k_reverse=10\\n found_key=(mech=None, partid=None, name=ku).\\n search_key=(mech=transcription_mm, partid=pconst, name=ku).\\n\",\"ordered_polymer[dna[ptet-forward]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]:dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:complex[dna[pconst]:protein[RNAP]-reverse]] --> dna[dna[ptet-forward]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]:dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:dna[pconst-reverse]]+rna[rna[UTR1-forward]:rna[RFP-forward]:rna[t16-forward]]+protein[RNAP]\\n Kf=k_forward * ordered_polymer_ptet_f_UTR1_f_GFP_f_t16_f_t16_r_RFP_r_UTR1_r_dna_pconst_protein_RNAP_r\\n k_forward=0.05\\n found_key=(mech=None, partid=None, name=ktx).\\n search_key=(mech=transcription_mm, partid=pconst, name=ktx).\\n\",\"rna[rna[UTR1-forward]:rna[GFP-forward]:rna[t16-forward]]+protein[Ribo] <--> ordered_polymer[complex[protein[Ribo]:rna[UTR1]-forward]:rna[GFP-forward]:rna[t16-forward]]\\n Kf=k_forward * rna_UTR1_f_GFP_f_t16_f * protein_Ribo\\n Kr=k_reverse * ordered_polymer_protein_Ribo_rna_UTR1_f_GFP_f_t16_f\\n k_forward=100\\n found_key=(mech=None, partid=None, name=kb).\\n search_key=(mech=translation_mm, partid=UTR1, name=kb).\\n k_reverse=10\\n found_key=(mech=None, partid=None, name=ku).\\n search_key=(mech=translation_mm, partid=UTR1, name=ku).\\n\",\"ordered_polymer[complex[protein[Ribo]:rna[UTR1]-forward]:rna[GFP-forward]:rna[t16-forward]] --> rna[rna[UTR1-forward]:rna[GFP-forward]:rna[t16-forward]]+protein[GFP]+protein[Ribo]\\n Kf=k_forward * ordered_polymer_protein_Ribo_rna_UTR1_f_GFP_f_t16_f\\n k_forward=0.2\\n found_key=(mech=None, partid=None, name=ktl).\\n search_key=(mech=translation_mm, partid=UTR1, name=ktl).\\n\",\"rna[rna[UTR1-forward]:rna[RFP-forward]:rna[t16-forward]]+protein[Ribo] <--> ordered_polymer[complex[protein[Ribo]:rna[UTR1]-forward]:rna[RFP-forward]:rna[t16-forward]]\\n Kf=k_forward * rna_UTR1_f_RFP_f_t16_f * protein_Ribo\\n Kr=k_reverse * ordered_polymer_protein_Ribo_rna_UTR1_f_RFP_f_t16_f\\n k_forward=100\\n found_key=(mech=None, partid=None, name=kb).\\n search_key=(mech=translation_mm, partid=UTR1, name=kb).\\n k_reverse=10\\n found_key=(mech=None, partid=None, name=ku).\\n search_key=(mech=translation_mm, partid=UTR1, name=ku).\\n\",\"ordered_polymer[complex[protein[Ribo]:rna[UTR1]-forward]:rna[RFP-forward]:rna[t16-forward]] --> rna[rna[UTR1-forward]:rna[RFP-forward]:rna[t16-forward]]+protein[RFP]+protein[Ribo]\\n Kf=k_forward * ordered_polymer_protein_Ribo_rna_UTR1_f_RFP_f_t16_f\\n k_forward=0.2\\n found_key=(mech=None, partid=None, name=ktl).\\n search_key=(mech=translation_mm, partid=UTR1, name=ktl).\\n\"],\"type\":[\"nothing\",\"ordered_polymer\",\"protein\",\"ordered_polymer\",\"dna\",\"protein\",\"ordered_polymer\",\"protein\",\"protein\",\"protein\",\"rna\",\"protein\",\"ordered_polymer\",\"ordered_polymer\",\"rna\",\"ordered_polymer\",\"ordered_polymer\",\"ordered_polymer\",\"ordered_polymer\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\"]},\"selected\":{\"id\":\"1703\",\"type\":\"Selection\"},\"selection_policy\":{\"id\":\"1702\",\"type\":\"UnionRenderers\"}},\"id\":\"1534\",\"type\":\"ColumnDataSource\"},{\"attributes\":{},\"id\":\"1709\",\"type\":\"Selection\"},{\"attributes\":{\"edge_renderer\":{\"id\":\"1539\",\"type\":\"GlyphRenderer\"},\"inspection_policy\":{\"id\":\"1622\",\"type\":\"EdgesAndLinkedNodes\"},\"layout_provider\":{\"id\":\"1545\",\"type\":\"StaticLayoutProvider\"},\"node_renderer\":{\"id\":\"1535\",\"type\":\"GlyphRenderer\"},\"selection_policy\":{\"id\":\"1620\",\"type\":\"NodesAndLinkedEdges\"}},\"id\":\"1532\",\"type\":\"GraphRenderer\"},{\"attributes\":{\"graph_layout\":{\"0\":[88.27152306903504,-253.1274824878269],\"1\":[132.03573345539652,142.29992410862027],\"10\":[162.0928482698882,120.19280405820047],\"11\":[153.46703847320822,129.6375000047943],\"12\":[179.01811297167205,119.78087829435556],\"13\":[-24.382793002770676,0.2780454482461787],\"14\":[136.34159815391814,131.33388525476965],\"15\":[-40.93392405496524,10.942280437411275],\"16\":[-73.84182523293367,40.30582736768835],\"17\":[4.072716776001942,-43.37608195400387],\"18\":[-61.44792512437408,-7.602735517487976],\"19\":[48.886251192130366,-36.73834083221431],\"2\":[-280.2646995413965,4.497423062199457],\"20\":[77.33719537503133,-87.90213240396263],\"21\":[-25.39627415162268,13.089477083375455],\"22\":[-73.90281181788369,12.288377863928684],\"23\":[-58.03935844755277,12.411691754707025],\"24\":[-92.78563945472774,46.54713682497346],\"25\":[25.777306584499808,-50.57408092198795],\"26\":[62.55342839535837,-97.7874982058831],\"27\":[-18.124619009412104,-18.185897504821483],\"28\":[-45.506998465856284,29.318906337011622],\"29\":[-92.85347895877348,62.838190585367364],\"3\":[55.37320691609743,-17.857314064199937],\"30\":[32.33770424277019,-6.716575168984064],\"31\":[75.33873507217703,-14.753244894467425],\"32\":[-7.418036529321104,-9.564658745630869],\"33\":[-36.09134666156681,-6.336766959270443],\"34\":[-80.73270969198812,-21.50039115023293],\"35\":[9.94954472387104,-22.068754327541964],\"36\":[0.0457860875360908,-63.89488669215859],\"37\":[165.18968390928575,124.15142915709694],\"38\":[189.3309902751563,116.43462330149798],\"39\":[140.14899161905018,135.3819966728867],\"4\":[14.953201438630577,-9.847483223963055],\"40\":[124.65816325015204,148.84266134422492],\"5\":[229.4826153772355,61.35301119982526],\"6\":[56.84426959995666,-72.79853161574077],\"7\":[0.04069251554409696,0.007758933055522639],\"8\":[-35.550380516396345,254.9737557261887],\"9\":[-11.180744283387114,-13.926469651525597]}},\"id\":\"1513\",\"type\":\"StaticLayoutProvider\"},{\"attributes\":{\"attachment\":\"right\",\"callback\":null,\"renderers\":[{\"id\":\"1500\",\"type\":\"GraphRenderer\"}],\"tooltips\":[[\"reaction\",\"@species\"],[\"type\",\"@type\"],[\"k_f\",\"@k\"],[\"k_r\",\"@k_r\"]]},\"id\":\"1608\",\"type\":\"HoverTool\"},{\"attributes\":{\"edge_renderer\":{\"id\":\"1523\",\"type\":\"GlyphRenderer\"},\"inspection_policy\":{\"id\":\"1695\",\"type\":\"NodesOnly\"},\"layout_provider\":{\"id\":\"1529\",\"type\":\"StaticLayoutProvider\"},\"node_renderer\":{\"id\":\"1519\",\"type\":\"GlyphRenderer\"},\"selection_policy\":{\"id\":\"1696\",\"type\":\"NodesOnly\"}},\"id\":\"1516\",\"type\":\"GraphRenderer\"},{\"attributes\":{\"text\":\"\"},\"id\":\"1672\",\"type\":\"Title\"},{\"attributes\":{\"data_source\":{\"id\":\"1502\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"1576\",\"type\":\"Square\"},\"hover_glyph\":{\"id\":\"1586\",\"type\":\"Square\"},\"muted_glyph\":null,\"selection_glyph\":{\"id\":\"1581\",\"type\":\"Square\"},\"view\":{\"id\":\"1504\",\"type\":\"CDSView\"}},\"id\":\"1503\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"fill_color\":{\"value\":\"#abdda4\"},\"size\":{\"units\":\"screen\",\"value\":15}},\"id\":\"1601\",\"type\":\"Circle\"},{\"attributes\":{\"source\":{\"id\":\"1522\",\"type\":\"ColumnDataSource\"}},\"id\":\"1524\",\"type\":\"CDSView\"},{\"attributes\":{},\"id\":\"1702\",\"type\":\"UnionRenderers\"},{\"attributes\":{},\"id\":\"1669\",\"type\":\"LinearScale\"},{\"attributes\":{\"data_source\":{\"id\":\"1518\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"1591\",\"type\":\"Circle\"},\"hover_glyph\":{\"id\":\"1601\",\"type\":\"Circle\"},\"muted_glyph\":null,\"selection_glyph\":{\"id\":\"1596\",\"type\":\"Circle\"},\"view\":{\"id\":\"1520\",\"type\":\"CDSView\"}},\"id\":\"1519\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"source\":{\"id\":\"1506\",\"type\":\"ColumnDataSource\"}},\"id\":\"1508\",\"type\":\"CDSView\"},{\"attributes\":{},\"id\":\"1705\",\"type\":\"Selection\"},{\"attributes\":{\"source\":{\"id\":\"1538\",\"type\":\"ColumnDataSource\"}},\"id\":\"1540\",\"type\":\"CDSView\"},{\"attributes\":{},\"id\":\"1704\",\"type\":\"UnionRenderers\"},{\"attributes\":{\"callback\":null,\"end\":253.5142265235687,\"start\":-116.88509010510667},\"id\":\"1574\",\"type\":\"Range1d\"},{\"attributes\":{\"fill_color\":{\"value\":\"#abdda4\"},\"size\":{\"units\":\"screen\",\"value\":8}},\"id\":\"1586\",\"type\":\"Square\"},{\"attributes\":{\"data_source\":{\"id\":\"1522\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"1521\",\"type\":\"MultiLine\"},\"hover_glyph\":null,\"muted_glyph\":null,\"view\":{\"id\":\"1524\",\"type\":\"CDSView\"}},\"id\":\"1523\",\"type\":\"GlyphRenderer\"},{\"attributes\":{},\"id\":\"1708\",\"type\":\"UnionRenderers\"},{\"attributes\":{},\"id\":\"1711\",\"type\":\"Selection\"},{\"attributes\":{},\"id\":\"1713\",\"type\":\"Selection\"},{\"attributes\":{\"fill_alpha\":{\"value\":0},\"fill_color\":{\"field\":\"color\"},\"line_alpha\":{\"value\":0},\"size\":{\"units\":\"screen\",\"value\":12}},\"id\":\"1546\",\"type\":\"Circle\"},{\"attributes\":{\"fill_color\":{\"value\":\"#fdae61\"},\"size\":{\"units\":\"screen\",\"value\":8}},\"id\":\"1581\",\"type\":\"Square\"},{\"attributes\":{\"fill_color\":{\"value\":\"#fdae61\"},\"size\":{\"units\":\"screen\",\"value\":15}},\"id\":\"1596\",\"type\":\"Circle\"},{\"attributes\":{\"data_source\":{\"id\":\"1538\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"1551\",\"type\":\"MultiLine\"},\"hover_glyph\":{\"id\":\"1561\",\"type\":\"MultiLine\"},\"muted_glyph\":null,\"selection_glyph\":{\"id\":\"1556\",\"type\":\"MultiLine\"},\"view\":{\"id\":\"1540\",\"type\":\"CDSView\"}},\"id\":\"1539\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"callback\":null,\"renderers\":[{\"id\":\"1532\",\"type\":\"GraphRenderer\"}],\"tooltips\":null},\"id\":\"1606\",\"type\":\"HoverTool\"},{\"attributes\":{\"edge_renderer\":{\"id\":\"1507\",\"type\":\"GlyphRenderer\"},\"inspection_policy\":{\"id\":\"1685\",\"type\":\"NodesOnly\"},\"layout_provider\":{\"id\":\"1513\",\"type\":\"StaticLayoutProvider\"},\"node_renderer\":{\"id\":\"1503\",\"type\":\"GlyphRenderer\"},\"selection_policy\":{\"id\":\"1686\",\"type\":\"NodesOnly\"}},\"id\":\"1500\",\"type\":\"GraphRenderer\"},{\"attributes\":{},\"id\":\"1620\",\"type\":\"NodesAndLinkedEdges\"},{\"attributes\":{\"line_color\":{\"value\":\"#abdda4\"},\"line_join\":\"round\",\"line_width\":{\"value\":5}},\"id\":\"1561\",\"type\":\"MultiLine\"},{\"attributes\":{\"callback\":null,\"data\":{\"end\":[],\"start\":[]},\"selected\":{\"id\":\"1713\",\"type\":\"Selection\"},\"selection_policy\":{\"id\":\"1712\",\"type\":\"UnionRenderers\"}},\"id\":\"1522\",\"type\":\"ColumnDataSource\"},{\"attributes\":{},\"id\":\"1611\",\"type\":\"PanTool\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"size\":{\"units\":\"screen\",\"value\":12}},\"id\":\"1591\",\"type\":\"Circle\"},{\"attributes\":{\"bottom_units\":\"screen\",\"fill_alpha\":{\"value\":0.5},\"fill_color\":{\"value\":\"lightgrey\"},\"left_units\":\"screen\",\"level\":\"overlay\",\"line_alpha\":{\"value\":1.0},\"line_color\":{\"value\":\"black\"},\"line_dash\":[4,4],\"line_width\":{\"value\":2},\"render_mode\":\"css\",\"right_units\":\"screen\",\"top_units\":\"screen\"},\"id\":\"1701\",\"type\":\"BoxAnnotation\"},{\"attributes\":{\"line_color\":{\"value\":\"#fdae61\"},\"line_join\":\"round\",\"line_width\":{\"value\":5}},\"id\":\"1556\",\"type\":\"MultiLine\"},{\"attributes\":{},\"id\":\"1695\",\"type\":\"NodesOnly\"},{\"attributes\":{},\"id\":\"1685\",\"type\":\"NodesOnly\"}],\"root_ids\":[\"1495\"]},\"title\":\"Bokeh Application\",\"version\":\"1.4.0\"}};\n var render_items = [{\"docid\":\"d2bf46f9-7fc1-4914-8741-9975303e6e0b\",\"roots\":{\"1495\":\"e0d50524-8cf2-47a8-9ddb-a53499200181\"}}];\n root.Bokeh.embed.embed_items_notebook(docs_json, render_items);\n\n }\n if (root.Bokeh !== undefined) {\n embed_document(root);\n } else {\n var attempts = 0;\n var timer = setInterval(function(root) {\n if (root.Bokeh !== undefined) {\n clearInterval(timer);\n embed_document(root);\n } else {\n attempts++;\n if (attempts > 100) {\n clearInterval(timer);\n console.log(\"Bokeh: ERROR: Unable to run BokehJS code because BokehJS library is missing\");\n }\n }\n }, 10, root)\n }\n})(window);", + "application/vnd.bokehjs_exec.v0+json": "" + }, + "metadata": { + "application/vnd.bokehjs_exec.v0+json": { + "id": "1495" + } + } + } + ], + "source": [ + "\n", + "# plotNetwork(myCRN)\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now you can see that many more arrows lead to each RNA. But there is still only one promoter per RNA, how can it be? Well, now that both promoters and transcripts are on the same DNA, we must take into account the fact that you can have both promoters with RNA polymerase bound, so for example Promoter1 can lead to RNA1 whether or not Promoter2 is bound by RNAP.\n", + "\n", + "We can even make a more complicated DNA construct, such as what happens before and after a promoter is \"flipped\" by integrase activity" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": { + "tags": [] + }, + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": "t16_r_RFP_r_UTR1_r_attP_pconst_attB_r_UTR1_GFP_t16\n\tpconst_4\n\trna = attB_r_UTR1_GFP_t16\n\tUTR1_1\n\tprotein = GFP_2\n" + }, + { + "output_type": "display_data", + "data": { + "text/plain": "
", + "image/svg+xml": "\r\n\r\n\r\n\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n\r\n", + "image/png": "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\n" + }, + "metadata": { + "needs_background": "light" + } + }, + { + "output_type": "display_data", + "data": { + "text/plain": "
", + "image/svg+xml": "\r\n\r\n\r\n\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n\r\n", + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAOYAAABtCAYAAAC1HR2gAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADh0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uMy4xLjMsIGh0dHA6Ly9tYXRwbG90bGliLm9yZy+AADFEAAARKElEQVR4nO2de3hU9ZnHP29CQoCYBAki94vgBVBE2SJaRVtBxRu0FitC13p93EV0RWVFtIh4q7qgrVbXqnUFVrAoIhZR6u1RsNYCAVnBC1exBLkEQiBAknf/+J1JhjGTTJKZOSeT9/M88zxzfud3zvueM/P93S+iqhiGESzS/HbAMIwfYsI0jABiwjSMAGLCNIwAYsI0jABiwjSMAGLCNIwAYsI0EJEWIvKGiOwWkVf89iccEblRRApFZK+ItAmAP2eIyFeeP8MTZkhVU/oDnA18GxE2GZgREfY+UArsBbYDrwLt4+zLn4CpEWHdAAWaebZDnwpgf9jxlZ7fh7zjImAJMCjsXpnAn4EN3j3PjtGvMcCnQLNa4l0FlHv29wAFwEXVPEv4cxREuXZF+LVR7GV476BfDM+gQM+6vAvgFOBDz6dC4OYY7Pw1lngN/SQ1xxSRZsm0Vw/Gqmo20BPIBh6t6w0a8oyqmh36AJuAi8PCZnrRZnvn84H3gMgc7iNgNLC1Dqa7Al+qalkMcZd69vOAp4CXRSQvIk5emN/9olz7HDBHRI6swVY7IAtYHfOTHE7UdyEi+cBbwDNAG9xv/nYM9+zaAH9iJuHCFJENIjJBRFYCJSLyrYjcJiIrvaLTbBHJ8uK2FpEFIvK9iOzyvneKwcavReQLESkWkXUicoMX3gpYCHTwih57RWQUMBG43DsuiLyfqhYB84CTY7A9WUT+LCIzRGQPLmdIOJ6IZgIdRaStF3ZQVaer6ke43KlWRORe4B6q3sc1MdqvAF4CWgG96uh7BfA80ALoEcWvY4G13mGRiLwb7X4i8qH3tcB7hstjeBe3AotUdaaqHlDVYlX9oia/ReQbz983PDvNa3zQBpCsHPMK4EJcSlkGjATOB7oDJ1H1Z04DXsClSl1wxZjfx3D/bcBFQA7wa2CaiJyiqiXABcB3YSn4LOABvJwnIkUHwKvL/Az4OsbnuxRXbMrDiSXhiEgm8CtgB7CrvvdR1d9w+Pt4Lkb76bh3fQjYWBebXqniWlwR8qsofn0J9PEO81T1J9Hup6pneV/7ec8wOwY3TgN2isgSEdnm1bG71HSBqh7D4SWZAzHYqRfJEuYTqrpZVfeHHX+nqjuBN/ByJlXdoapzVXWfqhYD9wODa7u5qr6pqt+o4wNckeTM+vgpIrtxdcx84KYYr1uqqvNUtSLsGRPFSBEpwiVa1wGXxVgEjRenefZLcUX90aq6LSLOdhEp8j63VXPtVlxiPUJVdyfH7R/QCfhX4GZcJrAe+F+ffPkByRLm5ojj8DL/Plx9DhFpKSLPiMhGr1j4IZDnpc5REZELROQTEdnp/fDDcMKqK+NUNReXi7fG/XixEPl80SjDNWiEk4Fr6KmI8R5zVDUPV//6HDg1xuvixSee/dbAfKpPAPNVNc/7PBp5rarmq+ppqro4KR5Xz37gNVX9u6qWAvcCp4tIro8+VZIsYcY6t2w8cBwwUFVzgFARRaJd4JXz5+JS73ben+YvYddUZ7tGf1R1FTAVeFJEotqO9X5hbMK1XIbTHdjs1btiRlW3AzcAk0WkfV2ujQequhf4N2CMiPRPtv04sJLDf7fQ91h+74QTtH7MI3ApWZHXWvebGK7JBJoD3wNlInIBMDTsfCHQJiIlLAS6iUhNz/8icBRwSR38r425wIUiMlRE0kWkAzAJeLk+N1PVNcAi4I5QmIg0DzWmAZkikhVj4lIf+zuAP+Iaj/ymkIiGpFrexQvACBE5WUQygLuBj7yGP98JmjCn41rqtgOf4Jqza8Sri44D5uAaQUbhilih82twdYd1Xp2nA1VdDDtEZFmU+x4EnsD9YHFBVVfj6lYPAjuBpcDfcMWo+vIIcL2IHOUdr8Ulbh1xot2Pa0xLFNOBYSJyUgJtxMJk4EXvNx7phUV9F6r6Lq51/k1c42FP3H8nEIjXaWoYRoAIWo5pGAaNSJhhAwQiP/XpFqmr7YVRbE9sSNxkIiKro/h1ZUS8p6PEezpBfk2MYm9hRLwzo/0H4uxPUuzU6ocVZQ0jeDSaHNMwmhImTMMIICZMwwggJkzDCCAmTMMIICZMwwggJkzDCCAmTMMIICZMwwggJkzDCCAmTMMIICZMwwggJkzDX0RyqXkliSZJ0BdgNlKf3sAYRP4dH6Y6benYOeE2O27ZXOelXSylMoLAjbjFzwwPE6YRFCZy+Bq0TRqbKG34i8gg3OZIIa4lxtXgk014sbc+xdO6YDmmETT+G5HL/HbCb0yYRtBIA2YhMrTWmCmMCdMIIhnAa4ic7rcjfmHCNALDt63b88/c0LrVtATexP+FpH0h9YQpIiRoSwAjsexqmcu40Q+ws2XlbhZ5wNuI9PTRLV9IHWE6QV6Ma+EzYTZSNrfpxC1X3s/e5i1DQe2AxYh09NGtpNP4hSnSDJErgALcniWn+eyR0UC+bN+T8VdMobRZ5YbNXYF3cNuzNwkarzBFmiNyHbAGmAWc6LNHRhwp6NKXO38xibK0yq1RTwAWIpLjo1tJo/GNlRVpBVwP3AZ0SLLtI4B+VG1sm47bQeorYBmwuUHjPd0W87HuYp0qdI52Ymmvf2HyiDuYMvch0tz2lQOA1xG5ALfZbMrSeIQp0hoYi9uau034qdKMVmQdKkmU3Rzc9mzX4HZvrqn++j0is4BncVvu1ZVY9wRtMizuM5hWpSXc+eYToaCzgdmIXIbqIf88SyzBL8qKHI3Iw7jdmKcQJsqS5rks7f1LZg2Zhsa7vccVlScD/wT+gEutazPSFpdwfI7IO4gcG1+nmiavnzqMJ396dXjQJcDzqTxdLLg5pkg34HZcTtU8/NSelvms6HkRX3Y+k/L0zETYHgQ8h6vXVFKeJmzunM267jlsb5OFpgkt9x2i68ZieqzfQ3ZJWXj0c4GViNwHPIRqeV1c2J2VzSs/urShT9Ko2JYTvW3npTNGkrO/mDFLQnsOMxrYhcjNfkwXSzTBE6ZIH9zW5Vfi6nCV7DyiIyt6Xsw3HQdSkZYg191uxC/htpAHYGPnbN46rwvvD+5ISXZG9ZdVKP1WbmfoO5sZ9Ekh6RUKLkGZCpyKyKi61Iv2tMzhj2ePadCjpBpP/vRqskv3MmJZ5Q59N+F2EU+54n9whCkyGngYaE9EkXFbXneW97qEDUefAoksvbhulxl4Rfx9Wem8NOY4Fp7XlYr0mkuxmiasOLktK05uS/f1exj71Cp6fb07dHoEMBeREbgt5I36IMIjw8aSfWAfQ1Z/EAq9B5FdqE7307V4468w3QidsbgUr03k6S35J7C81yVsye8DiR7MI9IXeAFPlJs6ZTPl7gFsO6plzddVw/ruOdz+0Olc9T9rGD5/fSh4GHAfMCFOHjdJKtLSuXf4bWSXljDom89CwdMQKUL1Tz66Flf8qTy7UTq/AXYDTxAhyg3t+jPvx/ew4PSJbGnbNxmibA7MxKvLbuqUzcSpA+slyhAV6cLzVx3PnJ8fEx58OyKDG+SrQVl6Bv85chIFnXuHBz+HyAi/fIo3yRWmSAYi04F9wGTgiMgonx07nEUDb6XwyF7J9OxmXN8kBzLTePiO/uzJbV7LJTEgwsxRx7KiX2W6I8CzqdyamCwOZGQx/ooprD26MuFLA15G5Fwf3YobyfmDiLRC5AWgBCeCrMM8yK6KWtLiByXaRPuWQVin/ktXHsfmzj9IL+qNpgnTb+pHScvKWkMvXLHWaCB7s7L5j1FT2XRk5TDaTGAeIgN9dCsuJFaYIm0RmYsrsl6Fm2fnyMCNar0Z91f1j+FAJ4Ci3Ez+ckGXuBvY2SaLRUMOG+ByS9yNNFF2Zrdm3OgHKKzqammFG7rX10e3GkxihCnSFZG3gULgZ4R3e2QBZ+H+mucB/o98vDj05a2hXSjLSK8pbr15c1g3Kqqqyucgkl1DdKMObM1rx7jRD7KrarpYa9x0sR4+utUg4itMkd6IfAxsAIYQ3u3RCtflfgtwDm4abDD4UejLP05pmzAj3x/Vgk2dK7WYBpySMGNNkI35nbll1FRKMiv/WO1x08WSO546TsSnu0TkNOBp3ADvw8kFzgBOJrwgGwzcoPTjQof5O0rJ+Xthwsy1LjqsC3MA8GHCjDVB1nboxW2/nMy0WZPIKjsI0B2Xc56F6k6f3asTsQlTpO5DnvKBHwN9iRi/kxTK69PFMuHR5QlwJSqPIfJYMg02BZZ3O4m7LruLh+dMoVlFOUAfYEdcutw6dKr6Xh9NhKNao0OJqWOm43LIE/BDlEYTZ1WnEyjMSVy1JBkkZuRPObAY+AgY6H1aJMSSYRxGywP7mDZrEh2LtvrtSoOITZi1ZLsAiLQDnsG1crqcuBT4ALcKzwBgENUMKUgI6ahWJMVSPBHpBXzptxuNlcyyg/x29r30+a7yFSowCtWX43H/ZC46FL+irGohqsNxK5vNAKrmQB0ClgKPAwtw8wEMI46kV5Rz39wHGbChIDz4xniJMtnEv46pWozqGNx4nieBA5XnyoF/AL8DXgO2xd260QQRrWDi/GkMXrs0PPhOVJ/xy6eGkriRP6oHUB2L68G8HzcczzsHrMStCzAbaFQN2UagUOWWRc9w4crF4aGP4KYQNloSP1ZWtRzVSbja5XgiZbgG2HhY/IS7ZKQO134wg8s/fT086FlgQmNf1SB5sxxUFdX/QrUNbrmQapvN+n/9Bl23LjOBGrUy8m/zuPbDmeFBr+DqlY3+z+PP9CPV51Ftj5vZvz78VM6+7zn/02lc9v5dHPPtUqSiTkvlGE2EYQXvcOuip8ODFgGj67q2UlDxd16g6jxUewA/Af4v/FSb4s2cu+wpLn/3Do7f+B5p5Sm7UqFRR85as4SJ86eFB30M/DyVlm0JxoRd1fdQ7YMb2B2atwlA7r5tDC54nlF/Hc+J3yykWVlKr/Nr1MKAdcuZOvdBmlV1UxcAF6GaoIWF/SE4i3EBqC4Hrkbkdtzk5XG4KTy0Kt3F6atn0f+r+azqcR6ruw3hYGYrP71NKOkV5eQX7/DbjaRSlpZOUau8qOd7b1nLb2ffS2ZV6elr4DxUi5LhXzKRQNeT3eyPG3CtuUeHnzrYLIvV3c5lVY/z2Z+Vy/Xzf4VQ+Sw28qcRsqrj8Vx3TfWL3fXYtoE/vHg7ufuLQ0FbgDNQ3VjtBY2cYOWYkagWA48i8nvcCggTgG4AmWWl9P96ASeuW8SaLoPDRWmkGO13beXxGRPDRbkDGJKqooSgCzOEWyj5aUSeAy4H7gR6AzSrOETfDYtruroxUY7bkqEpkUk1S5eGaFO8g9/NuJO2eyu7v4uB81H9IhnO+UXjEGYIt4nMDG/jnkuBibjh8amB6jqSvYOZ37jtKJZUdypnfzGPz7yLTrsq06oDwCWoflZd/FQiGK2ydUW1AtXXcMuCDAXe99chI960OLifx2bdTc9tG0JB5cAvUH3fN6eSSOMUZgg3mugdVM/BLWCywG+XjIaTUXaQh+bcx4lb1oQHX4XqG375lGwaV1G2JlSXABcj0g+sJaixkl5RzpRXH2bgumXhwWNRneGXT36QOsIMoVpQeyQjiAgwYcHjnLPm4/Dgu1F90ieXfCPY/ZhG6hPW+FOBhLZ0DzENGJ8Kg9LrSuOuYxopRYQoX6CJihJMmEYweRW4vqmKEkyYRvBYjFtAq6zWmCmMCdMIEp8AI1A9UGvMFMeEaQSFz4ELUd3rtyNBwIRpBIF1wNDGtr9IIrHuEsNf3FS3cm+csOFhwjSMAGJFWcMIICZMwwggJkzDCCAmTMMIICZMwwggJkzDCCAmTMMIICZMwwggJkzDCCAmTMMIICZMwwggJkzDCCAmTMMIICZMwwggJkzDCCAmTMMIICZMwwggJkzDCCD/D0j5Rn3Xa3sXAAAAAElFTkSuQmCC\n" + }, + "metadata": { + "needs_background": "light" + } + }, + { + "output_type": "stream", + "name": "stdout", + "text": "t16_r_RFP_r_UTR1_r_attP_pconst_attB_r_UTR1_GFP_t16\n\tpconst_4\n\trna = attB_r_UTR1_GFP_t16\n\tUTR1_1\n\tprotein = GFP_2\nt16_r_RFP_r_UTR1_r_attR_pconst_r_attL_r_UTR1_GFP_t16\n\tpconst_4_r\n\trna = attR_r_UTR1_RFP_t16\n\tUTR1_1\n\tprotein = RFP_2\n" + } + ], + "source": [ + "attB = AttachmentSite(\"attB\",\"attB\",integrase=\"Bxb1\")\n", + "attP = AttachmentSite(\"attP\",\"attP\",integrase=\"Bxb1\")\n", + "attL = AttachmentSite(\"attL\",\"attL\",integrase=\"Bxb1\")\n", + "attR = AttachmentSite(\"attR\",\"attR\",integrase=\"Bxb1\")\n", + "\n", + "\n", + "construct_1 = DNA_construct([[t16,\"reverse\"],[rfp,\"reverse\"],[utr1,\"reverse\"],[attP,\"forward\"],[pconst,\"forward\"],[attB,\"reverse\"],[utr1,\"forward\"],[gfp,\"forward\"],[t16,\"forward\"]])\n", + "construct_2 = DNA_construct([[t16,\"reverse\"],[rfp,\"reverse\"],[utr1,\"reverse\"],[attR,\"forward\"],[pconst,\"reverse\"],[attL,\"reverse\"],[utr1,\"forward\"],[gfp,\"forward\"],[t16,\"forward\"]])\n", + "#now, we are using dnaplotlib to plot the constructs\n", + "\n", + "if(dpl_enabled):\n", + " plotConstruct(construct_1,debug=False,plot_rnas=True,plot_dna_test=False)\n", + " plotConstruct(construct_2,debug=False,plot_rnas=True)\n", + " plotConstruct(construct_1,debug=False,plot_rnas=True,plot_dna_test=False)\n", + " plotConstruct(construct_2,debug=False,plot_rnas=True,plot_dna_test=False)\n", + "\n", + "#some very basic parameters are defined\n", + "parameters={\"cooperativity\":2,\"kb\":100, \"ku\":10, \"ktx\":.05, \"ktl\":.2, \"kdeg\":2,\"kint\":.05}\n", + "\n", + "components = [construct_1,construct_2]\n", + "myMixture = TxTlExtract(name = \"txtl\", parameters = parameters, components = components)\n", + "myCRN = myMixture.compile_crn()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "And we can see that this construct 'knows' that a forward facing promoter will not produce RNAs that face the reverse direction." + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": { + "tags": [] + }, + "outputs": [ + { + "output_type": "display_data", + "data": { + "text/html": "\n
\n \n Loading BokehJS ...\n
" + }, + "metadata": {} + }, + { + "output_type": "display_data", + "data": { + "application/javascript": "\n(function(root) {\n function now() {\n return new Date();\n }\n\n var force = true;\n\n if (typeof root._bokeh_onload_callbacks === \"undefined\" || force === true) {\n root._bokeh_onload_callbacks = [];\n root._bokeh_is_loading = undefined;\n }\n\n var JS_MIME_TYPE = 'application/javascript';\n var HTML_MIME_TYPE = 'text/html';\n var EXEC_MIME_TYPE = 'application/vnd.bokehjs_exec.v0+json';\n var CLASS_NAME = 'output_bokeh rendered_html';\n\n /**\n * Render data to the DOM node\n */\n function render(props, node) {\n var script = document.createElement(\"script\");\n node.appendChild(script);\n }\n\n /**\n * Handle when an output is cleared or removed\n */\n function handleClearOutput(event, handle) {\n var cell = handle.cell;\n\n var id = cell.output_area._bokeh_element_id;\n var server_id = cell.output_area._bokeh_server_id;\n // Clean up Bokeh references\n if (id != null && id in Bokeh.index) {\n Bokeh.index[id].model.document.clear();\n delete Bokeh.index[id];\n }\n\n if (server_id !== undefined) {\n // Clean up Bokeh references\n var cmd = \"from bokeh.io.state import curstate; print(curstate().uuid_to_server['\" + server_id + \"'].get_sessions()[0].document.roots[0]._id)\";\n cell.notebook.kernel.execute(cmd, {\n iopub: {\n output: function(msg) {\n var id = msg.content.text.trim();\n if (id in Bokeh.index) {\n Bokeh.index[id].model.document.clear();\n delete Bokeh.index[id];\n }\n }\n }\n });\n // Destroy server and session\n var cmd = \"import bokeh.io.notebook as ion; ion.destroy_server('\" + server_id + \"')\";\n cell.notebook.kernel.execute(cmd);\n }\n }\n\n /**\n * Handle when a new output is added\n */\n function handleAddOutput(event, handle) {\n var output_area = handle.output_area;\n var output = handle.output;\n\n // limit handleAddOutput to display_data with EXEC_MIME_TYPE content only\n if ((output.output_type != \"display_data\") || (!output.data.hasOwnProperty(EXEC_MIME_TYPE))) {\n return\n }\n\n var toinsert = output_area.element.find(\".\" + CLASS_NAME.split(' ')[0]);\n\n if (output.metadata[EXEC_MIME_TYPE][\"id\"] !== undefined) {\n toinsert[toinsert.length - 1].firstChild.textContent = output.data[JS_MIME_TYPE];\n // store reference to embed id on output_area\n output_area._bokeh_element_id = output.metadata[EXEC_MIME_TYPE][\"id\"];\n }\n if (output.metadata[EXEC_MIME_TYPE][\"server_id\"] !== undefined) {\n var bk_div = document.createElement(\"div\");\n bk_div.innerHTML = output.data[HTML_MIME_TYPE];\n var script_attrs = bk_div.children[0].attributes;\n for (var i = 0; i < script_attrs.length; i++) {\n toinsert[toinsert.length - 1].firstChild.setAttribute(script_attrs[i].name, script_attrs[i].value);\n }\n // store reference to server id on output_area\n output_area._bokeh_server_id = output.metadata[EXEC_MIME_TYPE][\"server_id\"];\n }\n }\n\n function register_renderer(events, OutputArea) {\n\n function append_mime(data, metadata, element) {\n // create a DOM node to render to\n var toinsert = this.create_output_subarea(\n metadata,\n CLASS_NAME,\n EXEC_MIME_TYPE\n );\n this.keyboard_manager.register_events(toinsert);\n // Render to node\n var props = {data: data, metadata: metadata[EXEC_MIME_TYPE]};\n render(props, toinsert[toinsert.length - 1]);\n element.append(toinsert);\n return toinsert\n }\n\n /* Handle when an output is cleared or removed */\n events.on('clear_output.CodeCell', handleClearOutput);\n events.on('delete.Cell', handleClearOutput);\n\n /* Handle when a new output is added */\n events.on('output_added.OutputArea', handleAddOutput);\n\n /**\n * Register the mime type and append_mime function with output_area\n */\n OutputArea.prototype.register_mime_type(EXEC_MIME_TYPE, append_mime, {\n /* Is output safe? */\n safe: true,\n /* Index of renderer in `output_area.display_order` */\n index: 0\n });\n }\n\n // register the mime type if in Jupyter Notebook environment and previously unregistered\n if (root.Jupyter !== undefined) {\n var events = require('base/js/events');\n var OutputArea = require('notebook/js/outputarea').OutputArea;\n\n if (OutputArea.prototype.mime_types().indexOf(EXEC_MIME_TYPE) == -1) {\n register_renderer(events, OutputArea);\n }\n }\n\n \n if (typeof (root._bokeh_timeout) === \"undefined\" || force === true) {\n root._bokeh_timeout = Date.now() + 5000;\n root._bokeh_failed_load = false;\n }\n\n var NB_LOAD_WARNING = {'data': {'text/html':\n \"
\\n\"+\n \"

\\n\"+\n \"BokehJS does not appear to have successfully loaded. If loading BokehJS from CDN, this \\n\"+\n \"may be due to a slow or bad network connection. Possible fixes:\\n\"+\n \"

\\n\"+\n \"
    \\n\"+\n \"
  • re-rerun `output_notebook()` to attempt to load from CDN again, or
  • \\n\"+\n \"
  • use INLINE resources instead, as so:
  • \\n\"+\n \"
\\n\"+\n \"\\n\"+\n \"from bokeh.resources import INLINE\\n\"+\n \"output_notebook(resources=INLINE)\\n\"+\n \"\\n\"+\n \"
\"}};\n\n function display_loaded() {\n var el = document.getElementById(\"2028\");\n if (el != null) {\n el.textContent = \"BokehJS is loading...\";\n }\n if (root.Bokeh !== undefined) {\n if (el != null) {\n el.textContent = \"BokehJS \" + root.Bokeh.version + \" successfully loaded.\";\n }\n } else if (Date.now() < root._bokeh_timeout) {\n setTimeout(display_loaded, 100)\n }\n }\n\n\n function run_callbacks() {\n try {\n root._bokeh_onload_callbacks.forEach(function(callback) {\n if (callback != null)\n callback();\n });\n } finally {\n delete root._bokeh_onload_callbacks\n }\n console.debug(\"Bokeh: all callbacks have finished\");\n }\n\n function load_libs(css_urls, js_urls, callback) {\n if (css_urls == null) css_urls = [];\n if (js_urls == null) js_urls = [];\n\n root._bokeh_onload_callbacks.push(callback);\n if (root._bokeh_is_loading > 0) {\n console.debug(\"Bokeh: BokehJS is being loaded, scheduling callback at\", now());\n return null;\n }\n if (js_urls == null || js_urls.length === 0) {\n run_callbacks();\n return null;\n }\n console.debug(\"Bokeh: BokehJS not loaded, scheduling load and callback at\", now());\n root._bokeh_is_loading = css_urls.length + js_urls.length;\n\n function on_load() {\n root._bokeh_is_loading--;\n if (root._bokeh_is_loading === 0) {\n console.debug(\"Bokeh: all BokehJS libraries/stylesheets loaded\");\n run_callbacks()\n }\n }\n\n function on_error() {\n console.error(\"failed to load \" + url);\n }\n\n for (var i = 0; i < css_urls.length; i++) {\n var url = css_urls[i];\n const element = document.createElement(\"link\");\n element.onload = on_load;\n element.onerror = on_error;\n element.rel = \"stylesheet\";\n element.type = \"text/css\";\n element.href = url;\n console.debug(\"Bokeh: injecting link tag for BokehJS stylesheet: \", url);\n document.body.appendChild(element);\n }\n\n for (var i = 0; i < js_urls.length; i++) {\n var url = js_urls[i];\n var element = document.createElement('script');\n element.onload = on_load;\n element.onerror = on_error;\n element.async = false;\n element.src = url;\n console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n document.head.appendChild(element);\n }\n };var element = document.getElementById(\"2028\");\n if (element == null) {\n console.error(\"Bokeh: ERROR: autoload.js configured with elementid '2028' but no matching script tag was found. \")\n return false;\n }\n\n function inject_raw_css(css) {\n const element = document.createElement(\"style\");\n element.appendChild(document.createTextNode(css));\n document.body.appendChild(element);\n }\n\n \n var js_urls = [\"https://cdn.pydata.org/bokeh/release/bokeh-1.4.0.min.js\", \"https://cdn.pydata.org/bokeh/release/bokeh-widgets-1.4.0.min.js\", \"https://cdn.pydata.org/bokeh/release/bokeh-tables-1.4.0.min.js\", \"https://cdn.pydata.org/bokeh/release/bokeh-gl-1.4.0.min.js\"];\n var css_urls = [];\n \n\n var inline_js = [\n function(Bokeh) {\n Bokeh.set_log_level(\"info\");\n },\n function(Bokeh) {\n \n \n }\n ];\n\n function run_inline_js() {\n \n if (root.Bokeh !== undefined || force === true) {\n \n for (var i = 0; i < inline_js.length; i++) {\n inline_js[i].call(root, root.Bokeh);\n }\n if (force === true) {\n display_loaded();\n }} else if (Date.now() < root._bokeh_timeout) {\n setTimeout(run_inline_js, 100);\n } else if (!root._bokeh_failed_load) {\n console.log(\"Bokeh: BokehJS failed to load within specified timeout.\");\n root._bokeh_failed_load = true;\n } else if (force !== true) {\n var cell = $(document.getElementById(\"2028\")).parents('.cell').data().cell;\n cell.output_area.append_execute_result(NB_LOAD_WARNING)\n }\n\n }\n\n if (root._bokeh_is_loading === 0) {\n console.debug(\"Bokeh: BokehJS loaded, going straight to plotting\");\n run_inline_js();\n } else {\n load_libs(css_urls, js_urls, function() {\n console.debug(\"Bokeh: BokehJS plotting callback run at\", now());\n run_inline_js();\n });\n }\n}(window));", + "application/vnd.bokehjs_load.v0+json": "\n(function(root) {\n function now() {\n return new Date();\n }\n\n var force = true;\n\n if (typeof root._bokeh_onload_callbacks === \"undefined\" || force === true) {\n root._bokeh_onload_callbacks = [];\n root._bokeh_is_loading = undefined;\n }\n\n \n\n \n if (typeof (root._bokeh_timeout) === \"undefined\" || force === true) {\n root._bokeh_timeout = Date.now() + 5000;\n root._bokeh_failed_load = false;\n }\n\n var NB_LOAD_WARNING = {'data': {'text/html':\n \"
\\n\"+\n \"

\\n\"+\n \"BokehJS does not appear to have successfully loaded. If loading BokehJS from CDN, this \\n\"+\n \"may be due to a slow or bad network connection. Possible fixes:\\n\"+\n \"

\\n\"+\n \"
    \\n\"+\n \"
  • re-rerun `output_notebook()` to attempt to load from CDN again, or
  • \\n\"+\n \"
  • use INLINE resources instead, as so:
  • \\n\"+\n \"
\\n\"+\n \"\\n\"+\n \"from bokeh.resources import INLINE\\n\"+\n \"output_notebook(resources=INLINE)\\n\"+\n \"\\n\"+\n \"
\"}};\n\n function display_loaded() {\n var el = document.getElementById(\"2028\");\n if (el != null) {\n el.textContent = \"BokehJS is loading...\";\n }\n if (root.Bokeh !== undefined) {\n if (el != null) {\n el.textContent = \"BokehJS \" + root.Bokeh.version + \" successfully loaded.\";\n }\n } else if (Date.now() < root._bokeh_timeout) {\n setTimeout(display_loaded, 100)\n }\n }\n\n\n function run_callbacks() {\n try {\n root._bokeh_onload_callbacks.forEach(function(callback) {\n if (callback != null)\n callback();\n });\n } finally {\n delete root._bokeh_onload_callbacks\n }\n console.debug(\"Bokeh: all callbacks have finished\");\n }\n\n function load_libs(css_urls, js_urls, callback) {\n if (css_urls == null) css_urls = [];\n if (js_urls == null) js_urls = [];\n\n root._bokeh_onload_callbacks.push(callback);\n if (root._bokeh_is_loading > 0) {\n console.debug(\"Bokeh: BokehJS is being loaded, scheduling callback at\", now());\n return null;\n }\n if (js_urls == null || js_urls.length === 0) {\n run_callbacks();\n return null;\n }\n console.debug(\"Bokeh: BokehJS not loaded, scheduling load and callback at\", now());\n root._bokeh_is_loading = css_urls.length + js_urls.length;\n\n function on_load() {\n root._bokeh_is_loading--;\n if (root._bokeh_is_loading === 0) {\n console.debug(\"Bokeh: all BokehJS libraries/stylesheets loaded\");\n run_callbacks()\n }\n }\n\n function on_error() {\n console.error(\"failed to load \" + url);\n }\n\n for (var i = 0; i < css_urls.length; i++) {\n var url = css_urls[i];\n const element = document.createElement(\"link\");\n element.onload = on_load;\n element.onerror = on_error;\n element.rel = \"stylesheet\";\n element.type = \"text/css\";\n element.href = url;\n console.debug(\"Bokeh: injecting link tag for BokehJS stylesheet: \", url);\n document.body.appendChild(element);\n }\n\n for (var i = 0; i < js_urls.length; i++) {\n var url = js_urls[i];\n var element = document.createElement('script');\n element.onload = on_load;\n element.onerror = on_error;\n element.async = false;\n element.src = url;\n console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n document.head.appendChild(element);\n }\n };var element = document.getElementById(\"2028\");\n if (element == null) {\n console.error(\"Bokeh: ERROR: autoload.js configured with elementid '2028' but no matching script tag was found. \")\n return false;\n }\n\n function inject_raw_css(css) {\n const element = document.createElement(\"style\");\n element.appendChild(document.createTextNode(css));\n document.body.appendChild(element);\n }\n\n \n var js_urls = [\"https://cdn.pydata.org/bokeh/release/bokeh-1.4.0.min.js\", \"https://cdn.pydata.org/bokeh/release/bokeh-widgets-1.4.0.min.js\", \"https://cdn.pydata.org/bokeh/release/bokeh-tables-1.4.0.min.js\", \"https://cdn.pydata.org/bokeh/release/bokeh-gl-1.4.0.min.js\"];\n var css_urls = [];\n \n\n var inline_js = [\n function(Bokeh) {\n Bokeh.set_log_level(\"info\");\n },\n function(Bokeh) {\n \n \n }\n ];\n\n function run_inline_js() {\n \n if (root.Bokeh !== undefined || force === true) {\n \n for (var i = 0; i < inline_js.length; i++) {\n inline_js[i].call(root, root.Bokeh);\n }\n if (force === true) {\n display_loaded();\n }} else if (Date.now() < root._bokeh_timeout) {\n setTimeout(run_inline_js, 100);\n } else if (!root._bokeh_failed_load) {\n console.log(\"Bokeh: BokehJS failed to load within specified timeout.\");\n root._bokeh_failed_load = true;\n } else if (force !== true) {\n var cell = $(document.getElementById(\"2028\")).parents('.cell').data().cell;\n cell.output_area.append_execute_result(NB_LOAD_WARNING)\n }\n\n }\n\n if (root._bokeh_is_loading === 0) {\n console.debug(\"Bokeh: BokehJS loaded, going straight to plotting\");\n run_inline_js();\n } else {\n load_libs(css_urls, js_urls, function() {\n console.debug(\"Bokeh: BokehJS plotting callback run at\", now());\n run_inline_js();\n });\n }\n}(window));" + }, + "metadata": {} + }, + { + "output_type": "stream", + "name": "stderr", + "text": "D:\\anaconda3\\lib\\site-packages\\bokeh\\models\\graphs.py:164: UserWarning: Node keys in 'layout_function' don't match node keys in the graph. These nodes may not be displayed correctly.\n warn(\"Node keys in 'layout_function' don't match node keys in the graph. \"\n" + }, + { + "output_type": "display_data", + "data": { + "text/html": "\n\n\n\n\n\n
\n" + }, + "metadata": {} + }, + { + "output_type": "display_data", + "data": { + "application/javascript": "(function(root) {\n function embed_document(root) {\n \n var docs_json = {\"536c913c-73cc-42a7-939f-583c0cbb3df0\":{\"roots\":{\"references\":[{\"attributes\":{\"plot_height\":500,\"plot_width\":500,\"renderers\":[{\"id\":\"2068\",\"type\":\"GraphRenderer\"},{\"id\":\"2036\",\"type\":\"GraphRenderer\"},{\"id\":\"2052\",\"type\":\"GraphRenderer\"}],\"title\":{\"id\":\"2253\",\"type\":\"Title\"},\"toolbar\":{\"id\":\"2149\",\"type\":\"Toolbar\"},\"x_range\":{\"id\":\"2110\",\"type\":\"Range1d\"},\"x_scale\":{\"id\":\"2252\",\"type\":\"LinearScale\"},\"y_range\":{\"id\":\"2111\",\"type\":\"Range1d\"},\"y_scale\":{\"id\":\"2250\",\"type\":\"LinearScale\"}},\"id\":\"2031\",\"type\":\"Plot\"},{\"attributes\":{},\"id\":\"2158\",\"type\":\"EdgesAndLinkedNodes\"},{\"attributes\":{\"graph_layout\":{\"0\":[54.163249804316095,-372.3988437082021],\"1\":[-5.376934391232813,29.179145738729886],\"10\":[80.18597477774912,-66.77754289445465],\"11\":[-279.0340418060077,127.27376899987718],\"12\":[-56.49756828421992,25.452036192329473],\"13\":[6.946220625723527,-31.10481605659189],\"14\":[54.82114390636223,-32.579534443325066],\"15\":[-312.8456429228426,-0.48769825556553786],\"16\":[32.27911705289395,-108.23054927304726],\"17\":[81.6574700653745,-32.96973490092418],\"18\":[-261.81459007243876,139.71439408655877],\"19\":[-29.880186647960503,68.79427403637042],\"2\":[-266.3342513271957,126.37354748285645],\"20\":[303.515598696637,172.0908090627593],\"21\":[-23.25892335143727,3.355813400389565],\"22\":[25.985027634664394,-63.97692357876045],\"23\":[53.0593385673255,-62.404924031003524],\"24\":[-57.68755719689085,-4.1719278913262],\"25\":[-0.7423733409832874,57.15111260781181],\"26\":[102.9172021383139,-77.75450951578995],\"27\":[81.2762658112454,-47.67221639320247],\"28\":[132.83459744728637,-90.94864585273737],\"29\":[68.64900974840148,-42.85260904487853],\"3\":[-22.286204920732175,-15.893932332372234],\"30\":[90.70577084550146,-64.63727923889147],\"31\":[54.83301420959346,-85.88234808320254],\"32\":[35.89747915454103,-60.18489099548072],\"33\":[18.97910897391239,-78.72546497988675],\"34\":[24.300423829928715,-138.31755081958136],\"35\":[83.12103865364213,-88.90036074491448],\"36\":[46.654347703132004,-76.3186307050533],\"37\":[72.92255122890413,-132.12310001662462],\"38\":[46.20261375290823,-108.18615543517068],\"39\":[69.59281761915204,-22.79469114324],\"4\":[28.119930988062897,-9.301706363586224],\"40\":[54.86493663998685,-45.22683346450635],\"41\":[110.08059091333182,-64.03495072668298],\"42\":[36.38600931689903,-42.07495686794399],\"43\":[-269.16332375430784,131.00734744620354],\"44\":[-288.0662103796319,124.18376030671041],\"45\":[-35.86821400504032,4.358736921811881],\"46\":[-77.64460979933524,33.298117054232016],\"47\":[-11.341529184006871,14.01149139466238],\"48\":[-52.75131830970994,10.125533073111447],\"49\":[-27.379367102201602,25.243090157913215],\"5\":[8.81956516896188,15.311254205601994],\"50\":[8.650451565354086,23.401213492016346],\"51\":[12.086869436585594,31.557274837172773],\"52\":[10.112348168314254,92.84630371836458],\"53\":[-41.76095958644098,45.44349623079249],\"54\":[-13.788158437080762,37.19475043550463],\"55\":[-39.015905256311996,101.96862194881874],\"56\":[-12.161074716958174,61.83117772959097],\"57\":[-18.580294761336713,-8.809462686792482],\"58\":[-37.38867077745631,-23.069068515975705],\"59\":[-88.67568035921364,-15.83112350397367],\"6\":[64.79616894839232,-107.12658247537667],\"60\":[-1.6641611892297095,-2.9036642890608477],\"61\":[-254.09712653916537,148.24265424743896],\"62\":[-248.6100641272736,168.35118289317538],\"7\":[-280.21735777124405,40.23719659705621],\"8\":[-249.35206171180178,145.69130507180833],\"9\":[-250.95397523463345,158.959461491847]}},\"id\":\"2049\",\"type\":\"StaticLayoutProvider\"},{\"attributes\":{\"source\":{\"id\":\"2058\",\"type\":\"ColumnDataSource\"}},\"id\":\"2060\",\"type\":\"CDSView\"},{\"attributes\":{\"source\":{\"id\":\"2054\",\"type\":\"ColumnDataSource\"}},\"id\":\"2056\",\"type\":\"CDSView\"},{\"attributes\":{},\"id\":\"2267\",\"type\":\"NodesOnly\"},{\"attributes\":{\"attachment\":\"right\",\"callback\":null,\"renderers\":[{\"id\":\"2052\",\"type\":\"GraphRenderer\"}],\"tooltips\":[[\"name\",\"@species\"],[\"type\",\"@type\"]]},\"id\":\"2143\",\"type\":\"HoverTool\"},{\"attributes\":{\"attachment\":\"right\",\"callback\":null,\"renderers\":[{\"id\":\"2036\",\"type\":\"GraphRenderer\"}],\"tooltips\":[[\"reaction\",\"@species\"],[\"type\",\"@type\"],[\"k_f\",\"@k\"],[\"k_r\",\"@k_r\"]]},\"id\":\"2144\",\"type\":\"HoverTool\"},{\"attributes\":{\"callback\":null,\"data\":{\"end\":[47,50,54,43,57,58,60,29,30,31,32,35,38,39,42,47,48,49,50,53,56,57,60,50,51,60,35,36,37,38,61,61,62,30,31,40,41,43,44,45,46,48,53,27,33,36,40,45,51,54,58,39,40,42,31,33,34,38,27,29,39,43,61,53,54,55,56,45,47,57,32,33,42,29,32,36,48,49,58,59,49,51,52,56,27,28,30,35,17,13,26,17,2,13,4,17,23,4,10,26,4,10,16,4,22,23,22,13,16,22,2,13,4,26,6,23,13,6,23,2,13,4,16,6,4,14,17,14,13,10,14,2,13,4,14,22,2,18,11,2,7,18,21,13,12,21,8,13,4,21,1,4,24,12,4,24,25,4,5,1,5,13,25,5,8,13,4,12,19,1,13,19,1,8,13,4,25,19,4,3,21,3,13,24,3,8,13,4,3,5,8,18,9,8,15,18],\"start\":[1,1,1,2,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,5,5,5,6,6,6,6,8,9,9,10,10,10,10,11,11,12,12,12,12,13,13,13,13,13,13,13,13,14,14,14,16,16,16,16,17,17,17,18,18,19,19,19,19,21,21,21,22,22,22,23,23,23,24,24,24,24,25,25,25,25,26,26,26,26,27,27,27,28,28,28,29,29,29,30,30,30,31,31,31,32,32,32,33,33,33,34,34,34,35,35,35,36,36,36,37,37,37,38,38,38,39,39,39,40,40,40,41,41,41,42,42,42,43,43,43,44,44,44,45,45,45,46,46,46,47,47,47,48,48,48,49,49,49,50,50,50,51,51,51,52,52,52,53,53,53,54,54,54,55,55,55,56,56,56,57,57,57,58,58,58,59,59,59,60,60,60,61,61,61,62,62,62],\"weight\":[1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1],\"xs\":[[-5.376934391232813,-10.06065328917502,-12.083428223403189,-11.341529184006871,-7.430284247411958,-10.06065328917502],[-5.376934391232813,5.414236615985794,3.6945246765835016,8.650451565354086,5.598823144810637,5.414236615985794],[-5.376934391232813,-11.254415218137103,-8.928771743840535,-13.788158437080762,-12.378156575258803,-11.254415218137103],[-266.3342513271957,-267.3395134848672,-264.77318731773227,-269.16332375430784,-269.0407001194019,-267.3395134848672],[-22.286204920732175,-20.202600577423993,-18.37215624637174,-18.580294761336713,-22.8025991318412,-20.202600577423993],[-22.286204920732175,-34.2273183639977,-34.55033223387088,-37.38867077745631,-32.404690748554884,-34.2273183639977],[-22.286204920732175,-4.625586386039503,-3.9954994740955385,-1.6641611892297095,-6.660449909634201,-4.625586386039503],[28.119930988062897,65.95294319543397,63.71930253875115,68.64900974840148,66.90768231472781,65.95294319543397],[28.119930988062897,88.08368367264329,85.80582852022923,90.70577084550146,89.11773002039514,88.08368367264329],[28.119930988062897,53.680253755504104,51.04633207115652,54.83301420959346,55.76735395454621,53.680253755504104],[28.119930988062897,35.368642536147476,32.7719158504714,35.89747915454103,37.7145111843813,35.368642536147476],[28.119930988062897,81.13138818336604,78.60272729839028,83.12103865364213,82.71624186057757,81.13138818336604],[28.119930988062897,45.57302027591385,42.964474188413305,46.20261375290823,47.882913474162834,45.57302027591385],[28.119930988062897,66.26453580036471,64.701680379316,69.59281761915204,66.24859312749177,66.26453580036471],[28.119930988062897,35.53004471998998,32.90294319132998,36.38600931689903,37.75111234057282,35.53004471998998],[28.119930988062897,-8.328121201117533,-6.341780015882225,-11.341529184006871,-8.885027308848688,-8.328121201117533],[28.119930988062897,-49.348136053561625,-47.957024268234925,-52.75131830970994,-49.12492010109101,-49.348136053561625],[28.119930988062897,-24.407954809014427,-22.382115001998606,-27.379367102201602,-25.02428054235469,-24.407954809014427],[28.119930988062897,10.44087971928452,13.01366438210832,8.650451565354086,8.717399505613084,10.44087971928452],[28.119930988062897,-39.0057603873446,-36.81053939126276,-41.76095958644098,-39.894029784750614,-39.0057603873446],[28.119930988062897,-10.436426195740152,-7.851957731551371,-12.161074716958174,-12.2027933252962,-10.436426195740152],[28.119930988062897,-15.080489173840924,-14.224058482050731,-18.580294761336713,-14.276758048971054,-15.080489173840924],[28.119930988062897,1.7577764036041994,3.0944460351818197,-1.6641611892297095,2.0443312593848644,1.7577764036041994],[8.81956516896188,8.723600058379306,11.240403306014493,8.650451565354086,6.241495405289079,8.723600058379306],[8.81956516896188,11.396787490964503,13.684039602254177,12.086869436585594,8.782189283485991,11.396787490964503],[8.81956516896188,0.08175770693827622,-1.6708906500778453,-1.6641611892297095,2.662597177414887,0.08175770693827622],[64.79616894839232,80.63949450480258,81.81391347173647,83.12103865364213,78.2879344826687,80.63949450480258],[64.79616894839232,48.43033592313648,51.00580280934566,46.654347703132004,46.69732378362058,48.43033592313648],[64.79616894839232,71.84044718921076,69.20627980351848,72.92255122890413,73.96130954596916,71.84044718921076],[64.79616894839232,49.69694459270454,50.3834926804681,46.20261375290823,50.6679613296084,49.69694459270454],[-249.35206171180178,-251.0144787311365,-249.09941549744414,-254.09712653916537,-251.4672624018197,-251.0144787311365],[-250.95397523463345,-253.112097601827,-255.2774186640593,-254.09712653916537,-250.47951989084913,-253.112097601827],[-250.95397523463345,-249.45757096242085,-247.23298161106882,-248.6100641272736,-252.08418221238827,-249.45757096242085],[80.18597477774912,87.2760335485077,86.9609882968055,90.70577084550146,85.96415445847295,87.2760335485077],[80.18597477774912,57.62823960382686,56.786672275429474,54.83301420959346,59.795745288641726,57.62823960382686],[80.18597477774912,57.530278277986945,59.782777107306124,54.86493663998685,56.5421063677319,57.530278277986945],[80.18597477774912,106.5952276280216,105.99696801321458,110.08059091333182,105.54017625203124,106.5952276280216],[-279.0340418060077,-272.43696700533786,-272.32894355986645,-269.16332375430784,-274.09787028680483,-272.43696700533786],[-279.0340418060077,-284.75464275264613,-284.7784403573351,-288.0662103796319,-283.15997556958627,-284.75464275264613],[-56.49756828421992,-38.31541649890308,-40.68315546502055,-35.86821400504032,-37.108528339030904,-38.31541649890308],[-56.49756828421992,-74.36318929680394,-72.71526977092147,-77.64460979933524,-74.45453978291701,-74.36318929680394],[-56.49756828421992,-53.58235628195739,-56.20796703016474,-52.75131830970994,-51.350955290614564,-53.58235628195739],[-56.49756828421992,-43.83770959805301,-42.3179231152859,-41.76095958644098,-46.342619678640766,-43.83770959805301],[6.946220625723527,77.86009465024269,76.50597200322179,81.2762658112454,77.59372816468581,77.86009465024269],[6.946220625723527,18.121670877327563,15.494485570104402,18.97910897391239,20.342123309677422,18.121670877327563],[6.946220625723527,44.34477455143771,41.91856015255088,46.654347703132004,45.67542376438241,44.34477455143771],[6.946220625723527,51.50769417778904,50.00470812562144,54.86493663998685,51.41814441456049,51.50769417778904],[6.946220625723527,-33.172790176164966,-30.93874754930117,-35.86821400504032,-34.128236147145245,-33.172790176164966],[6.946220625723527,11.80069913874188,14.224455024827549,12.086869436585594,9.241195997654454,11.80069913874188],[6.946220625723527,-12.77144668994607,-10.138108089112983,-13.788158437080762,-14.922499638349388,-12.77144668994607],[6.946220625723527,-33.94478288496362,-32.68210131225907,-37.38867077745631,-33.573827663555484,-33.94478288496362],[54.82114390636223,66.6749161855958,67.36344725348287,69.59281761915204,64.60225436425338,66.6749161855958],[54.82114390636223,54.852817558388544,52.349958151935176,54.86493663998685,57.34992817793946,54.852817558388544],[54.82114390636223,39.497520929028994,39.090754716604955,36.38600931689903,41.38025848940688,39.497520929028994],[32.27911705289395,52.34682919565854,53.51680832223529,54.83301420959346,49.997507581020756,52.34682919565854],[32.27911705289395,20.417428337733504,23.037714224164468,18.97910897391239,18.479421174586474,20.417428337733504],[32.27911705289395,25.197569985381417,22.993879348349232,24.300423829928715,27.826829344449862,25.197569985381417],[32.27911705289395,42.7026315432171,41.88047973217657,46.20261375290823,41.86453775539387,42.7026315432171],[81.6574700653745,81.36698292248033,78.88933902525831,81.2762658112454,83.8876592340536,81.36698292248033],[81.6574700653745,71.43594436592855,70.58458390460912,68.64900974840148,73.60931038495013,71.43594436592855],[81.6574700653745,72.26833033920985,74.51466646828406,69.59281761915204,71.29114586635849,72.26833033920985],[-261.81459007243876,-266.9058873463199,-268.280965264089,-269.16332375430784,-264.4599757395397,-266.9058873463199],[-261.81459007243876,-256.44556053871344,-255.1488740803445,-254.09712653916537,-258.85624614861405,-256.44556053871344],[-29.880186647960503,-40.17380058566753,-42.025533329019694,-41.76095958644098,-37.569185802391026,-40.17380058566753],[-29.880186647960503,-15.37644083477267,-17.980913611443967,-13.788158437080762,-13.525382990674272,-15.37644083477267],[-29.880186647960503,-38.08664974972788,-35.455973653798154,-39.015905256311996,-40.27652578651607,-38.08664974972788],[-29.880186647960503,-15.418578754382075,-17.105551120940248,-12.161074716958174,-15.276830453946024,-15.418578754382075],[-23.25892335143727,-32.379232891111414,-31.35349919790302,-35.86821400504032,-31.749939446501738,-32.379232891111414],[-23.25892335143727,-13.950662782171648,-12.903137806971614,-11.341529184006871,-16.2358519264084,-13.950662782171648],[-23.25892335143727,-19.836645804964135,-22.46801089623067,-18.580294761336713,-17.801241254592586,-19.836645804964135],[25.985027634664394,32.62851533843143,32.7464353609221,35.89747915454103,30.959935208722708,32.62851533843143],[25.985027634664394,20.48087104845803,18.578885388710457,18.97910897391239,23.09523000767588,20.48087104845803],[25.985027634664394,34.884599325477005,36.78678793777527,36.38600931689903,32.270204427259216,34.884599325477005],[53.0593385673255,66.4670332650737,67.90422810507539,68.64900974840148,63.994799777378745,66.4670332650737],[53.0593385673255,39.36855776777624,40.51254927480396,35.89747915454103,39.871101198833955,39.36855776777624],[53.0593385673255,48.117900993992926,46.19408963764008,46.654347703132004,50.73596099627499,48.117900993992926],[-57.68755719689085,-53.89354298172567,-51.801332268404074,-52.75131830970994,-56.52757744471573,-53.89354298172567],[-57.68755719689085,-29.890972193966014,-28.74553758994897,-27.379367102201602,-32.227807510860885,-29.890972193966014],[-57.68755719689085,-39.95041439872289,-42.26146487883043,-37.38867077745631,-38.854548258938195,-39.95041439872289],[-57.68755719689085,-85.39987343791863,-85.50328697943053,-88.67568035921364,-83.74255370546996,-85.39987343791863],[-0.7423733409832874,-25.136388122794575,-26.52356321529832,-27.379367102201602,-22.685237342473513,-25.136388122794575],[-0.7423733409832874,10.518461306878459,7.911529816501734,12.086869436585594,12.38140538858826,10.518461306878459],[-0.7423733409832874,9.094058036066576,11.24439407275428,10.112348168314254,6.460687626875643,9.094058036066576],[-0.7423733409832874,-8.922533550699233,-7.206313831126918,-12.161074716958174,-9.102524399412498,-8.922533550699233],[102.9172021383139,83.32019297800983,85.83439145200151,81.2762658112454,81.7755483130697,83.32019297800983],[102.9172021383139,129.63219880353284,127.86385784875573,132.83459744728637,129.88145539285875,129.63219880353284],[102.9172021383139,93.09061408588403,95.48606497848138,90.70577084550146,91.8264333702784,93.09061408588403],[102.9172021383139,86.17086095688951,85.66768370097189,83.12103865364213,88.12074672528553,86.17086095688951],[81.2762658112454,81.56675295413956,84.04439685136158,81.6574700653745,79.04607664256629,81.56675295413956],[81.2762658112454,10.36239178672623,11.71651443374714,6.946220625723527,10.628758272283115,10.36239178672623],[81.2762658112454,100.87327497154946,98.35907649755778,102.9172021383139,102.41791963648959,100.87327497154946],[132.83459744728637,83.97363597642065,86.3972678769302,81.6574700653745,82.64869659194878,83.97363597642065],[132.83459744728637,-263.2603025474188,-261.33581834873377,-266.3342513271957,-263.72663363931775,-263.2603025474188],[132.83459744728637,10.107235819618811,11.930290300401271,6.946220625723527,9.783635121508382,10.107235819618811],[68.64900974840148,30.815997541030406,33.049638197713236,28.119930988062897,29.861258421736576,30.815997541030406],[68.64900974840148,78.87053544784743,79.72189590916686,81.6574700653745,76.69716942882584,78.87053544784743],[68.64900974840148,55.24131505065328,53.8041202106516,53.0593385673255,57.713548538348235,55.24131505065328],[90.70577084550146,30.74201816092107,33.01987331333514,28.119930988062897,29.707971813169216,30.74201816092107],[90.70577084550146,83.61571207474287,83.93075732644509,80.18597477774912,84.92759116477764,83.61571207474287],[90.70577084550146,100.53235889793133,98.13690800533398,102.9172021383139,101.79653961353696,100.53235889793133],[54.83301420959346,29.27269144215225,31.906613126499835,28.119930988062897,27.185591243110146,29.27269144215225],[54.83301420959346,77.39074938351573,78.23231671191311,80.18597477774912,75.22324369870086,77.39074938351573],[54.83301420959346,34.765302066828866,33.59532294025212,32.27911705289395,37.114623681466654,34.765302066828866],[35.89747915454103,28.648767606456452,31.245494292132527,28.119930988062897,26.302898958222627,28.648767606456452],[35.89747915454103,29.253991450774,29.13607142828333,25.985027634664394,30.922571580482717,29.253991450774],[35.89747915454103,49.58825995409029,48.44426844706257,53.0593385673255,49.08571652303257,49.58825995409029],[18.97910897391239,24.483265560118753,26.385251219866323,25.985027634664394,21.868906600900907,24.483265560118753],[18.97910897391239,7.803658722308352,10.430844029531514,6.946220625723527,5.583206289958493,7.803658722308352],[18.97910897391239,30.840797689072836,28.220511802641873,32.27911705289395,32.778804852219864,30.840797689072836],[24.300423829928715,25.905735862698723,28.386287875921173,25.985027634664394,23.387571139598034,25.905735862698723],[24.300423829928715,-263.74657935459396,-261.4494926717338,-266.3342513271957,-264.8161823685602,-263.74657935459396],[24.300423829928715,7.505475976513998,10.105998374756142,6.946220625723527,5.1702409937964156,7.505475976513998],[83.12103865364213,30.109581458338983,32.63824234331475,28.119930988062897,28.524727781127467,30.109581458338983],[83.12103865364213,99.86737983506652,100.37055709098414,102.9172021383139,97.9174940666705,99.86737983506652],[83.12103865364213,67.27771309723187,66.10329413029798,64.79616894839232,69.62927311936575,67.27771309723187],[46.654347703132004,51.595785276464575,53.51959663281742,53.0593385673255,48.97772527418251,51.595785276464575],[46.654347703132004,9.255793777417821,11.682008176304649,6.946220625723527,7.92514456447312,9.255793777417821],[46.654347703132004,63.02018072838784,60.444713842178665,64.79616894839232,64.75319286790373,63.02018072838784],[72.92255122890413,54.018350694259524,56.65013013520661,53.0593385673255,51.84148661219357,54.018350694259524],[72.92255122890413,-263.5503007303029,-261.3748410156711,-266.3342513271957,-264.40517038217746,-263.5503007303029],[72.92255122890413,8.860087652270494,11.407143876029664,6.946220625723527,7.220890131003272,8.860087652270494],[46.20261375290823,28.74952446505728,31.358070552557816,28.119930988062897,26.439631266808288,28.74952446505728],[46.20261375290823,35.77909926258508,36.60125107362561,32.27911705289395,36.61719305040832,35.77909926258508],[46.20261375290823,61.30183810859601,60.61529002083245,64.79616894839232,60.330821371692146,61.30183810859601],[69.59281761915204,31.448212806850236,33.01106822789893,28.119930988062897,31.464155479723175,31.448212806850236],[69.59281761915204,57.73904533991847,57.05051427203139,54.82114390636223,59.811707161260884,57.73904533991847],[69.59281761915204,78.98195734531669,76.73562121624248,81.6574700653745,79.95914181816805,78.98195734531669],[54.86493663998685,54.83326298796054,57.336122394413906,54.82114390636223,52.33615236840962,54.83326298796054],[54.86493663998685,10.303463087921337,11.806449140088937,6.946220625723527,10.39301285114989,10.303463087921337],[54.86493663998685,77.52063313974902,75.26813431042986,80.18597477774912,78.50880505000409,77.52063313974902],[110.08059091333182,57.862869549025845,59.821050560976985,54.82114390636223,57.347556331431015,57.862869549025845],[110.08059091333182,-263.2110952846839,-261.3418902203244,-266.3342513271957,-263.59880536892956,-263.2110952846839],[110.08059091333182,10.28038822086664,11.8315961518087,6.946220625723527,10.310770350692088,10.28038822086664],[36.38600931689903,28.97589558497194,31.602997113631947,28.119930988062897,26.754827964389104,28.97589558497194],[36.38600931689903,51.709632294232264,52.1163985066563,54.82114390636223,49.82689473385438,51.709632294232264],[36.38600931689903,27.486437626086417,25.584249013788146,25.985027634664394,30.100832524304206,27.486437626086417],[-269.16332375430784,-268.15806159663634,-270.7243877637713,-266.3342513271957,-266.45687496210167,-268.15806159663634],[-269.16332375430784,-264.0720264804267,-262.6969485626576,-261.81459007243876,-266.5179380872069,-264.0720264804267],[-269.16332375430784,-275.76039855497766,-275.8684220004491,-279.0340418060077,-274.0994952735107,-275.76039855497766],[-288.0662103796319,-269.8166172690974,-270.3919224231734,-266.3342513271957,-270.89320129110536,-269.8166172690974],[-288.0662103796319,-280.5431804137354,-283.1096024855665,-280.21735777124405,-278.1313150155665,-280.5431804137354],[-288.0662103796319,-264.8269121744792,-264.26843655056075,-261.81459007243876,-266.81430777931223,-264.8269121744792],[-35.86821400504032,-26.747904465366176,-27.773638158574578,-23.25892335143727,-27.377197909975855,-26.747904465366176],[-35.86821400504032,4.250796796848169,2.0167541699843765,6.946220625723527,5.206242767828449,4.250796796848169],[-35.86821400504032,-54.05036579035716,-51.6826268242397,-56.49756828421992,-55.25725395022934,-54.05036579035716],[-77.64460979933524,-26.324960395632335,-28.25789014800797,-23.25892335143727,-25.846430752629647,-26.324960395632335],[-77.64460979933524,-246.4236287212924,-244.3598931867929,-249.35206171180178,-247.0982377709205,-246.4236287212924],[-77.64460979933524,4.161460354141518,1.9865679273700012,6.946220625723527,5.015378642249416,4.161460354141518],[-11.341529184006871,25.106523005173557,23.120181819938253,28.119930988062897,25.663429112904712,25.106523005173557],[-11.341529184006871,-20.649789753272497,-21.69731472847253,-23.25892335143727,-18.36460060903574,-20.649789753272497],[-11.341529184006871,-6.657810286064665,-4.635035351836497,-5.376934391232813,-9.288179327827725,-6.657810286064665],[-52.75131830970994,24.716748731914585,23.325636946587885,28.119930988062897,24.49353277944397,24.716748731914585],[-52.75131830970994,-56.545332524875114,-58.63754323819671,-57.68755719689085,-53.91129806188505,-56.545332524875114],[-52.75131830970994,-55.66653031197247,-53.04091956376512,-56.49756828421992,-57.897931303315296,-55.66653031197247],[-27.379367102201602,25.148518694875722,23.122678887859898,28.119930988062897,25.764844428215984,25.148518694875722],[-27.379367102201602,-55.175952105126434,-56.32138670914348,-57.68755719689085,-52.839116788231564,-55.175952105126434],[-27.379367102201602,-2.985352320390316,-1.5981772278865685,-0.7423733409832874,-5.436503100711378,-2.985352320390316],[8.650451565354086,26.329502834132462,23.756718171308663,28.119930988062897,28.0529830478039,26.329502834132462],[8.650451565354086,8.746416675936658,6.229613428301471,8.81956516896188,11.228521329026886,8.746416675936658],[8.650451565354086,-2.140719441864521,-0.4210075024622286,-5.376934391232813,-2.3253059706893637,-2.140719441864521],[12.086869436585594,9.509647114582972,7.222395003293299,8.81956516896188,12.124245322061483,9.509647114582972],[12.086869436585594,7.232390923567241,4.808635037481574,6.946220625723527,9.791894064654667,7.232390923567241],[12.086869436585594,0.8260347887238487,3.4329662791005733,-0.7423733409832874,-1.036909292985951,0.8260347887238487],[10.112348168314254,8.877914414927176,6.392101075213527,8.81956516896188,11.391406203560553,8.877914414927176],[10.112348168314254,-245.92247088787204,-244.61011256953606,-249.35206171180178,-245.60797434518418,-245.92247088787204],[10.112348168314254,7.03559321929324,4.557605714805749,6.946220625723527,9.555975355022657,7.03559321929324],[-41.76095958644098,25.364731788966516,23.16951079288467,28.119930988062897,26.253001186372533,25.364731788966516],[-41.76095958644098,-54.420818272607896,-55.940604755375006,-56.49756828421992,-51.91590819202014,-54.420818272607896],[-41.76095958644098,-31.467345648733954,-29.61561290538179,-29.880186647960503,-34.07196043201046,-31.467345648733954],[-13.788158437080762,-7.910677610176471,-10.23632108447304,-5.376934391232813,-6.7869362530547725,-7.910677610176471],[-13.788158437080762,5.929508878588834,3.2961702777557464,6.946220625723527,8.080561826992152,5.929508878588834],[-13.788158437080762,-28.291904250268594,-25.687431473597297,-29.880186647960503,-30.142962094366993,-28.291904250268594],[-39.015905256311996,-6.845214901186791,-9.46283869067783,-5.376934391232813,-4.924082153221271,-6.845214901186791],[-39.015905256311996,-245.92531390866228,-244.603760928159,-249.35206171180178,-245.62136063864077,-245.92531390866228],[-39.015905256311996,5.803592926484505,3.1695622836737365,6.946220625723527,7.895608640319725,5.803592926484505],[-12.161074716958174,26.395282466844876,23.810814002656095,28.119930988062897,28.161649596400924,26.395282466844876],[-12.161074716958174,-3.9809145072422285,-5.697134226814543,-0.7423733409832874,-3.8009236585289647,-3.9809145072422285],[-12.161074716958174,-26.6226826105366,-24.93571024397843,-29.880186647960503,-26.764430910972653,-26.6226826105366],[-18.580294761336713,24.620125400567108,23.763694708776917,28.119930988062897,23.816394275697235,24.620125400567108],[-18.580294761336713,-20.663899104644894,-22.494343435697147,-22.286204920732175,-18.063900550227693,-20.663899104644894],[-18.580294761336713,-22.00257230780985,-19.371207216543315,-23.25892335143727,-24.0379768581814,-22.00257230780985],[-37.38867077745631,-25.447557334190783,-25.124543464317604,-22.286204920732175,-27.270184949633602,-25.447557334190783],[-37.38867077745631,3.502332733230834,2.2396511605262885,6.946220625723527,3.131377511822696,3.502332733230834],[-37.38867077745631,-55.12581357562427,-52.81476309551673,-57.68755719689085,-56.22167971540897,-55.12581357562427],[-88.67568035921364,-25.786203354411548,-26.61869516588696,-22.286204920732175,-26.613964837783335,-25.786203354411548],[-88.67568035921364,-246.8836951460153,-244.5258473248577,-249.35206171180178,-248.07065280782228,-246.8836951460153],[-88.67568035921364,3.4900329888533665,2.2759708637258527,6.946220625723527,3.064623834077585,3.4900329888533665],[-1.6641611892297095,24.697993395228988,23.36132376365137,28.119930988062897,24.411438539448323,24.697993395228988],[-1.6641611892297095,-19.324779723922383,-19.954866635866345,-22.286204920732175,-17.28991620032768,-19.324779723922383],[-1.6641611892297095,7.073646272793894,8.826294629810015,8.81956516896188,4.492806802317284,7.073646272793894],[-254.09712653916537,-252.43470951983065,-254.349772753523,-249.35206171180178,-251.98192584914744,-252.43470951983065],[-254.09712653916537,-259.46615607289067,-260.7628425312596,-261.81459007243876,-257.0554704629901,-259.46615607289067],[-254.09712653916537,-251.93900417197182,-249.77368310973952,-250.95397523463345,-254.5715818829497,-251.93900417197182],[-248.6100641272736,-249.23751562321553,-251.70900846299057,-249.35206171180178,-246.71168689598485,-249.23751562321553],[-248.6100641272736,-311.6010805492064,-313.64250213118044,-312.8456429228426,-308.96929047975283,-311.6010805492064],[-248.6100641272736,-260.3490260248001,-262.27169876006485,-261.81459007243876,-257.7311508244462,-260.3490260248001]],\"ys\":[[29.179145738729886,17.26869217785624,18.95614363878864,14.01149139466238,17.126320931885992,17.26869217785624],[29.179145738729886,24.734222419775342,22.738802235197202,23.401213492016346,27.361966448580475,24.734222419775342],[29.179145738729886,34.780181053511846,36.01731212902747,37.19475043550463,32.39767895910795,34.780181053511846],[126.37354748285645,128.02008848503482,128.61429457001137,131.00734744620354,126.00885132795332,128.02008848503482],[-15.893932332372234,-11.9107727066211,-13.805128644258833,-8.809462686792482,-11.48754890699129,-11.9107727066211],[-15.893932332372234,-21.567119476254504,-18.952779615522125,-23.069068515975705,-23.46899734903442,-21.567119476254504],[-15.893932332372234,-4.769129593937912,-7.326882778070729,-2.9036642890608477,-3.09627535405674,-4.769129593937912],[-9.301706363586224,-40.620743201694864,-42.01715298551842,-42.85260904487853,-38.16562933842199,-40.620743201694864],[-9.301706363586224,-62.318948188775316,-63.64200781410039,-64.63727923889147,-59.89616899573157,-62.318948188775316],[-9.301706363586224,-82.57763276482976,-82.61722352471436,-85.88234808320254,-80.97042287601528,-82.57763276482976],[-9.301706363586224,-56.72507426174379,-56.282218317398,-60.18489099548072,-55.52673743397864,-56.72507426174379],[-9.301706363586224,-86.02090055138338,-86.75913154256313,-88.90036074491448,-83.91677372788301,-86.02090055138338],[-9.301706363586224,-104.743247935146,-104.37637169316476,-108.18615543517068,-103.47695244031564,-104.743247935146],[-9.301706363586224,-21.711852219516967,-23.83236956215846,-22.79469114324,-19.077681249605124,-21.711852219516967],[-9.301706363586224,-38.681238463473996,-38.487722506362154,-42.07495686794399,-37.26491593934924,-38.681238463473996],[-9.301706363586224,12.231218289585858,13.961408904339805,14.01149139466238,9.656540357355034,12.231218289585858],[-9.301706363586224,9.308005990112186,11.544950081561456,10.125533073111447,6.683261144206725,9.308005990112186],[-9.301706363586224,23.393574279663955,25.07734503123756,25.243090157913215,20.832470326684454,23.393574279663955],[-9.301706363586224,20.393828078469678,20.959416220392107,23.401213492016346,18.4016617147772,20.393828078469678],[-9.301706363586224,43.285052955350984,44.74111464563271,45.44349623079249,40.805115789780736,43.285052955350984],[-9.301706363586224,58.785592813969586,59.29513537858841,61.83117772959097,56.83135177684838,58.785592813969586],[-9.301706363586224,-8.846352383636708,-6.355240716588355,-8.809462686792482,-11.354962984439481,-8.846352383636708],[-9.301706363586224,-3.6387446321187165,-1.3688492240519055,-2.9036642890608477,-6.2573314995289175,-3.6387446321187165],[15.311254205601994,19.901977961508557,19.12428118239884,23.401213492016346,19.019783335219955,19.901977961508557],[15.311254205601994,28.125979614035042,26.819232260127038,31.557274837172773,27.80506361101431,28.125979614035042],[15.311254205601994,0.12977719018406475,2.096331182372771,-2.9036642890608477,-0.39783866929578027,0.12977719018406475],[-107.12658247537667,-91.36854603726192,-93.72647965754273,-88.90036074491448,-90.18141658777195,-91.36854603726192],[-107.12658247537667,-79.33456602306084,-78.78131997871473,-76.3186307050533,-81.31844600729255,-79.33456602306084],[-107.12658247537667,-128.79457919690915,-128.7780549208356,-132.12310001662462,-127.23219200698794,-128.79457919690915],[-107.12658247537667,-107.98702738077246,-105.44384775858043,-108.18615543517068,-110.43574895828944,-107.98702738077246],[145.69130507180833,146.58516141437607,148.39392996742657,148.24265424743896,143.9901473845282,146.58516141437607],[158.959461491847,151.60118338868608,153.101348567924,148.24265424743896,151.69416437172632,151.60118338868608],[158.959461491847,164.95534247225174,163.54455790847322,168.35118289317538,164.75528195868355,164.95534247225174],[-66.77754289445465,-65.33506292572424,-67.95037502123495,-64.63727923889147,-63.05075031124387,-65.33506292572424],[-66.77754289445465,-83.77599697395397,-81.27982484460897,-85.88234808320254,-85.27300397922812,-83.77599697395397],[-66.77754289445465,-47.49530298220831,-46.129521194564184,-45.22683346450635,-49.937152105992894,-47.49530298220831],[-66.77754289445465,-64.35470495951131,-66.92008919990019,-64.03495072668298,-61.940998792314176,-64.35470495951131],[127.27376899987718,129.7690987373467,127.13709535536307,131.00734744620354,131.81372857112024,129.7690987373467],[127.27376899987718,125.3166856581346,127.9507973758785,124.18376030671041,123.2199864801845,125.3166856581346],[25.452036192329473,6.860975910004633,5.70645304064533,4.358736921811881,9.202456603306414,6.860975910004633],[25.452036192329473,32.080628045835134,34.135736827325765,33.298117054232016,29.447993252281048,32.080628045835134],[25.452036192329473,13.525441290796572,13.738230074435826,10.125533073111447,14.92542717764647,13.525441290796572],[25.452036192329473,42.62620863644408,40.47461389896608,45.44349623079249,43.44139962984041,42.62620863644408],[-31.10481605659189,-46.91078708017765,-49.170314182110644,-47.67221639320247,-44.290069666392505,-46.91078708017765],[-31.10481605659189,-75.33211856218564,-75.13974333234722,-78.72546497988675,-73.91483176579747,-75.33211856218564],[-31.10481605659189,-73.68882617677123,-74.71478648700689,-76.3186307050533,-71.41539627030076,-73.68882617677123],[-31.10481605659189,-44.237428062249016,-46.40079206179563,-45.22683346450635,-41.60473140151304,-44.237428062249016],[-31.10481605659189,2.12609490332103,3.521861505909075,4.358736921811881,-0.3287439639128653,2.12609490332103],[-31.10481605659189,28.068993518151608,27.037238570400092,31.557274837172773,27.4460532816054,28.068993518151608],[-31.10481605659189,33.845676351039145,33.7775684887391,37.19475043550463,32.32512313568954,33.845676351039145],[-31.10481605659189,-23.69327696188319,-21.381406266213332,-23.069068515975705,-26.301246112631468,-23.69327696188319],[-32.579534443325066,-24.727526165700645,-27.270169639744722,-22.79469114324,-23.101739020378663,-24.727526165700645],[-32.579534443325066,-41.72685444630335,-40.905388890681834,-45.22683346450635,-40.88807591696997,-41.72685444630335],[-32.579534443325066,-40.472304226982644,-37.86968014425866,-42.07495686794399,-42.31469673301576,-40.472304226982644],[-108.23054927304726,-88.34585860205272,-90.70599836717668,-85.88234808320254,-87.1543054901268,-88.34585860205272],[-108.23054927304726,-81.91627011459136,-81.6456915845574,-78.72546497988675,-83.70043353287328,-81.91627011459136],[-108.23054927304726,-134.9344858223109,-133.4912746652721,-138.31755081958136,-134.77291203020454,-134.9344858223109],[-108.23054927304726,-108.19731481891857,-110.69994888468756,-108.18615543517068,-105.69997429941452,-108.19731481891857],[-32.96973490092418,-44.17339224704576,-43.27874617954023,-47.67221639320247,-43.40834205273299,-44.17339224704576],[-32.96973490092418,-40.73530050863982,-38.24245148945582,-42.85260904487853,-42.22378665735162,-40.73530050863982],[-32.96973490092418,-25.051155564587894,-23.675261359803038,-22.79469114324,-27.497422388457046,-25.051155564587894],[139.71439408655877,133.68204011338804,135.92887601919168,131.00734744620354,132.7039668649232,133.68204011338804],[139.71439408655877,145.6474937996503,143.35452299821665,148.24265424743896,146.70942871185676,145.6474937996503],[68.79427403637042,48.56293949943256,50.43649139749733,45.44349623079249,48.1691213963924,48.56293949943256],[68.79427403637042,40.31362187004342,39.91886571350785,37.19475043550463,42.18784056735343,40.31362187004342],[68.79427403637042,98.59423545591619,98.45765527489213,101.96862194881874,97.1301474083434,98.59423545591619],[68.79427403637042,63.111282196486925,61.08810768547366,61.83117772959097,65.74168488179352,63.111282196486925],[3.355813400389565,4.081228747792777,6.507538962534847,4.358736921811881,1.5232802283506972,4.081228747792777],[3.355813400389565,11.678591511056627,9.261609447847054,14.01149139466238,12.988943159511017,11.678591511056627],[3.355813400389565,-5.542723937645823,-5.665315226114917,-8.809462686792482,-3.870528020932883,-5.542723937645823],[-63.97692357876045,-61.43544110202029,-64.06701966551415,-60.18489099548072,-59.39707135678616,-61.43544110202029],[-63.97692357876045,-75.56402374661096,-73.74150861151352,-78.72546497988675,-75.88688300372158,-75.56402374661096],[-63.97692357876045,-45.23656532530523,-47.058868634523385,-42.07495686794399,-44.913997218206205,-45.23656532530523],[-62.404924031003524,-45.58920887426618,-47.79682792188675,-42.85260904487853,-44.67971865998992,-45.58920887426618],[-62.404924031003524,-60.63390464865972,-58.26105945788282,-60.18489099548072,-63.21974319107597,-60.63390464865972],[-62.404924031003524,-73.13932075400886,-71.33985951999672,-76.3186307050533,-73.43064993551232,-73.13932075400886],[-4.1719278913262,6.817161449693282,5.2166099201863565,10.125533073111447,6.848359451637408,6.817161449693282],[-4.1719278913262,22.805501213274873,20.433352306594486,25.243090157913215,24.021359580543646,22.805501213274873],[-4.1719278913262,-20.68422688205114,-21.94840904690689,-23.069068515975705,-18.288775302240346,-20.68422688205114],[-4.1719278913262,-14.598610212201267,-11.966421672795967,-15.83112350397367,-16.646145846074564,-14.598610212201267],[57.15111260781181,27.92991826889058,30.169305714216172,25.243090157913215,26.965050029348987,27.92991826889058],[57.15111260781181,34.68618773763334,34.308009113135824,31.557274837172773,36.54859215557459,34.68618773763334],[57.15111260781181,89.49770920624954,87.97614231752368,92.84630371836458,89.43084250644894,89.49770920624954],[57.15111260781181,60.503830331791065,62.50225489671609,61.83117772959097,57.87576751634617,60.503830331791065],[-77.75450951578995,-50.51340659045473,-49.72732968523327,-47.67221639320247,-52.647225637753884,-50.51340659045473],[-77.75450951578995,-89.53632757186526,-91.48878272761215,-90.94864585273737,-86.91392752224996,-89.53632757186526],[-77.75450951578995,-67.19902136463355,-66.10315372267164,-64.63727923889147,-69.51007263750387,-67.19902136463355],[-77.75450951578995,-87.18321662789494,-84.59750134645503,-88.90036074491448,-88.95439035109415,-87.18321662789494],[-47.67221639320247,-36.46855904708089,-37.36320511458642,-32.96973490092418,-37.23360924139366,-36.46855904708089],[-47.67221639320247,-31.866245369616706,-29.60671826768371,-31.10481605659189,-34.48696278340186,-31.866245369616706],[-47.67221639320247,-74.91331931853769,-75.69939622375915,-77.75450951578995,-72.77950027123853,-74.91331931853769],[-90.94864585273737,-35.59373480041118,-34.56168863943915,-32.96973490092418,-37.87049708379079,-35.59373480041118],[-90.94864585273737,124.69997677944767,126.49871840529508,126.37354748285645,122.10736300561382,124.69997677944767],[-90.94864585273737,-32.60747468181691,-30.706005979039073,-31.10481605659189,-35.22174197031805,-32.60747468181691],[-42.85260904487853,-11.533572206769882,-10.137162422946327,-9.301706363586224,-13.988686070042764,-11.533572206769882],[-42.85260904487853,-35.08704343716289,-37.57989245634689,-32.96973490092418,-33.59855728845109,-35.08704343716289],[-42.85260904487853,-59.668324201615874,-57.4607051539953,-62.404924031003524,-60.57781441589213,-59.668324201615874],[-64.63727923889147,-11.62003741370237,-10.296977788377296,-9.301706363586224,-14.042816606746115,-11.62003741370237],[-64.63727923889147,-66.07975920762186,-63.46444711211117,-66.77754289445465,-68.36407182210226,-66.07975920762186],[-64.63727923889147,-75.19276739004786,-76.28863503200978,-77.75450951578995,-72.88171611717755,-75.19276739004786],[-85.88234808320254,-12.606421681959004,-12.56683092207441,-9.301706363586224,-14.213631570773487,-12.606421681959004],[-85.88234808320254,-68.88389400370323,-71.38006613304823,-66.77754289445465,-67.38688699842909,-68.88389400370323],[-85.88234808320254,-105.76703875419709,-103.40689898907313,-108.23054927304726,-106.958591866123,-105.76703875419709],[-60.18489099548072,-12.761523097323153,-13.204379041668943,-9.301706363586224,-13.959859925088308,-12.761523097323153],[-60.18489099548072,-62.72637347222088,-60.09479490872701,-63.97692357876045,-64.76474321745502,-62.72637347222088],[-60.18489099548072,-61.955910377824516,-64.32875556860142,-62.404924031003524,-59.370071835408275,-61.955910377824516],[-78.72546497988675,-67.13836481203624,-68.96087994713368,-63.97692357876045,-66.81550555492562,-67.13836481203624],[-78.72546497988675,-34.498162474293004,-34.69053770413142,-31.10481605659189,-35.91544927068117,-34.498162474293004],[-78.72546497988675,-105.03974413834266,-105.31032266837661,-108.23054927304726,-103.25558072006073,-105.03974413834266],[-138.31755081958136,-67.47602529418664,-68.3625762387142,-63.97692357876045,-68.24930227876324,-67.47602529418664],[-138.31755081958136,124.01686469507796,125.3062458020324,126.37354748285645,121.60957155545849,124.01686469507796],[-138.31755081958136,-34.5598462232637,-34.979839227712084,-31.10481605659189,-35.77877544312704,-34.5598462232637],[-88.90036074491448,-12.18116655711732,-11.44293556593757,-9.301706363586224,-14.285293380617695,-12.18116655711732],[-88.90036074491448,-79.47165363280949,-82.0573689142494,-77.75450951578995,-77.70047990961028,-79.47165363280949],[-88.90036074491448,-104.65839718302922,-102.30046356274842,-107.12658247537667,-105.8455266325192,-104.65839718302922],[-76.3186307050533,-65.58423398204796,-67.38369521606009,-62.404924031003524,-65.2929048005445,-65.58423398204796],[-76.3186307050533,-33.73462058487396,-32.708660274638284,-31.10481605659189,-36.00805049134442,-33.73462058487396],[-76.3186307050533,-104.11064715736912,-104.66389320171523,-107.12658247537667,-102.12676717313741,-104.11064715736912],[-132.12310001662462,-65.77097449711265,-65.88432281758058,-62.404924031003524,-67.25434014177205,-65.77097449711265],[-132.12310001662462,124.25231692630199,125.73774141026563,126.37354748285645,121.76066912899023,124.25231692630199],[-132.12310001662462,-34.03519367811037,-33.36317027036751,-31.10481605659189,-36.097266022577465,-34.03519367811037],[-108.18615543517068,-12.744613863610894,-13.111490105592146,-9.301706363586224,-14.010909358441264,-12.744613863610894],[-108.18615543517068,-108.21938988929936,-105.71675582353038,-108.23054927304726,-110.71673040880341,-108.21938988929936],[-108.18615543517068,-107.32571052977488,-109.86889015196691,-107.12658247537667,-104.8769889522579,-107.32571052977488],[-22.79469114324,-10.384545287309257,-8.264027944667763,-9.301706363586224,-13.0187162572211,-10.384545287309257],[-22.79469114324,-30.646699420864422,-28.104055946820345,-32.579534443325066,-32.2724865661864,-30.646699420864422],[-22.79469114324,-30.713270479576288,-32.089164684361144,-32.96973490092418,-28.267003655707136,-30.713270479576288],[-45.22683346450635,-36.079513461528066,-36.90097901714958,-32.579534443325066,-36.91829199086145,-36.079513461528066],[-45.22683346450635,-32.09422145884922,-29.930857459302615,-31.10481605659189,-34.7269181195852,-32.09422145884922],[-45.22683346450635,-64.5090733767527,-65.87485516439682,-66.77754289445465,-62.06722425296812,-64.5090733767527],[-64.03495072668298,-34.310980404007246,-32.54898210889494,-32.579534443325066,-36.89430445555725,-34.310980404007246],[-64.03495072668298,124.79370687883284,126.64982737462977,126.37354748285645,122.18817588532713,124.79370687883284],[-64.03495072668298,-32.16939411737352,-30.040341552844616,-31.10481605659189,-34.80343811733478,-32.16939411737352],[-42.07495686794399,-12.695424768056213,-12.888940725168055,-9.301706363586224,-14.111747292180976,-12.695424768056213],[-42.07495686794399,-34.18218708428641,-36.784811167010396,-32.579534443325066,-32.3397945782533,-34.18218708428641],[-42.07495686794399,-60.81531512139921,-58.99301181218105,-63.97692357876045,-61.13788322849823,-60.81531512139921],[131.00734744620354,129.36080644402517,128.76660035904862,126.37354748285645,131.37204360110667,129.36080644402517],[131.00734744620354,137.03970141937427,134.79286551357063,139.71439408655877,138.01777466783912,137.03970141937427],[131.00734744620354,128.51201770873402,131.14402109071764,127.27376899987718,126.46738787496048,128.51201770873402],[124.18376030671041,126.0226522753041,123.4520230046316,126.37354748285645,128.42683149306256,126.0226522753041],[124.18376030671041,43.72199782605622,44.31578955449557,40.23719659705621,44.78125047234039,43.72199782605622],[124.18376030671041,137.93228422643273,135.35794628338147,139.71439408655877,139.6612635720107,137.93228422643273],[4.358736921811881,3.633321574408669,1.2070113596666006,3.355813400389565,6.191270093850749,3.633321574408669],[4.358736921811881,-28.872174038101036,-30.267940640689083,-31.10481605659189,-26.417335170867144,-28.872174038101036],[4.358736921811881,22.949797204136722,24.104320073496027,25.452036192329473,20.60831651083494,22.949797204136722],[33.298117054232016,5.043834977154391,3.2541720368425255,3.355813400389565,7.634224957121184,5.043834977154391],[33.298117054232016,143.77446386291902,145.41156694800216,145.69130507180833,141.22809124727445,143.77446386291902],[33.298117054232016,-28.9846485561763,-30.470903513953242,-31.10481605659189,-26.492674554550376,-28.9846485561763],[14.01149139466238,-7.521433258509701,-9.251623873263648,-9.301706363586224,-4.946755326278879,-7.521433258509701],[14.01149139466238,5.688713283995317,8.105695347204891,3.355813400389565,4.378361635540927,5.688713283995317],[14.01149139466238,25.921944955536027,24.23449349460363,29.179145738729886,26.064316201506276,25.921944955536027],[10.125533073111447,-8.484179280586963,-10.721123372036233,-9.301706363586224,-5.859434434681503,-8.484179280586963],[10.125533073111447,-0.8635562679080353,0.7369952615988904,-4.1719278913262,-0.8947542698521618,-0.8635562679080353],[10.125533073111447,22.05212797464435,21.839339191005095,25.452036192329473,20.65214208779445,22.05212797464435],[25.243090157913215,-7.452190485336964,-9.13596123691057,-9.301706363586224,-4.891086532357462,-7.452190485336964],[25.243090157913215,-1.7343389466878567,0.6378099599925307,-4.1719278913262,-2.9501973139566307,-1.7343389466878567],[25.243090157913215,54.464284496834445,52.224897051508854,57.15111260781181,55.42915273637604,54.464284496834445],[23.401213492016346,-6.294320950039556,-6.859909091961986,-9.301706363586224,-4.30215458634708,-6.294320950039556],[23.401213492016346,18.810489736109783,19.588186515219498,15.311254205601994,19.692684362398385,18.810489736109783],[23.401213492016346,27.84613681097089,29.84155699554903,29.179145738729886,25.218392782165758,27.84613681097089],[31.557274837172773,18.742549428739725,20.04929678264773,15.311254205601994,19.063465431760456,18.742549428739725],[31.557274837172773,-27.616534737570724,-26.58477978981921,-31.10481605659189,-26.993594501024518,-27.616534737570724],[31.557274837172773,54.02219970735124,54.40037833184876,57.15111260781181,52.15979528941,54.02219970735124],[92.84630371836458,18.810767795444914,19.682457480852698,15.311254205601994,19.59910141518799,18.810767795444914],[92.84630371836458,144.99280182885465,147.27683915601,145.69130507180833,142.3774236932532,144.99280182885465],[92.84630371836458,-27.605957308440054,-26.712263403823655,-31.10481605659189,-26.839938537494675,-27.605957308440054],[45.44349623079249,-7.143263088144719,-8.599324778426446,-9.301706363586224,-4.663325922574471,-7.143263088144719],[45.44349623079249,28.26932378667788,30.42091852415588,25.452036192329473,27.454132793281552,28.26932378667788],[45.44349623079249,65.67483076773036,63.80127886966559,68.79427403637042,66.06864887077052,65.67483076773036],[37.19475043550463,31.593715120722674,30.356584045207054,29.179145738729886,33.97621721512657,31.593715120722674],[37.19475043550463,-27.755741972126405,-27.687634109826355,-31.10481605659189,-26.235188756776793,-27.755741972126405],[37.19475043550463,65.67540260183164,66.0701587583672,68.79427403637042,63.80118390452162,65.67540260183164],[101.96862194881874,32.35627531494948,32.061052408935694,29.179145738729886,34.15859599458423,32.35627531494948],[101.96862194881874,144.97898527447109,147.25771487388994,145.69130507180833,142.3623608694049,144.97898527447109],[101.96862194881874,-27.7965836069397,-27.82810249458716,-31.10481605659189,-26.195777209959985,-27.7965836069397],[61.83117772959097,-6.256121447964842,-6.765664012583665,-9.301706363586224,-4.301880410843634,-6.256121447964842],[61.83117772959097,58.478460005611716,56.48003544068669,57.15111260781181,61.10652282105661,58.478460005611716],[61.83117772959097,67.51416956947446,69.53734408048773,68.79427403637042,64.88376688416787,67.51416956947446],[-8.809462686792482,-9.264816666742,-11.75592833379035,-9.301706363586224,-6.756206065939226,-9.264816666742],[-8.809462686792482,-12.792622312543616,-10.898266374905884,-15.893932332372234,-13.215846112173427,-12.792622312543616],[-8.809462686792482,0.08907465124290503,0.21166593971199799,3.355813400389565,-1.583121265470035,0.08907465124290503],[-23.069068515975705,-17.395881372093434,-20.010221232825813,-15.893932332372234,-15.494003499313518,-17.395881372093434],[-23.069068515975705,-30.480607610684405,-32.79247830635426,-31.10481605659189,-27.87263845993613,-30.480607610684405],[-23.069068515975705,-6.556769525250765,-5.292587360395016,-4.1719278913262,-8.95222110506156,-6.556769525250765],[-15.83112350397367,-15.890621102699695,-18.389834629265806,-15.893932332372234,-13.389836866866707,-15.890621102699695],[-15.83112350397367,143.2099412337331,144.38453244764838,145.69130507180833,140.85829449652485,143.2099412337331],[-15.83112350397367,-30.552758977345675,-32.89052800440449,-31.10481605659189,-27.953117094589977,-30.552758977345675],[-2.9036642890608477,-8.566626020528355,-10.836521428595166,-9.301706363586224,-5.948039153118154,-8.566626020528355],[-2.9036642890608477,-14.02846702749517,-11.470713843362352,-15.893932332372234,-15.701321267376343,-14.02846702749517],[-2.9036642890608477,12.277812726357082,10.311258734168376,15.311254205601994,12.805428585836927,12.277812726357082],[148.24265424743896,147.34879790487122,145.54002935182072,145.69130507180833,149.9438119347191,147.34879790487122],[148.24265424743896,142.30955453434743,144.60252533578108,139.71439408655877,141.24761962214097,142.30955453434743],[148.24265424743896,155.6009323505999,154.10076717136198,158.959461491847,155.50795136755966,155.6009323505999],[168.35118289317538,149.18943016871233,150.1009311344196,145.69130507180833,149.93729386501067,149.18943016871233],[168.35118289317538,2.7835499004337985,4.448394875858061,-0.48769825556553786,2.670448627806364,2.7835499004337985],[168.35118289317538,142.89277764149182,144.69345540850458,139.71439408655877,142.59979248330643,142.89277764149182]]},\"selected\":{\"id\":\"2286\",\"type\":\"Selection\"},\"selection_policy\":{\"id\":\"2285\",\"type\":\"UnionRenderers\"}},\"id\":\"2074\",\"type\":\"ColumnDataSource\"},{\"attributes\":{\"graph_layout\":{\"0\":[54.163249804316095,-372.3988437082021],\"1\":[-5.376934391232813,29.179145738729886],\"10\":[80.18597477774912,-66.77754289445465],\"11\":[-279.0340418060077,127.27376899987718],\"12\":[-56.49756828421992,25.452036192329473],\"13\":[6.946220625723527,-31.10481605659189],\"14\":[54.82114390636223,-32.579534443325066],\"15\":[-312.8456429228426,-0.48769825556553786],\"16\":[32.27911705289395,-108.23054927304726],\"17\":[81.6574700653745,-32.96973490092418],\"18\":[-261.81459007243876,139.71439408655877],\"19\":[-29.880186647960503,68.79427403637042],\"2\":[-266.3342513271957,126.37354748285645],\"20\":[303.515598696637,172.0908090627593],\"21\":[-23.25892335143727,3.355813400389565],\"22\":[25.985027634664394,-63.97692357876045],\"23\":[53.0593385673255,-62.404924031003524],\"24\":[-57.68755719689085,-4.1719278913262],\"25\":[-0.7423733409832874,57.15111260781181],\"26\":[102.9172021383139,-77.75450951578995],\"27\":[81.2762658112454,-47.67221639320247],\"28\":[132.83459744728637,-90.94864585273737],\"29\":[68.64900974840148,-42.85260904487853],\"3\":[-22.286204920732175,-15.893932332372234],\"30\":[90.70577084550146,-64.63727923889147],\"31\":[54.83301420959346,-85.88234808320254],\"32\":[35.89747915454103,-60.18489099548072],\"33\":[18.97910897391239,-78.72546497988675],\"34\":[24.300423829928715,-138.31755081958136],\"35\":[83.12103865364213,-88.90036074491448],\"36\":[46.654347703132004,-76.3186307050533],\"37\":[72.92255122890413,-132.12310001662462],\"38\":[46.20261375290823,-108.18615543517068],\"39\":[69.59281761915204,-22.79469114324],\"4\":[28.119930988062897,-9.301706363586224],\"40\":[54.86493663998685,-45.22683346450635],\"41\":[110.08059091333182,-64.03495072668298],\"42\":[36.38600931689903,-42.07495686794399],\"43\":[-269.16332375430784,131.00734744620354],\"44\":[-288.0662103796319,124.18376030671041],\"45\":[-35.86821400504032,4.358736921811881],\"46\":[-77.64460979933524,33.298117054232016],\"47\":[-11.341529184006871,14.01149139466238],\"48\":[-52.75131830970994,10.125533073111447],\"49\":[-27.379367102201602,25.243090157913215],\"5\":[8.81956516896188,15.311254205601994],\"50\":[8.650451565354086,23.401213492016346],\"51\":[12.086869436585594,31.557274837172773],\"52\":[10.112348168314254,92.84630371836458],\"53\":[-41.76095958644098,45.44349623079249],\"54\":[-13.788158437080762,37.19475043550463],\"55\":[-39.015905256311996,101.96862194881874],\"56\":[-12.161074716958174,61.83117772959097],\"57\":[-18.580294761336713,-8.809462686792482],\"58\":[-37.38867077745631,-23.069068515975705],\"59\":[-88.67568035921364,-15.83112350397367],\"6\":[64.79616894839232,-107.12658247537667],\"60\":[-1.6641611892297095,-2.9036642890608477],\"61\":[-254.09712653916537,148.24265424743896],\"62\":[-248.6100641272736,168.35118289317538],\"7\":[-280.21735777124405,40.23719659705621],\"8\":[-249.35206171180178,145.69130507180833],\"9\":[-250.95397523463345,158.959461491847]}},\"id\":\"2081\",\"type\":\"StaticLayoutProvider\"},{\"attributes\":{\"data_source\":{\"id\":\"2074\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"2087\",\"type\":\"MultiLine\"},\"hover_glyph\":{\"id\":\"2097\",\"type\":\"MultiLine\"},\"muted_glyph\":null,\"selection_glyph\":{\"id\":\"2092\",\"type\":\"MultiLine\"},\"view\":{\"id\":\"2076\",\"type\":\"CDSView\"}},\"id\":\"2075\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"line_color\":{\"value\":\"#abdda4\"},\"line_join\":\"round\",\"line_width\":{\"value\":5}},\"id\":\"2097\",\"type\":\"MultiLine\"},{\"attributes\":{\"bottom_units\":\"screen\",\"fill_alpha\":{\"value\":0.5},\"fill_color\":{\"value\":\"lightgrey\"},\"left_units\":\"screen\",\"level\":\"overlay\",\"line_alpha\":{\"value\":1.0},\"line_color\":{\"value\":\"black\"},\"line_dash\":[4,4],\"line_width\":{\"value\":2},\"render_mode\":\"css\",\"right_units\":\"screen\",\"top_units\":\"screen\"},\"id\":\"2282\",\"type\":\"BoxAnnotation\"},{\"attributes\":{\"callback\":null,\"end\":143.97660345653964,\"start\":-323.98764893209585},\"id\":\"2110\",\"type\":\"Range1d\"},{\"attributes\":{},\"id\":\"2276\",\"type\":\"NodesOnly\"},{\"attributes\":{\"line_color\":{\"value\":\"#fdae61\"},\"line_join\":\"round\",\"line_width\":{\"value\":5}},\"id\":\"2092\",\"type\":\"MultiLine\"},{\"attributes\":{\"callback\":null},\"id\":\"2145\",\"type\":\"TapTool\"},{\"attributes\":{\"source\":{\"id\":\"2038\",\"type\":\"ColumnDataSource\"}},\"id\":\"2040\",\"type\":\"CDSView\"},{\"attributes\":{\"active_drag\":\"auto\",\"active_inspect\":\"auto\",\"active_multi\":null,\"active_scroll\":\"auto\",\"active_tap\":\"auto\",\"tools\":[{\"id\":\"2142\",\"type\":\"HoverTool\"},{\"id\":\"2143\",\"type\":\"HoverTool\"},{\"id\":\"2144\",\"type\":\"HoverTool\"},{\"id\":\"2145\",\"type\":\"TapTool\"},{\"id\":\"2146\",\"type\":\"BoxSelectTool\"},{\"id\":\"2147\",\"type\":\"PanTool\"},{\"id\":\"2148\",\"type\":\"WheelZoomTool\"}]},\"id\":\"2149\",\"type\":\"Toolbar\"},{\"attributes\":{\"data_source\":{\"id\":\"2070\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"2082\",\"type\":\"Circle\"},\"hover_glyph\":null,\"muted_glyph\":null,\"view\":{\"id\":\"2072\",\"type\":\"CDSView\"}},\"id\":\"2071\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"source\":{\"id\":\"2042\",\"type\":\"ColumnDataSource\"}},\"id\":\"2044\",\"type\":\"CDSView\"},{\"attributes\":{},\"id\":\"2292\",\"type\":\"Selection\"},{\"attributes\":{},\"id\":\"2277\",\"type\":\"NodesOnly\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"size\":{\"units\":\"screen\",\"value\":12}},\"id\":\"2127\",\"type\":\"Circle\"},{\"attributes\":{},\"id\":\"2291\",\"type\":\"UnionRenderers\"},{\"attributes\":{\"callback\":null,\"overlay\":{\"id\":\"2282\",\"type\":\"BoxAnnotation\"}},\"id\":\"2146\",\"type\":\"BoxSelectTool\"},{\"attributes\":{\"text\":\"\"},\"id\":\"2253\",\"type\":\"Title\"},{\"attributes\":{},\"id\":\"2147\",\"type\":\"PanTool\"},{\"attributes\":{\"fill_color\":{\"value\":\"#abdda4\"},\"size\":{\"units\":\"screen\",\"value\":8}},\"id\":\"2122\",\"type\":\"Square\"},{\"attributes\":{},\"id\":\"2057\",\"type\":\"MultiLine\"},{\"attributes\":{},\"id\":\"2148\",\"type\":\"WheelZoomTool\"},{\"attributes\":{},\"id\":\"2285\",\"type\":\"UnionRenderers\"},{\"attributes\":{\"data_source\":{\"id\":\"2054\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"2127\",\"type\":\"Circle\"},\"hover_glyph\":{\"id\":\"2137\",\"type\":\"Circle\"},\"muted_glyph\":null,\"selection_glyph\":{\"id\":\"2132\",\"type\":\"Circle\"},\"view\":{\"id\":\"2056\",\"type\":\"CDSView\"}},\"id\":\"2055\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"fill_color\":{\"value\":\"#2b83ba\"},\"size\":{\"units\":\"screen\",\"value\":8}},\"id\":\"2112\",\"type\":\"Square\"},{\"attributes\":{},\"id\":\"2287\",\"type\":\"UnionRenderers\"},{\"attributes\":{},\"id\":\"2156\",\"type\":\"NodesAndLinkedEdges\"},{\"attributes\":{\"graph_layout\":{\"0\":[54.163249804316095,-372.3988437082021],\"1\":[-5.376934391232813,29.179145738729886],\"10\":[80.18597477774912,-66.77754289445465],\"11\":[-279.0340418060077,127.27376899987718],\"12\":[-56.49756828421992,25.452036192329473],\"13\":[6.946220625723527,-31.10481605659189],\"14\":[54.82114390636223,-32.579534443325066],\"15\":[-312.8456429228426,-0.48769825556553786],\"16\":[32.27911705289395,-108.23054927304726],\"17\":[81.6574700653745,-32.96973490092418],\"18\":[-261.81459007243876,139.71439408655877],\"19\":[-29.880186647960503,68.79427403637042],\"2\":[-266.3342513271957,126.37354748285645],\"20\":[303.515598696637,172.0908090627593],\"21\":[-23.25892335143727,3.355813400389565],\"22\":[25.985027634664394,-63.97692357876045],\"23\":[53.0593385673255,-62.404924031003524],\"24\":[-57.68755719689085,-4.1719278913262],\"25\":[-0.7423733409832874,57.15111260781181],\"26\":[102.9172021383139,-77.75450951578995],\"27\":[81.2762658112454,-47.67221639320247],\"28\":[132.83459744728637,-90.94864585273737],\"29\":[68.64900974840148,-42.85260904487853],\"3\":[-22.286204920732175,-15.893932332372234],\"30\":[90.70577084550146,-64.63727923889147],\"31\":[54.83301420959346,-85.88234808320254],\"32\":[35.89747915454103,-60.18489099548072],\"33\":[18.97910897391239,-78.72546497988675],\"34\":[24.300423829928715,-138.31755081958136],\"35\":[83.12103865364213,-88.90036074491448],\"36\":[46.654347703132004,-76.3186307050533],\"37\":[72.92255122890413,-132.12310001662462],\"38\":[46.20261375290823,-108.18615543517068],\"39\":[69.59281761915204,-22.79469114324],\"4\":[28.119930988062897,-9.301706363586224],\"40\":[54.86493663998685,-45.22683346450635],\"41\":[110.08059091333182,-64.03495072668298],\"42\":[36.38600931689903,-42.07495686794399],\"43\":[-269.16332375430784,131.00734744620354],\"44\":[-288.0662103796319,124.18376030671041],\"45\":[-35.86821400504032,4.358736921811881],\"46\":[-77.64460979933524,33.298117054232016],\"47\":[-11.341529184006871,14.01149139466238],\"48\":[-52.75131830970994,10.125533073111447],\"49\":[-27.379367102201602,25.243090157913215],\"5\":[8.81956516896188,15.311254205601994],\"50\":[8.650451565354086,23.401213492016346],\"51\":[12.086869436585594,31.557274837172773],\"52\":[10.112348168314254,92.84630371836458],\"53\":[-41.76095958644098,45.44349623079249],\"54\":[-13.788158437080762,37.19475043550463],\"55\":[-39.015905256311996,101.96862194881874],\"56\":[-12.161074716958174,61.83117772959097],\"57\":[-18.580294761336713,-8.809462686792482],\"58\":[-37.38867077745631,-23.069068515975705],\"59\":[-88.67568035921364,-15.83112350397367],\"6\":[64.79616894839232,-107.12658247537667],\"60\":[-1.6641611892297095,-2.9036642890608477],\"61\":[-254.09712653916537,148.24265424743896],\"62\":[-248.6100641272736,168.35118289317538],\"7\":[-280.21735777124405,40.23719659705621],\"8\":[-249.35206171180178,145.69130507180833],\"9\":[-250.95397523463345,158.959461491847]}},\"id\":\"2065\",\"type\":\"StaticLayoutProvider\"},{\"attributes\":{\"line_alpha\":{\"value\":0.2},\"line_join\":\"round\",\"line_width\":{\"value\":4}},\"id\":\"2087\",\"type\":\"MultiLine\"},{\"attributes\":{\"fill_color\":{\"value\":\"#fdae61\"},\"size\":{\"units\":\"screen\",\"value\":15}},\"id\":\"2132\",\"type\":\"Circle\"},{\"attributes\":{},\"id\":\"2252\",\"type\":\"LinearScale\"},{\"attributes\":{},\"id\":\"2283\",\"type\":\"UnionRenderers\"},{\"attributes\":{\"edge_renderer\":{\"id\":\"2059\",\"type\":\"GlyphRenderer\"},\"inspection_policy\":{\"id\":\"2276\",\"type\":\"NodesOnly\"},\"layout_provider\":{\"id\":\"2065\",\"type\":\"StaticLayoutProvider\"},\"node_renderer\":{\"id\":\"2055\",\"type\":\"GlyphRenderer\"},\"selection_policy\":{\"id\":\"2277\",\"type\":\"NodesOnly\"}},\"id\":\"2052\",\"type\":\"GraphRenderer\"},{\"attributes\":{},\"id\":\"2284\",\"type\":\"Selection\"},{\"attributes\":{\"fill_alpha\":{\"value\":0},\"fill_color\":{\"field\":\"color\"},\"line_alpha\":{\"value\":0},\"size\":{\"units\":\"screen\",\"value\":12}},\"id\":\"2082\",\"type\":\"Circle\"},{\"attributes\":{},\"id\":\"2290\",\"type\":\"Selection\"},{\"attributes\":{},\"id\":\"2293\",\"type\":\"UnionRenderers\"},{\"attributes\":{\"callback\":null,\"renderers\":[{\"id\":\"2068\",\"type\":\"GraphRenderer\"}],\"tooltips\":null},\"id\":\"2142\",\"type\":\"HoverTool\"},{\"attributes\":{\"source\":{\"id\":\"2074\",\"type\":\"ColumnDataSource\"}},\"id\":\"2076\",\"type\":\"CDSView\"},{\"attributes\":{\"callback\":null,\"data\":{\"end\":[],\"start\":[]},\"selected\":{\"id\":\"2294\",\"type\":\"Selection\"},\"selection_policy\":{\"id\":\"2293\",\"type\":\"UnionRenderers\"}},\"id\":\"2058\",\"type\":\"ColumnDataSource\"},{\"attributes\":{\"edge_renderer\":{\"id\":\"2075\",\"type\":\"GlyphRenderer\"},\"inspection_policy\":{\"id\":\"2158\",\"type\":\"EdgesAndLinkedNodes\"},\"layout_provider\":{\"id\":\"2081\",\"type\":\"StaticLayoutProvider\"},\"node_renderer\":{\"id\":\"2071\",\"type\":\"GlyphRenderer\"},\"selection_policy\":{\"id\":\"2156\",\"type\":\"NodesAndLinkedEdges\"}},\"id\":\"2068\",\"type\":\"GraphRenderer\"},{\"attributes\":{\"data_source\":{\"id\":\"2042\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"2041\",\"type\":\"MultiLine\"},\"hover_glyph\":null,\"muted_glyph\":null,\"view\":{\"id\":\"2044\",\"type\":\"CDSView\"}},\"id\":\"2043\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"data_source\":{\"id\":\"2058\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"2057\",\"type\":\"MultiLine\"},\"hover_glyph\":null,\"muted_glyph\":null,\"view\":{\"id\":\"2060\",\"type\":\"CDSView\"}},\"id\":\"2059\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"source\":{\"id\":\"2070\",\"type\":\"ColumnDataSource\"}},\"id\":\"2072\",\"type\":\"CDSView\"},{\"attributes\":{},\"id\":\"2289\",\"type\":\"UnionRenderers\"},{\"attributes\":{\"data_source\":{\"id\":\"2038\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"2112\",\"type\":\"Square\"},\"hover_glyph\":{\"id\":\"2122\",\"type\":\"Square\"},\"muted_glyph\":null,\"selection_glyph\":{\"id\":\"2117\",\"type\":\"Square\"},\"view\":{\"id\":\"2040\",\"type\":\"CDSView\"}},\"id\":\"2039\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"fill_color\":{\"value\":\"#fdae61\"},\"size\":{\"units\":\"screen\",\"value\":8}},\"id\":\"2117\",\"type\":\"Square\"},{\"attributes\":{},\"id\":\"2286\",\"type\":\"Selection\"},{\"attributes\":{},\"id\":\"2294\",\"type\":\"Selection\"},{\"attributes\":{},\"id\":\"2041\",\"type\":\"MultiLine\"},{\"attributes\":{},\"id\":\"2288\",\"type\":\"Selection\"},{\"attributes\":{},\"id\":\"2266\",\"type\":\"NodesOnly\"},{\"attributes\":{\"callback\":null,\"data\":{\"end\":[],\"start\":[]},\"selected\":{\"id\":\"2290\",\"type\":\"Selection\"},\"selection_policy\":{\"id\":\"2289\",\"type\":\"UnionRenderers\"}},\"id\":\"2042\",\"type\":\"ColumnDataSource\"},{\"attributes\":{\"fill_color\":{\"value\":\"#abdda4\"},\"size\":{\"units\":\"screen\",\"value\":15}},\"id\":\"2137\",\"type\":\"Circle\"},{\"attributes\":{\"edge_renderer\":{\"id\":\"2043\",\"type\":\"GlyphRenderer\"},\"inspection_policy\":{\"id\":\"2266\",\"type\":\"NodesOnly\"},\"layout_provider\":{\"id\":\"2049\",\"type\":\"StaticLayoutProvider\"},\"node_renderer\":{\"id\":\"2039\",\"type\":\"GlyphRenderer\"},\"selection_policy\":{\"id\":\"2267\",\"type\":\"NodesOnly\"}},\"id\":\"2036\",\"type\":\"GraphRenderer\"},{\"attributes\":{},\"id\":\"2250\",\"type\":\"LinearScale\"},{\"attributes\":{\"callback\":null,\"data\":{\"color\":[\"blue\",\"blue\",\"blue\",\"blue\",\"blue\",\"blue\",\"blue\",\"blue\",\"blue\",\"blue\",\"blue\",\"blue\",\"blue\",\"blue\",\"blue\",\"blue\",\"blue\",\"blue\",\"blue\",\"blue\",\"blue\",\"blue\",\"blue\",\"blue\",\"blue\",\"blue\",\"blue\",\"blue\",\"blue\",\"blue\",\"blue\",\"blue\",\"blue\",\"blue\",\"blue\",\"blue\"],\"index\":[27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62],\"k\":[\"100\",\"0.05\",\"100\",\"100\",\"100\",\"100\",\"100\",\"0.05\",\"100\",\"100\",\"0.05\",\"100\",\"100\",\"100\",\"0.05\",\"100\",\"100\",\"0.2\",\"100\",\"0.05\",\"100\",\"100\",\"100\",\"100\",\"100\",\"0.05\",\"100\",\"100\",\"0.05\",\"100\",\"100\",\"100\",\"0.05\",\"100\",\"100\",\"0.2\"],\"k_r\":[\"10\",\"None\",\"10\",\"10\",\"10\",\"10\",\"10\",\"None\",\"10\",\"10\",\"None\",\"10\",\"10\",\"10\",\"None\",\"10\",\"10\",\"None\",\"10\",\"None\",\"10\",\"10\",\"10\",\"10\",\"10\",\"None\",\"10\",\"10\",\"None\",\"10\",\"10\",\"10\",\"None\",\"10\",\"10\",\"None\"],\"species\":[\"ordered_polymer[dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:[dna[attP]:2x_protein[Bxb1]-forward]:dna[pconst-forward]:dna[attB-reverse]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]]+protein[RNAP] <--> ordered_polymer[dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:[dna[attP]:2x_protein[Bxb1]-forward]:complex[dna[pconst]:protein[RNAP]-forward]:dna[attB-reverse]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]]\\n Kf=k_forward * ordered_polymer_t16_r_RFP_r_UTR1_r_dna_attP_protein_Bxb1_2x_f_pconst_f_attB_r_UTR1_f_GFP_f_t16_f * protein_RNAP\\n Kr=k_reverse * ordered_polymer_t16_r_RFP_r_UTR1_r_dna_attP_protein_Bxb1_2x_f_dna_pconst_protein_RNAP_f_attB_r_UTR1_f_GFP_f_t16_f\\n k_forward=100\\n found_key=(mech=None, partid=None, name=kb).\\n search_key=(mech=transcription_mm, partid=pconst, name=kb).\\n k_reverse=10\\n found_key=(mech=None, partid=None, name=ku).\\n search_key=(mech=transcription_mm, partid=pconst, name=ku).\\n\",\"ordered_polymer[dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:[dna[attP]:2x_protein[Bxb1]-forward]:complex[dna[pconst]:protein[RNAP]-forward]:dna[attB-reverse]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]] --> ordered_polymer[dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:[dna[attP]:2x_protein[Bxb1]-forward]:dna[pconst-forward]:dna[attB-reverse]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]]+rna[rna[attB-reverse]:rna[UTR1-forward]:rna[GFP-forward]:rna[t16-forward]]+protein[RNAP]\\n Kf=k_forward * ordered_polymer_t16_r_RFP_r_UTR1_r_dna_attP_protein_Bxb1_2x_f_dna_pconst_protein_RNAP_f_attB_r_UTR1_f_GFP_f_t16_f\\n k_forward=0.05\\n found_key=(mech=None, partid=None, name=ktx).\\n search_key=(mech=transcription_mm, partid=pconst, name=ktx).\\n\",\"2protein[Bxb1]+ordered_polymer[dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:[dna[attP]:2x_protein[Bxb1]-forward]:dna[pconst-forward]:dna[attB-reverse]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]] <--> ordered_polymer[dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:[dna[attP]:2x_protein[Bxb1]-forward]:dna[pconst-forward]:[dna[attB]:2x_protein[Bxb1]-reverse]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]]\\n Kf=k_forward * protein_Bxb1^2 * ordered_polymer_t16_r_RFP_r_UTR1_r_dna_attP_protein_Bxb1_2x_f_pconst_f_attB_r_UTR1_f_GFP_f_t16_f\\n Kr=k_reverse * ordered_polymer_t16_r_RFP_r_UTR1_r_dna_attP_protein_Bxb1_2x_f_pconst_f_dna_attB_protein_Bxb1_2x_r_UTR1_f_GFP_f_t16_f\\n k_forward=100\\n found_key=(mech=None, partid=None, name=kb).\\n search_key=(mech=one_step_cooperative_binding, partid=attB, name=kb).\\n k_reverse=10\\n found_key=(mech=None, partid=None, name=ku).\\n search_key=(mech=one_step_cooperative_binding, partid=attB, name=ku).\\n\",\"2protein[Bxb1]+ordered_polymer[dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:dna[attP-forward]:complex[dna[pconst]:protein[RNAP]-forward]:dna[attB-reverse]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]] <--> ordered_polymer[dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:[dna[attP]:2x_protein[Bxb1]-forward]:complex[dna[pconst]:protein[RNAP]-forward]:dna[attB-reverse]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]]\\n Kf=k_forward * protein_Bxb1^2 * ordered_polymer_t16_r_RFP_r_UTR1_r_attP_f_dna_pconst_protein_RNAP_f_attB_r_UTR1_f_GFP_f_t16_f\\n Kr=k_reverse * ordered_polymer_t16_r_RFP_r_UTR1_r_dna_attP_protein_Bxb1_2x_f_dna_pconst_protein_RNAP_f_attB_r_UTR1_f_GFP_f_t16_f\\n k_forward=100\\n found_key=(mech=None, partid=None, name=kb).\\n search_key=(mech=one_step_cooperative_binding, partid=attP, name=kb).\\n k_reverse=10\\n found_key=(mech=None, partid=None, name=ku).\\n search_key=(mech=one_step_cooperative_binding, partid=attP, name=ku).\\n\",\"2protein[Bxb1]+ordered_polymer[dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:dna[attP-forward]:complex[dna[pconst]:protein[RNAP]-forward]:dna[attB-reverse]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]] <--> ordered_polymer[dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:dna[attP-forward]:complex[dna[pconst]:protein[RNAP]-forward]:[dna[attB]:2x_protein[Bxb1]-reverse]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]]\\n Kf=k_forward * protein_Bxb1^2 * ordered_polymer_t16_r_RFP_r_UTR1_r_attP_f_dna_pconst_protein_RNAP_f_attB_r_UTR1_f_GFP_f_t16_f\\n Kr=k_reverse * ordered_polymer_t16_r_RFP_r_UTR1_r_attP_f_dna_pconst_protein_RNAP_f_dna_attB_protein_Bxb1_2x_r_UTR1_f_GFP_f_t16_f\\n k_forward=100\\n found_key=(mech=None, partid=None, name=kb).\\n search_key=(mech=one_step_cooperative_binding, partid=attB, name=kb).\\n k_reverse=10\\n found_key=(mech=None, partid=None, name=ku).\\n search_key=(mech=one_step_cooperative_binding, partid=attB, name=ku).\\n\",\"2protein[Bxb1]+ordered_polymer[dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:dna[attP-forward]:dna[pconst-forward]:[dna[attB]:2x_protein[Bxb1]-reverse]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]] <--> ordered_polymer[dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:[dna[attP]:2x_protein[Bxb1]-forward]:dna[pconst-forward]:[dna[attB]:2x_protein[Bxb1]-reverse]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]]\\n Kf=k_forward * protein_Bxb1^2 * ordered_polymer_t16_r_RFP_r_UTR1_r_attP_f_pconst_f_dna_attB_protein_Bxb1_2x_r_UTR1_f_GFP_f_t16_f\\n Kr=k_reverse * ordered_polymer_t16_r_RFP_r_UTR1_r_dna_attP_protein_Bxb1_2x_f_pconst_f_dna_attB_protein_Bxb1_2x_r_UTR1_f_GFP_f_t16_f\\n k_forward=100\\n found_key=(mech=None, partid=None, name=kb).\\n search_key=(mech=one_step_cooperative_binding, partid=attP, name=kb).\\n k_reverse=10\\n found_key=(mech=None, partid=None, name=ku).\\n search_key=(mech=one_step_cooperative_binding, partid=attP, name=ku).\\n\",\"ordered_polymer[dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:dna[attP-forward]:dna[pconst-forward]:[dna[attB]:2x_protein[Bxb1]-reverse]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]]+protein[RNAP] <--> ordered_polymer[dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:dna[attP-forward]:complex[dna[pconst]:protein[RNAP]-forward]:[dna[attB]:2x_protein[Bxb1]-reverse]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]]\\n Kf=k_forward * ordered_polymer_t16_r_RFP_r_UTR1_r_attP_f_pconst_f_dna_attB_protein_Bxb1_2x_r_UTR1_f_GFP_f_t16_f * protein_RNAP\\n Kr=k_reverse * ordered_polymer_t16_r_RFP_r_UTR1_r_attP_f_dna_pconst_protein_RNAP_f_dna_attB_protein_Bxb1_2x_r_UTR1_f_GFP_f_t16_f\\n k_forward=100\\n found_key=(mech=None, partid=None, name=kb).\\n search_key=(mech=transcription_mm, partid=pconst, name=kb).\\n k_reverse=10\\n found_key=(mech=None, partid=None, name=ku).\\n search_key=(mech=transcription_mm, partid=pconst, name=ku).\\n\",\"ordered_polymer[dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:dna[attP-forward]:complex[dna[pconst]:protein[RNAP]-forward]:[dna[attB]:2x_protein[Bxb1]-reverse]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]] --> ordered_polymer[dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:dna[attP-forward]:dna[pconst-forward]:[dna[attB]:2x_protein[Bxb1]-reverse]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]]+rna[rna[attB-reverse]:rna[UTR1-forward]:rna[GFP-forward]:rna[t16-forward]]+protein[RNAP]\\n Kf=k_forward * ordered_polymer_t16_r_RFP_r_UTR1_r_attP_f_dna_pconst_protein_RNAP_f_dna_attB_protein_Bxb1_2x_r_UTR1_f_GFP_f_t16_f\\n k_forward=0.05\\n found_key=(mech=None, partid=None, name=ktx).\\n search_key=(mech=transcription_mm, partid=pconst, name=ktx).\\n\",\"2protein[Bxb1]+ordered_polymer[dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:[dna[attP]:2x_protein[Bxb1]-forward]:complex[dna[pconst]:protein[RNAP]-forward]:dna[attB-reverse]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]] <--> ordered_polymer[dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:[dna[attP]:2x_protein[Bxb1]-forward]:complex[dna[pconst]:protein[RNAP]-forward]:[dna[attB]:2x_protein[Bxb1]-reverse]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]]\\n Kf=k_forward * protein_Bxb1^2 * ordered_polymer_t16_r_RFP_r_UTR1_r_dna_attP_protein_Bxb1_2x_f_dna_pconst_protein_RNAP_f_attB_r_UTR1_f_GFP_f_t16_f\\n Kr=k_reverse * ordered_polymer_t16_r_RFP_r_UTR1_r_dna_attP_protein_Bxb1_2x_f_dna_pconst_protein_RNAP_f_dna_attB_protein_Bxb1_2x_r_UTR1_f_GFP_f_t16_f\\n k_forward=100\\n found_key=(mech=None, partid=None, name=kb).\\n search_key=(mech=one_step_cooperative_binding, partid=attB, name=kb).\\n k_reverse=10\\n found_key=(mech=None, partid=None, name=ku).\\n search_key=(mech=one_step_cooperative_binding, partid=attB, name=ku).\\n\",\"ordered_polymer[dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:[dna[attP]:2x_protein[Bxb1]-forward]:dna[pconst-forward]:[dna[attB]:2x_protein[Bxb1]-reverse]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]]+protein[RNAP] <--> ordered_polymer[dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:[dna[attP]:2x_protein[Bxb1]-forward]:complex[dna[pconst]:protein[RNAP]-forward]:[dna[attB]:2x_protein[Bxb1]-reverse]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]]\\n Kf=k_forward * ordered_polymer_t16_r_RFP_r_UTR1_r_dna_attP_protein_Bxb1_2x_f_pconst_f_dna_attB_protein_Bxb1_2x_r_UTR1_f_GFP_f_t16_f * protein_RNAP\\n Kr=k_reverse * ordered_polymer_t16_r_RFP_r_UTR1_r_dna_attP_protein_Bxb1_2x_f_dna_pconst_protein_RNAP_f_dna_attB_protein_Bxb1_2x_r_UTR1_f_GFP_f_t16_f\\n k_forward=100\\n found_key=(mech=None, partid=None, name=kb).\\n search_key=(mech=transcription_mm, partid=pconst, name=kb).\\n k_reverse=10\\n found_key=(mech=None, partid=None, name=ku).\\n search_key=(mech=transcription_mm, partid=pconst, name=ku).\\n\",\"ordered_polymer[dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:[dna[attP]:2x_protein[Bxb1]-forward]:complex[dna[pconst]:protein[RNAP]-forward]:[dna[attB]:2x_protein[Bxb1]-reverse]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]] --> ordered_polymer[dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:[dna[attP]:2x_protein[Bxb1]-forward]:dna[pconst-forward]:[dna[attB]:2x_protein[Bxb1]-reverse]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]]+rna[rna[attB-reverse]:rna[UTR1-forward]:rna[GFP-forward]:rna[t16-forward]]+protein[RNAP]\\n Kf=k_forward * ordered_polymer_t16_r_RFP_r_UTR1_r_dna_attP_protein_Bxb1_2x_f_dna_pconst_protein_RNAP_f_dna_attB_protein_Bxb1_2x_r_UTR1_f_GFP_f_t16_f\\n k_forward=0.05\\n found_key=(mech=None, partid=None, name=ktx).\\n search_key=(mech=transcription_mm, partid=pconst, name=ktx).\\n\",\"2protein[Bxb1]+ordered_polymer[dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:dna[attP-forward]:complex[dna[pconst]:protein[RNAP]-forward]:[dna[attB]:2x_protein[Bxb1]-reverse]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]] <--> ordered_polymer[dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:[dna[attP]:2x_protein[Bxb1]-forward]:complex[dna[pconst]:protein[RNAP]-forward]:[dna[attB]:2x_protein[Bxb1]-reverse]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]]\\n Kf=k_forward * protein_Bxb1^2 * ordered_polymer_t16_r_RFP_r_UTR1_r_attP_f_dna_pconst_protein_RNAP_f_dna_attB_protein_Bxb1_2x_r_UTR1_f_GFP_f_t16_f\\n Kr=k_reverse * ordered_polymer_t16_r_RFP_r_UTR1_r_dna_attP_protein_Bxb1_2x_f_dna_pconst_protein_RNAP_f_dna_attB_protein_Bxb1_2x_r_UTR1_f_GFP_f_t16_f\\n k_forward=100\\n found_key=(mech=None, partid=None, name=kb).\\n search_key=(mech=one_step_cooperative_binding, partid=attP, name=kb).\\n k_reverse=10\\n found_key=(mech=None, partid=None, name=ku).\\n search_key=(mech=one_step_cooperative_binding, partid=attP, name=ku).\\n\",\"2protein[Bxb1]+dna[dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:dna[attP-forward]:dna[pconst-forward]:dna[attB-reverse]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]] <--> ordered_polymer[dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:[dna[attP]:2x_protein[Bxb1]-forward]:dna[pconst-forward]:dna[attB-reverse]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]]\\n Kf=k_forward * protein_Bxb1^2 * dna_t16_r_RFP_r_UTR1_r_attP_f_pconst_f_attB_r_UTR1_f_GFP_f_t16_f\\n Kr=k_reverse * ordered_polymer_t16_r_RFP_r_UTR1_r_dna_attP_protein_Bxb1_2x_f_pconst_f_attB_r_UTR1_f_GFP_f_t16_f\\n k_forward=100\\n found_key=(mech=None, partid=None, name=kb).\\n search_key=(mech=one_step_cooperative_binding, partid=attP, name=kb).\\n k_reverse=10\\n found_key=(mech=None, partid=None, name=ku).\\n search_key=(mech=one_step_cooperative_binding, partid=attP, name=ku).\\n\",\"dna[dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:dna[attP-forward]:dna[pconst-forward]:dna[attB-reverse]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]]+protein[RNAP] <--> ordered_polymer[dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:dna[attP-forward]:complex[dna[pconst]:protein[RNAP]-forward]:dna[attB-reverse]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]]\\n Kf=k_forward * dna_t16_r_RFP_r_UTR1_r_attP_f_pconst_f_attB_r_UTR1_f_GFP_f_t16_f * protein_RNAP\\n Kr=k_reverse * ordered_polymer_t16_r_RFP_r_UTR1_r_attP_f_dna_pconst_protein_RNAP_f_attB_r_UTR1_f_GFP_f_t16_f\\n k_forward=100\\n found_key=(mech=None, partid=None, name=kb).\\n search_key=(mech=transcription_mm, partid=pconst, name=kb).\\n k_reverse=10\\n found_key=(mech=None, partid=None, name=ku).\\n search_key=(mech=transcription_mm, partid=pconst, name=ku).\\n\",\"ordered_polymer[dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:dna[attP-forward]:complex[dna[pconst]:protein[RNAP]-forward]:dna[attB-reverse]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]] --> dna[dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:dna[attP-forward]:dna[pconst-forward]:dna[attB-reverse]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]]+rna[rna[attB-reverse]:rna[UTR1-forward]:rna[GFP-forward]:rna[t16-forward]]+protein[RNAP]\\n Kf=k_forward * ordered_polymer_t16_r_RFP_r_UTR1_r_attP_f_dna_pconst_protein_RNAP_f_attB_r_UTR1_f_GFP_f_t16_f\\n k_forward=0.05\\n found_key=(mech=None, partid=None, name=ktx).\\n search_key=(mech=transcription_mm, partid=pconst, name=ktx).\\n\",\"2protein[Bxb1]+dna[dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:dna[attP-forward]:dna[pconst-forward]:dna[attB-reverse]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]] <--> ordered_polymer[dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:dna[attP-forward]:dna[pconst-forward]:[dna[attB]:2x_protein[Bxb1]-reverse]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]]\\n Kf=k_forward * protein_Bxb1^2 * dna_t16_r_RFP_r_UTR1_r_attP_f_pconst_f_attB_r_UTR1_f_GFP_f_t16_f\\n Kr=k_reverse * ordered_polymer_t16_r_RFP_r_UTR1_r_attP_f_pconst_f_dna_attB_protein_Bxb1_2x_r_UTR1_f_GFP_f_t16_f\\n k_forward=100\\n found_key=(mech=None, partid=None, name=kb).\\n search_key=(mech=one_step_cooperative_binding, partid=attB, name=kb).\\n k_reverse=10\\n found_key=(mech=None, partid=None, name=ku).\\n search_key=(mech=one_step_cooperative_binding, partid=attB, name=ku).\\n\",\"rna[rna[attB-reverse]:rna[UTR1-forward]:rna[GFP-forward]:rna[t16-forward]]+protein[Ribo] <--> ordered_polymer[rna[attB-reverse]:complex[protein[Ribo]:rna[UTR1]-forward]:rna[GFP-forward]:rna[t16-forward]]\\n Kf=k_forward * rna_attB_r_UTR1_f_GFP_f_t16_f * protein_Ribo\\n Kr=k_reverse * ordered_polymer_attB_r_protein_Ribo_rna_UTR1_f_GFP_f_t16_f\\n k_forward=100\\n found_key=(mech=None, partid=None, name=kb).\\n search_key=(mech=translation_mm, partid=UTR1, name=kb).\\n k_reverse=10\\n found_key=(mech=None, partid=None, name=ku).\\n search_key=(mech=translation_mm, partid=UTR1, name=ku).\\n\",\"ordered_polymer[rna[attB-reverse]:complex[protein[Ribo]:rna[UTR1]-forward]:rna[GFP-forward]:rna[t16-forward]] --> rna[rna[attB-reverse]:rna[UTR1-forward]:rna[GFP-forward]:rna[t16-forward]]+protein[GFP]+protein[Ribo]\\n Kf=k_forward * ordered_polymer_attB_r_protein_Ribo_rna_UTR1_f_GFP_f_t16_f\\n k_forward=0.2\\n found_key=(mech=None, partid=None, name=ktl).\\n search_key=(mech=translation_mm, partid=UTR1, name=ktl).\\n\",\"ordered_polymer[dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:[dna[attR]:2x_protein[Bxb1]-forward]:dna[pconst-reverse]:dna[attL-reverse]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]]+protein[RNAP] <--> ordered_polymer[dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:[dna[attR]:2x_protein[Bxb1]-forward]:complex[dna[pconst]:protein[RNAP]-reverse]:dna[attL-reverse]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]]\\n Kf=k_forward * ordered_polymer_t16_r_RFP_r_UTR1_r_dna_attR_protein_Bxb1_2x_f_pconst_r_attL_r_UTR1_f_GFP_f_t16_f * protein_RNAP\\n Kr=k_reverse * ordered_polymer_t16_r_RFP_r_UTR1_r_dna_attR_protein_Bxb1_2x_f_dna_pconst_protein_RNAP_r_attL_r_UTR1_f_GFP_f_t16_f\\n k_forward=100\\n found_key=(mech=None, partid=None, name=kb).\\n search_key=(mech=transcription_mm, partid=pconst, name=kb).\\n k_reverse=10\\n found_key=(mech=None, partid=None, name=ku).\\n search_key=(mech=transcription_mm, partid=pconst, name=ku).\\n\",\"ordered_polymer[dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:[dna[attR]:2x_protein[Bxb1]-forward]:complex[dna[pconst]:protein[RNAP]-reverse]:dna[attL-reverse]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]] --> ordered_polymer[dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:[dna[attR]:2x_protein[Bxb1]-forward]:dna[pconst-reverse]:dna[attL-reverse]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]]+rna[rna[attR-reverse]:rna[UTR1-forward]:rna[RFP-forward]:rna[t16-forward]]+protein[RNAP]\\n Kf=k_forward * ordered_polymer_t16_r_RFP_r_UTR1_r_dna_attR_protein_Bxb1_2x_f_dna_pconst_protein_RNAP_r_attL_r_UTR1_f_GFP_f_t16_f\\n k_forward=0.05\\n found_key=(mech=None, partid=None, name=ktx).\\n search_key=(mech=transcription_mm, partid=pconst, name=ktx).\\n\",\"2protein[Bxb1]+ordered_polymer[dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:[dna[attR]:2x_protein[Bxb1]-forward]:dna[pconst-reverse]:dna[attL-reverse]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]] <--> ordered_polymer[dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:[dna[attR]:2x_protein[Bxb1]-forward]:dna[pconst-reverse]:[dna[attL]:2x_protein[Bxb1]-reverse]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]]\\n Kf=k_forward * protein_Bxb1^2 * ordered_polymer_t16_r_RFP_r_UTR1_r_dna_attR_protein_Bxb1_2x_f_pconst_r_attL_r_UTR1_f_GFP_f_t16_f\\n Kr=k_reverse * ordered_polymer_t16_r_RFP_r_UTR1_r_dna_attR_protein_Bxb1_2x_f_pconst_r_dna_attL_protein_Bxb1_2x_r_UTR1_f_GFP_f_t16_f\\n k_forward=100\\n found_key=(mech=None, partid=None, name=kb).\\n search_key=(mech=one_step_cooperative_binding, partid=attL, name=kb).\\n k_reverse=10\\n found_key=(mech=None, partid=None, name=ku).\\n search_key=(mech=one_step_cooperative_binding, partid=attL, name=ku).\\n\",\"2protein[Bxb1]+ordered_polymer[dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:dna[attR-forward]:complex[dna[pconst]:protein[RNAP]-reverse]:dna[attL-reverse]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]] <--> ordered_polymer[dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:[dna[attR]:2x_protein[Bxb1]-forward]:complex[dna[pconst]:protein[RNAP]-reverse]:dna[attL-reverse]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]]\\n Kf=k_forward * protein_Bxb1^2 * ordered_polymer_t16_r_RFP_r_UTR1_r_attR_f_dna_pconst_protein_RNAP_r_attL_r_UTR1_f_GFP_f_t16_f\\n Kr=k_reverse * ordered_polymer_t16_r_RFP_r_UTR1_r_dna_attR_protein_Bxb1_2x_f_dna_pconst_protein_RNAP_r_attL_r_UTR1_f_GFP_f_t16_f\\n k_forward=100\\n found_key=(mech=None, partid=None, name=kb).\\n search_key=(mech=one_step_cooperative_binding, partid=attR, name=kb).\\n k_reverse=10\\n found_key=(mech=None, partid=None, name=ku).\\n search_key=(mech=one_step_cooperative_binding, partid=attR, name=ku).\\n\",\"2protein[Bxb1]+ordered_polymer[dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:dna[attR-forward]:complex[dna[pconst]:protein[RNAP]-reverse]:dna[attL-reverse]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]] <--> ordered_polymer[dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:dna[attR-forward]:complex[dna[pconst]:protein[RNAP]-reverse]:[dna[attL]:2x_protein[Bxb1]-reverse]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]]\\n Kf=k_forward * protein_Bxb1^2 * ordered_polymer_t16_r_RFP_r_UTR1_r_attR_f_dna_pconst_protein_RNAP_r_attL_r_UTR1_f_GFP_f_t16_f\\n Kr=k_reverse * ordered_polymer_t16_r_RFP_r_UTR1_r_attR_f_dna_pconst_protein_RNAP_r_dna_attL_protein_Bxb1_2x_r_UTR1_f_GFP_f_t16_f\\n k_forward=100\\n found_key=(mech=None, partid=None, name=kb).\\n search_key=(mech=one_step_cooperative_binding, partid=attL, name=kb).\\n k_reverse=10\\n found_key=(mech=None, partid=None, name=ku).\\n search_key=(mech=one_step_cooperative_binding, partid=attL, name=ku).\\n\",\"2protein[Bxb1]+ordered_polymer[dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:dna[attR-forward]:dna[pconst-reverse]:[dna[attL]:2x_protein[Bxb1]-reverse]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]] <--> ordered_polymer[dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:[dna[attR]:2x_protein[Bxb1]-forward]:dna[pconst-reverse]:[dna[attL]:2x_protein[Bxb1]-reverse]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]]\\n Kf=k_forward * protein_Bxb1^2 * ordered_polymer_t16_r_RFP_r_UTR1_r_attR_f_pconst_r_dna_attL_protein_Bxb1_2x_r_UTR1_f_GFP_f_t16_f\\n Kr=k_reverse * ordered_polymer_t16_r_RFP_r_UTR1_r_dna_attR_protein_Bxb1_2x_f_pconst_r_dna_attL_protein_Bxb1_2x_r_UTR1_f_GFP_f_t16_f\\n k_forward=100\\n found_key=(mech=None, partid=None, name=kb).\\n search_key=(mech=one_step_cooperative_binding, partid=attR, name=kb).\\n k_reverse=10\\n found_key=(mech=None, partid=None, name=ku).\\n search_key=(mech=one_step_cooperative_binding, partid=attR, name=ku).\\n\",\"ordered_polymer[dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:dna[attR-forward]:dna[pconst-reverse]:[dna[attL]:2x_protein[Bxb1]-reverse]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]]+protein[RNAP] <--> ordered_polymer[dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:dna[attR-forward]:complex[dna[pconst]:protein[RNAP]-reverse]:[dna[attL]:2x_protein[Bxb1]-reverse]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]]\\n Kf=k_forward * ordered_polymer_t16_r_RFP_r_UTR1_r_attR_f_pconst_r_dna_attL_protein_Bxb1_2x_r_UTR1_f_GFP_f_t16_f * protein_RNAP\\n Kr=k_reverse * ordered_polymer_t16_r_RFP_r_UTR1_r_attR_f_dna_pconst_protein_RNAP_r_dna_attL_protein_Bxb1_2x_r_UTR1_f_GFP_f_t16_f\\n k_forward=100\\n found_key=(mech=None, partid=None, name=kb).\\n search_key=(mech=transcription_mm, partid=pconst, name=kb).\\n k_reverse=10\\n found_key=(mech=None, partid=None, name=ku).\\n search_key=(mech=transcription_mm, partid=pconst, name=ku).\\n\",\"ordered_polymer[dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:dna[attR-forward]:complex[dna[pconst]:protein[RNAP]-reverse]:[dna[attL]:2x_protein[Bxb1]-reverse]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]] --> ordered_polymer[dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:dna[attR-forward]:dna[pconst-reverse]:[dna[attL]:2x_protein[Bxb1]-reverse]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]]+rna[rna[attR-reverse]:rna[UTR1-forward]:rna[RFP-forward]:rna[t16-forward]]+protein[RNAP]\\n Kf=k_forward * ordered_polymer_t16_r_RFP_r_UTR1_r_attR_f_dna_pconst_protein_RNAP_r_dna_attL_protein_Bxb1_2x_r_UTR1_f_GFP_f_t16_f\\n k_forward=0.05\\n found_key=(mech=None, partid=None, name=ktx).\\n search_key=(mech=transcription_mm, partid=pconst, name=ktx).\\n\",\"2protein[Bxb1]+ordered_polymer[dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:[dna[attR]:2x_protein[Bxb1]-forward]:complex[dna[pconst]:protein[RNAP]-reverse]:dna[attL-reverse]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]] <--> ordered_polymer[dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:[dna[attR]:2x_protein[Bxb1]-forward]:complex[dna[pconst]:protein[RNAP]-reverse]:[dna[attL]:2x_protein[Bxb1]-reverse]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]]\\n Kf=k_forward * protein_Bxb1^2 * ordered_polymer_t16_r_RFP_r_UTR1_r_dna_attR_protein_Bxb1_2x_f_dna_pconst_protein_RNAP_r_attL_r_UTR1_f_GFP_f_t16_f\\n Kr=k_reverse * ordered_polymer_t16_r_RFP_r_UTR1_r_dna_attR_protein_Bxb1_2x_f_dna_pconst_protein_RNAP_r_dna_attL_protein_Bxb1_2x_r_UTR1_f_GFP_f_t16_f\\n k_forward=100\\n found_key=(mech=None, partid=None, name=kb).\\n search_key=(mech=one_step_cooperative_binding, partid=attL, name=kb).\\n k_reverse=10\\n found_key=(mech=None, partid=None, name=ku).\\n search_key=(mech=one_step_cooperative_binding, partid=attL, name=ku).\\n\",\"ordered_polymer[dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:[dna[attR]:2x_protein[Bxb1]-forward]:dna[pconst-reverse]:[dna[attL]:2x_protein[Bxb1]-reverse]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]]+protein[RNAP] <--> ordered_polymer[dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:[dna[attR]:2x_protein[Bxb1]-forward]:complex[dna[pconst]:protein[RNAP]-reverse]:[dna[attL]:2x_protein[Bxb1]-reverse]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]]\\n Kf=k_forward * ordered_polymer_t16_r_RFP_r_UTR1_r_dna_attR_protein_Bxb1_2x_f_pconst_r_dna_attL_protein_Bxb1_2x_r_UTR1_f_GFP_f_t16_f * protein_RNAP\\n Kr=k_reverse * ordered_polymer_t16_r_RFP_r_UTR1_r_dna_attR_protein_Bxb1_2x_f_dna_pconst_protein_RNAP_r_dna_attL_protein_Bxb1_2x_r_UTR1_f_GFP_f_t16_f\\n k_forward=100\\n found_key=(mech=None, partid=None, name=kb).\\n search_key=(mech=transcription_mm, partid=pconst, name=kb).\\n k_reverse=10\\n found_key=(mech=None, partid=None, name=ku).\\n search_key=(mech=transcription_mm, partid=pconst, name=ku).\\n\",\"ordered_polymer[dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:[dna[attR]:2x_protein[Bxb1]-forward]:complex[dna[pconst]:protein[RNAP]-reverse]:[dna[attL]:2x_protein[Bxb1]-reverse]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]] --> ordered_polymer[dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:[dna[attR]:2x_protein[Bxb1]-forward]:dna[pconst-reverse]:[dna[attL]:2x_protein[Bxb1]-reverse]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]]+rna[rna[attR-reverse]:rna[UTR1-forward]:rna[RFP-forward]:rna[t16-forward]]+protein[RNAP]\\n Kf=k_forward * ordered_polymer_t16_r_RFP_r_UTR1_r_dna_attR_protein_Bxb1_2x_f_dna_pconst_protein_RNAP_r_dna_attL_protein_Bxb1_2x_r_UTR1_f_GFP_f_t16_f\\n k_forward=0.05\\n found_key=(mech=None, partid=None, name=ktx).\\n search_key=(mech=transcription_mm, partid=pconst, name=ktx).\\n\",\"2protein[Bxb1]+ordered_polymer[dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:dna[attR-forward]:complex[dna[pconst]:protein[RNAP]-reverse]:[dna[attL]:2x_protein[Bxb1]-reverse]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]] <--> ordered_polymer[dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:[dna[attR]:2x_protein[Bxb1]-forward]:complex[dna[pconst]:protein[RNAP]-reverse]:[dna[attL]:2x_protein[Bxb1]-reverse]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]]\\n Kf=k_forward * protein_Bxb1^2 * ordered_polymer_t16_r_RFP_r_UTR1_r_attR_f_dna_pconst_protein_RNAP_r_dna_attL_protein_Bxb1_2x_r_UTR1_f_GFP_f_t16_f\\n Kr=k_reverse * ordered_polymer_t16_r_RFP_r_UTR1_r_dna_attR_protein_Bxb1_2x_f_dna_pconst_protein_RNAP_r_dna_attL_protein_Bxb1_2x_r_UTR1_f_GFP_f_t16_f\\n k_forward=100\\n found_key=(mech=None, partid=None, name=kb).\\n search_key=(mech=one_step_cooperative_binding, partid=attR, name=kb).\\n k_reverse=10\\n found_key=(mech=None, partid=None, name=ku).\\n search_key=(mech=one_step_cooperative_binding, partid=attR, name=ku).\\n\",\"2protein[Bxb1]+dna[dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:dna[attR-forward]:dna[pconst-reverse]:dna[attL-reverse]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]] <--> ordered_polymer[dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:[dna[attR]:2x_protein[Bxb1]-forward]:dna[pconst-reverse]:dna[attL-reverse]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]]\\n Kf=k_forward * protein_Bxb1^2 * dna_t16_r_RFP_r_UTR1_r_attR_f_pconst_r_attL_r_UTR1_f_GFP_f_t16_f\\n Kr=k_reverse * ordered_polymer_t16_r_RFP_r_UTR1_r_dna_attR_protein_Bxb1_2x_f_pconst_r_attL_r_UTR1_f_GFP_f_t16_f\\n k_forward=100\\n found_key=(mech=None, partid=None, name=kb).\\n search_key=(mech=one_step_cooperative_binding, partid=attR, name=kb).\\n k_reverse=10\\n found_key=(mech=None, partid=None, name=ku).\\n search_key=(mech=one_step_cooperative_binding, partid=attR, name=ku).\\n\",\"dna[dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:dna[attR-forward]:dna[pconst-reverse]:dna[attL-reverse]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]]+protein[RNAP] <--> ordered_polymer[dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:dna[attR-forward]:complex[dna[pconst]:protein[RNAP]-reverse]:dna[attL-reverse]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]]\\n Kf=k_forward * dna_t16_r_RFP_r_UTR1_r_attR_f_pconst_r_attL_r_UTR1_f_GFP_f_t16_f * protein_RNAP\\n Kr=k_reverse * ordered_polymer_t16_r_RFP_r_UTR1_r_attR_f_dna_pconst_protein_RNAP_r_attL_r_UTR1_f_GFP_f_t16_f\\n k_forward=100\\n found_key=(mech=None, partid=None, name=kb).\\n search_key=(mech=transcription_mm, partid=pconst, name=kb).\\n k_reverse=10\\n found_key=(mech=None, partid=None, name=ku).\\n search_key=(mech=transcription_mm, partid=pconst, name=ku).\\n\",\"ordered_polymer[dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:dna[attR-forward]:complex[dna[pconst]:protein[RNAP]-reverse]:dna[attL-reverse]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]] --> dna[dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:dna[attR-forward]:dna[pconst-reverse]:dna[attL-reverse]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]]+rna[rna[attR-reverse]:rna[UTR1-forward]:rna[RFP-forward]:rna[t16-forward]]+protein[RNAP]\\n Kf=k_forward * ordered_polymer_t16_r_RFP_r_UTR1_r_attR_f_dna_pconst_protein_RNAP_r_attL_r_UTR1_f_GFP_f_t16_f\\n k_forward=0.05\\n found_key=(mech=None, partid=None, name=ktx).\\n search_key=(mech=transcription_mm, partid=pconst, name=ktx).\\n\",\"2protein[Bxb1]+dna[dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:dna[attR-forward]:dna[pconst-reverse]:dna[attL-reverse]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]] <--> ordered_polymer[dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:dna[attR-forward]:dna[pconst-reverse]:[dna[attL]:2x_protein[Bxb1]-reverse]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]]\\n Kf=k_forward * protein_Bxb1^2 * dna_t16_r_RFP_r_UTR1_r_attR_f_pconst_r_attL_r_UTR1_f_GFP_f_t16_f\\n Kr=k_reverse * ordered_polymer_t16_r_RFP_r_UTR1_r_attR_f_pconst_r_dna_attL_protein_Bxb1_2x_r_UTR1_f_GFP_f_t16_f\\n k_forward=100\\n found_key=(mech=None, partid=None, name=kb).\\n search_key=(mech=one_step_cooperative_binding, partid=attL, name=kb).\\n k_reverse=10\\n found_key=(mech=None, partid=None, name=ku).\\n search_key=(mech=one_step_cooperative_binding, partid=attL, name=ku).\\n\",\"rna[rna[attR-reverse]:rna[UTR1-forward]:rna[RFP-forward]:rna[t16-forward]]+protein[Ribo] <--> ordered_polymer[rna[attR-reverse]:complex[protein[Ribo]:rna[UTR1]-forward]:rna[RFP-forward]:rna[t16-forward]]\\n Kf=k_forward * rna_attR_r_UTR1_f_RFP_f_t16_f * protein_Ribo\\n Kr=k_reverse * ordered_polymer_attR_r_protein_Ribo_rna_UTR1_f_RFP_f_t16_f\\n k_forward=100\\n found_key=(mech=None, partid=None, name=kb).\\n search_key=(mech=translation_mm, partid=UTR1, name=kb).\\n k_reverse=10\\n found_key=(mech=None, partid=None, name=ku).\\n search_key=(mech=translation_mm, partid=UTR1, name=ku).\\n\",\"ordered_polymer[rna[attR-reverse]:complex[protein[Ribo]:rna[UTR1]-forward]:rna[RFP-forward]:rna[t16-forward]] --> rna[rna[attR-reverse]:rna[UTR1-forward]:rna[RFP-forward]:rna[t16-forward]]+protein[RFP]+protein[Ribo]\\n Kf=k_forward * ordered_polymer_attR_r_protein_Ribo_rna_UTR1_f_RFP_f_t16_f\\n k_forward=0.2\\n found_key=(mech=None, partid=None, name=ktl).\\n search_key=(mech=translation_mm, partid=UTR1, name=ktl).\\n\"],\"type\":[\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\"]},\"selected\":{\"id\":\"2288\",\"type\":\"Selection\"},\"selection_policy\":{\"id\":\"2287\",\"type\":\"UnionRenderers\"}},\"id\":\"2038\",\"type\":\"ColumnDataSource\"},{\"attributes\":{\"callback\":null,\"end\":248.99894223111477,\"start\":-218.96531015752072},\"id\":\"2111\",\"type\":\"Range1d\"},{\"attributes\":{\"callback\":null,\"data\":{\"color\":[\"purple\",\"grey\",\"orange\",\"white\",\"green\",\"grey\",\"grey\",\"lightgreen\",\"orange\",\"grey\",\"grey\",\"grey\",\"grey\",\"green\",\"white\",\"red\",\"grey\",\"grey\",\"green\",\"grey\",\"green\",\"grey\",\"grey\",\"grey\",\"grey\",\"grey\",\"grey\",\"blue\",\"blue\",\"blue\",\"blue\",\"blue\",\"blue\",\"blue\",\"blue\",\"blue\",\"blue\",\"blue\",\"blue\",\"blue\",\"blue\",\"blue\",\"blue\",\"blue\",\"blue\",\"blue\",\"blue\",\"blue\",\"blue\",\"blue\",\"blue\",\"blue\",\"blue\",\"blue\",\"blue\",\"blue\",\"blue\",\"blue\",\"blue\",\"blue\",\"blue\",\"blue\",\"blue\"],\"index\":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62],\"k\":[null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,\"100\",\"0.05\",\"100\",\"100\",\"100\",\"100\",\"100\",\"0.05\",\"100\",\"100\",\"0.05\",\"100\",\"100\",\"100\",\"0.05\",\"100\",\"100\",\"0.2\",\"100\",\"0.05\",\"100\",\"100\",\"100\",\"100\",\"100\",\"0.05\",\"100\",\"100\",\"0.05\",\"100\",\"100\",\"100\",\"0.05\",\"100\",\"100\",\"0.2\"],\"k_r\":[null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,\"10\",\"None\",\"10\",\"10\",\"10\",\"10\",\"10\",\"None\",\"10\",\"10\",\"None\",\"10\",\"10\",\"10\",\"None\",\"10\",\"10\",\"None\",\"10\",\"None\",\"10\",\"10\",\"10\",\"10\",\"10\",\"None\",\"10\",\"10\",\"None\",\"10\",\"10\",\"10\",\"None\",\"10\",\"10\",\"None\"],\"species\":[\"nothing\",\"ordered_polymer[dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:[dna[attR]:2x_protein[Bxb1]-forward]:dna[pconst-reverse]:[dna[attL]:2x_protein[Bxb1]-reverse]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]]\",\"rna[rna[attB-reverse]:rna[UTR1-forward]:rna[GFP-forward]:rna[t16-forward]]\",\"dna[dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:dna[attR-forward]:dna[pconst-reverse]:dna[attL-reverse]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]]\",\"protein[Bxb1]\",\"ordered_polymer[dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:dna[attR-forward]:dna[pconst-reverse]:[dna[attL]:2x_protein[Bxb1]-reverse]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]]\",\"ordered_polymer[dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:[dna[attP]:2x_protein[Bxb1]-forward]:complex[dna[pconst]:protein[RNAP]-forward]:[dna[attB]:2x_protein[Bxb1]-reverse]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]]\",\"protein[GFP]\",\"rna[rna[attR-reverse]:rna[UTR1-forward]:rna[RFP-forward]:rna[t16-forward]]\",\"ordered_polymer[rna[attR-reverse]:complex[protein[Ribo]:rna[UTR1]-forward]:rna[RFP-forward]:rna[t16-forward]]\",\"ordered_polymer[dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:dna[attP-forward]:complex[dna[pconst]:protein[RNAP]-forward]:dna[attB-reverse]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]]\",\"ordered_polymer[rna[attB-reverse]:complex[protein[Ribo]:rna[UTR1]-forward]:rna[GFP-forward]:rna[t16-forward]]\",\"ordered_polymer[dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:[dna[attR]:2x_protein[Bxb1]-forward]:complex[dna[pconst]:protein[RNAP]-reverse]:dna[attL-reverse]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]]\",\"protein[RNAP]\",\"dna[dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:dna[attP-forward]:dna[pconst-forward]:dna[attB-reverse]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]]\",\"protein[RFP]\",\"ordered_polymer[dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:dna[attP-forward]:complex[dna[pconst]:protein[RNAP]-forward]:[dna[attB]:2x_protein[Bxb1]-reverse]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]]\",\"ordered_polymer[dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:[dna[attP]:2x_protein[Bxb1]-forward]:dna[pconst-forward]:dna[attB-reverse]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]]\",\"protein[Ribo]\",\"ordered_polymer[dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:[dna[attR]:2x_protein[Bxb1]-forward]:complex[dna[pconst]:protein[RNAP]-reverse]:[dna[attL]:2x_protein[Bxb1]-reverse]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]]\",\"protein[RNAase]\",\"ordered_polymer[dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:[dna[attR]:2x_protein[Bxb1]-forward]:dna[pconst-reverse]:dna[attL-reverse]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]]\",\"ordered_polymer[dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:dna[attP-forward]:dna[pconst-forward]:[dna[attB]:2x_protein[Bxb1]-reverse]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]]\",\"ordered_polymer[dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:[dna[attP]:2x_protein[Bxb1]-forward]:dna[pconst-forward]:[dna[attB]:2x_protein[Bxb1]-reverse]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]]\",\"ordered_polymer[dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:dna[attR-forward]:complex[dna[pconst]:protein[RNAP]-reverse]:dna[attL-reverse]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]]\",\"ordered_polymer[dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:dna[attR-forward]:complex[dna[pconst]:protein[RNAP]-reverse]:[dna[attL]:2x_protein[Bxb1]-reverse]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]]\",\"ordered_polymer[dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:[dna[attP]:2x_protein[Bxb1]-forward]:complex[dna[pconst]:protein[RNAP]-forward]:dna[attB-reverse]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]]\",\"ordered_polymer[dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:[dna[attP]:2x_protein[Bxb1]-forward]:dna[pconst-forward]:dna[attB-reverse]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]]+protein[RNAP] <--> ordered_polymer[dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:[dna[attP]:2x_protein[Bxb1]-forward]:complex[dna[pconst]:protein[RNAP]-forward]:dna[attB-reverse]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]]\\n Kf=k_forward * ordered_polymer_t16_r_RFP_r_UTR1_r_dna_attP_protein_Bxb1_2x_f_pconst_f_attB_r_UTR1_f_GFP_f_t16_f * protein_RNAP\\n Kr=k_reverse * ordered_polymer_t16_r_RFP_r_UTR1_r_dna_attP_protein_Bxb1_2x_f_dna_pconst_protein_RNAP_f_attB_r_UTR1_f_GFP_f_t16_f\\n k_forward=100\\n found_key=(mech=None, partid=None, name=kb).\\n search_key=(mech=transcription_mm, partid=pconst, name=kb).\\n k_reverse=10\\n found_key=(mech=None, partid=None, name=ku).\\n search_key=(mech=transcription_mm, partid=pconst, name=ku).\\n\",\"ordered_polymer[dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:[dna[attP]:2x_protein[Bxb1]-forward]:complex[dna[pconst]:protein[RNAP]-forward]:dna[attB-reverse]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]] --> ordered_polymer[dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:[dna[attP]:2x_protein[Bxb1]-forward]:dna[pconst-forward]:dna[attB-reverse]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]]+rna[rna[attB-reverse]:rna[UTR1-forward]:rna[GFP-forward]:rna[t16-forward]]+protein[RNAP]\\n Kf=k_forward * ordered_polymer_t16_r_RFP_r_UTR1_r_dna_attP_protein_Bxb1_2x_f_dna_pconst_protein_RNAP_f_attB_r_UTR1_f_GFP_f_t16_f\\n k_forward=0.05\\n found_key=(mech=None, partid=None, name=ktx).\\n search_key=(mech=transcription_mm, partid=pconst, name=ktx).\\n\",\"2protein[Bxb1]+ordered_polymer[dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:[dna[attP]:2x_protein[Bxb1]-forward]:dna[pconst-forward]:dna[attB-reverse]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]] <--> ordered_polymer[dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:[dna[attP]:2x_protein[Bxb1]-forward]:dna[pconst-forward]:[dna[attB]:2x_protein[Bxb1]-reverse]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]]\\n Kf=k_forward * protein_Bxb1^2 * ordered_polymer_t16_r_RFP_r_UTR1_r_dna_attP_protein_Bxb1_2x_f_pconst_f_attB_r_UTR1_f_GFP_f_t16_f\\n Kr=k_reverse * ordered_polymer_t16_r_RFP_r_UTR1_r_dna_attP_protein_Bxb1_2x_f_pconst_f_dna_attB_protein_Bxb1_2x_r_UTR1_f_GFP_f_t16_f\\n k_forward=100\\n found_key=(mech=None, partid=None, name=kb).\\n search_key=(mech=one_step_cooperative_binding, partid=attB, name=kb).\\n k_reverse=10\\n found_key=(mech=None, partid=None, name=ku).\\n search_key=(mech=one_step_cooperative_binding, partid=attB, name=ku).\\n\",\"2protein[Bxb1]+ordered_polymer[dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:dna[attP-forward]:complex[dna[pconst]:protein[RNAP]-forward]:dna[attB-reverse]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]] <--> ordered_polymer[dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:[dna[attP]:2x_protein[Bxb1]-forward]:complex[dna[pconst]:protein[RNAP]-forward]:dna[attB-reverse]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]]\\n Kf=k_forward * protein_Bxb1^2 * ordered_polymer_t16_r_RFP_r_UTR1_r_attP_f_dna_pconst_protein_RNAP_f_attB_r_UTR1_f_GFP_f_t16_f\\n Kr=k_reverse * ordered_polymer_t16_r_RFP_r_UTR1_r_dna_attP_protein_Bxb1_2x_f_dna_pconst_protein_RNAP_f_attB_r_UTR1_f_GFP_f_t16_f\\n k_forward=100\\n found_key=(mech=None, partid=None, name=kb).\\n search_key=(mech=one_step_cooperative_binding, partid=attP, name=kb).\\n k_reverse=10\\n found_key=(mech=None, partid=None, name=ku).\\n search_key=(mech=one_step_cooperative_binding, partid=attP, name=ku).\\n\",\"2protein[Bxb1]+ordered_polymer[dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:dna[attP-forward]:complex[dna[pconst]:protein[RNAP]-forward]:dna[attB-reverse]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]] <--> ordered_polymer[dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:dna[attP-forward]:complex[dna[pconst]:protein[RNAP]-forward]:[dna[attB]:2x_protein[Bxb1]-reverse]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]]\\n Kf=k_forward * protein_Bxb1^2 * ordered_polymer_t16_r_RFP_r_UTR1_r_attP_f_dna_pconst_protein_RNAP_f_attB_r_UTR1_f_GFP_f_t16_f\\n Kr=k_reverse * ordered_polymer_t16_r_RFP_r_UTR1_r_attP_f_dna_pconst_protein_RNAP_f_dna_attB_protein_Bxb1_2x_r_UTR1_f_GFP_f_t16_f\\n k_forward=100\\n found_key=(mech=None, partid=None, name=kb).\\n search_key=(mech=one_step_cooperative_binding, partid=attB, name=kb).\\n k_reverse=10\\n found_key=(mech=None, partid=None, name=ku).\\n search_key=(mech=one_step_cooperative_binding, partid=attB, name=ku).\\n\",\"2protein[Bxb1]+ordered_polymer[dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:dna[attP-forward]:dna[pconst-forward]:[dna[attB]:2x_protein[Bxb1]-reverse]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]] <--> ordered_polymer[dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:[dna[attP]:2x_protein[Bxb1]-forward]:dna[pconst-forward]:[dna[attB]:2x_protein[Bxb1]-reverse]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]]\\n Kf=k_forward * protein_Bxb1^2 * ordered_polymer_t16_r_RFP_r_UTR1_r_attP_f_pconst_f_dna_attB_protein_Bxb1_2x_r_UTR1_f_GFP_f_t16_f\\n Kr=k_reverse * ordered_polymer_t16_r_RFP_r_UTR1_r_dna_attP_protein_Bxb1_2x_f_pconst_f_dna_attB_protein_Bxb1_2x_r_UTR1_f_GFP_f_t16_f\\n k_forward=100\\n found_key=(mech=None, partid=None, name=kb).\\n search_key=(mech=one_step_cooperative_binding, partid=attP, name=kb).\\n k_reverse=10\\n found_key=(mech=None, partid=None, name=ku).\\n search_key=(mech=one_step_cooperative_binding, partid=attP, name=ku).\\n\",\"ordered_polymer[dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:dna[attP-forward]:dna[pconst-forward]:[dna[attB]:2x_protein[Bxb1]-reverse]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]]+protein[RNAP] <--> ordered_polymer[dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:dna[attP-forward]:complex[dna[pconst]:protein[RNAP]-forward]:[dna[attB]:2x_protein[Bxb1]-reverse]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]]\\n Kf=k_forward * ordered_polymer_t16_r_RFP_r_UTR1_r_attP_f_pconst_f_dna_attB_protein_Bxb1_2x_r_UTR1_f_GFP_f_t16_f * protein_RNAP\\n Kr=k_reverse * ordered_polymer_t16_r_RFP_r_UTR1_r_attP_f_dna_pconst_protein_RNAP_f_dna_attB_protein_Bxb1_2x_r_UTR1_f_GFP_f_t16_f\\n k_forward=100\\n found_key=(mech=None, partid=None, name=kb).\\n search_key=(mech=transcription_mm, partid=pconst, name=kb).\\n k_reverse=10\\n found_key=(mech=None, partid=None, name=ku).\\n search_key=(mech=transcription_mm, partid=pconst, name=ku).\\n\",\"ordered_polymer[dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:dna[attP-forward]:complex[dna[pconst]:protein[RNAP]-forward]:[dna[attB]:2x_protein[Bxb1]-reverse]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]] --> ordered_polymer[dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:dna[attP-forward]:dna[pconst-forward]:[dna[attB]:2x_protein[Bxb1]-reverse]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]]+rna[rna[attB-reverse]:rna[UTR1-forward]:rna[GFP-forward]:rna[t16-forward]]+protein[RNAP]\\n Kf=k_forward * ordered_polymer_t16_r_RFP_r_UTR1_r_attP_f_dna_pconst_protein_RNAP_f_dna_attB_protein_Bxb1_2x_r_UTR1_f_GFP_f_t16_f\\n k_forward=0.05\\n found_key=(mech=None, partid=None, name=ktx).\\n search_key=(mech=transcription_mm, partid=pconst, name=ktx).\\n\",\"2protein[Bxb1]+ordered_polymer[dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:[dna[attP]:2x_protein[Bxb1]-forward]:complex[dna[pconst]:protein[RNAP]-forward]:dna[attB-reverse]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]] <--> ordered_polymer[dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:[dna[attP]:2x_protein[Bxb1]-forward]:complex[dna[pconst]:protein[RNAP]-forward]:[dna[attB]:2x_protein[Bxb1]-reverse]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]]\\n Kf=k_forward * protein_Bxb1^2 * ordered_polymer_t16_r_RFP_r_UTR1_r_dna_attP_protein_Bxb1_2x_f_dna_pconst_protein_RNAP_f_attB_r_UTR1_f_GFP_f_t16_f\\n Kr=k_reverse * ordered_polymer_t16_r_RFP_r_UTR1_r_dna_attP_protein_Bxb1_2x_f_dna_pconst_protein_RNAP_f_dna_attB_protein_Bxb1_2x_r_UTR1_f_GFP_f_t16_f\\n k_forward=100\\n found_key=(mech=None, partid=None, name=kb).\\n search_key=(mech=one_step_cooperative_binding, partid=attB, name=kb).\\n k_reverse=10\\n found_key=(mech=None, partid=None, name=ku).\\n search_key=(mech=one_step_cooperative_binding, partid=attB, name=ku).\\n\",\"ordered_polymer[dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:[dna[attP]:2x_protein[Bxb1]-forward]:dna[pconst-forward]:[dna[attB]:2x_protein[Bxb1]-reverse]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]]+protein[RNAP] <--> ordered_polymer[dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:[dna[attP]:2x_protein[Bxb1]-forward]:complex[dna[pconst]:protein[RNAP]-forward]:[dna[attB]:2x_protein[Bxb1]-reverse]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]]\\n Kf=k_forward * ordered_polymer_t16_r_RFP_r_UTR1_r_dna_attP_protein_Bxb1_2x_f_pconst_f_dna_attB_protein_Bxb1_2x_r_UTR1_f_GFP_f_t16_f * protein_RNAP\\n Kr=k_reverse * ordered_polymer_t16_r_RFP_r_UTR1_r_dna_attP_protein_Bxb1_2x_f_dna_pconst_protein_RNAP_f_dna_attB_protein_Bxb1_2x_r_UTR1_f_GFP_f_t16_f\\n k_forward=100\\n found_key=(mech=None, partid=None, name=kb).\\n search_key=(mech=transcription_mm, partid=pconst, name=kb).\\n k_reverse=10\\n found_key=(mech=None, partid=None, name=ku).\\n search_key=(mech=transcription_mm, partid=pconst, name=ku).\\n\",\"ordered_polymer[dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:[dna[attP]:2x_protein[Bxb1]-forward]:complex[dna[pconst]:protein[RNAP]-forward]:[dna[attB]:2x_protein[Bxb1]-reverse]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]] --> ordered_polymer[dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:[dna[attP]:2x_protein[Bxb1]-forward]:dna[pconst-forward]:[dna[attB]:2x_protein[Bxb1]-reverse]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]]+rna[rna[attB-reverse]:rna[UTR1-forward]:rna[GFP-forward]:rna[t16-forward]]+protein[RNAP]\\n Kf=k_forward * ordered_polymer_t16_r_RFP_r_UTR1_r_dna_attP_protein_Bxb1_2x_f_dna_pconst_protein_RNAP_f_dna_attB_protein_Bxb1_2x_r_UTR1_f_GFP_f_t16_f\\n k_forward=0.05\\n found_key=(mech=None, partid=None, name=ktx).\\n search_key=(mech=transcription_mm, partid=pconst, name=ktx).\\n\",\"2protein[Bxb1]+ordered_polymer[dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:dna[attP-forward]:complex[dna[pconst]:protein[RNAP]-forward]:[dna[attB]:2x_protein[Bxb1]-reverse]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]] <--> ordered_polymer[dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:[dna[attP]:2x_protein[Bxb1]-forward]:complex[dna[pconst]:protein[RNAP]-forward]:[dna[attB]:2x_protein[Bxb1]-reverse]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]]\\n Kf=k_forward * protein_Bxb1^2 * ordered_polymer_t16_r_RFP_r_UTR1_r_attP_f_dna_pconst_protein_RNAP_f_dna_attB_protein_Bxb1_2x_r_UTR1_f_GFP_f_t16_f\\n Kr=k_reverse * ordered_polymer_t16_r_RFP_r_UTR1_r_dna_attP_protein_Bxb1_2x_f_dna_pconst_protein_RNAP_f_dna_attB_protein_Bxb1_2x_r_UTR1_f_GFP_f_t16_f\\n k_forward=100\\n found_key=(mech=None, partid=None, name=kb).\\n search_key=(mech=one_step_cooperative_binding, partid=attP, name=kb).\\n k_reverse=10\\n found_key=(mech=None, partid=None, name=ku).\\n search_key=(mech=one_step_cooperative_binding, partid=attP, name=ku).\\n\",\"2protein[Bxb1]+dna[dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:dna[attP-forward]:dna[pconst-forward]:dna[attB-reverse]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]] <--> ordered_polymer[dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:[dna[attP]:2x_protein[Bxb1]-forward]:dna[pconst-forward]:dna[attB-reverse]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]]\\n Kf=k_forward * protein_Bxb1^2 * dna_t16_r_RFP_r_UTR1_r_attP_f_pconst_f_attB_r_UTR1_f_GFP_f_t16_f\\n Kr=k_reverse * ordered_polymer_t16_r_RFP_r_UTR1_r_dna_attP_protein_Bxb1_2x_f_pconst_f_attB_r_UTR1_f_GFP_f_t16_f\\n k_forward=100\\n found_key=(mech=None, partid=None, name=kb).\\n search_key=(mech=one_step_cooperative_binding, partid=attP, name=kb).\\n k_reverse=10\\n found_key=(mech=None, partid=None, name=ku).\\n search_key=(mech=one_step_cooperative_binding, partid=attP, name=ku).\\n\",\"dna[dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:dna[attP-forward]:dna[pconst-forward]:dna[attB-reverse]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]]+protein[RNAP] <--> ordered_polymer[dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:dna[attP-forward]:complex[dna[pconst]:protein[RNAP]-forward]:dna[attB-reverse]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]]\\n Kf=k_forward * dna_t16_r_RFP_r_UTR1_r_attP_f_pconst_f_attB_r_UTR1_f_GFP_f_t16_f * protein_RNAP\\n Kr=k_reverse * ordered_polymer_t16_r_RFP_r_UTR1_r_attP_f_dna_pconst_protein_RNAP_f_attB_r_UTR1_f_GFP_f_t16_f\\n k_forward=100\\n found_key=(mech=None, partid=None, name=kb).\\n search_key=(mech=transcription_mm, partid=pconst, name=kb).\\n k_reverse=10\\n found_key=(mech=None, partid=None, name=ku).\\n search_key=(mech=transcription_mm, partid=pconst, name=ku).\\n\",\"ordered_polymer[dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:dna[attP-forward]:complex[dna[pconst]:protein[RNAP]-forward]:dna[attB-reverse]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]] --> dna[dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:dna[attP-forward]:dna[pconst-forward]:dna[attB-reverse]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]]+rna[rna[attB-reverse]:rna[UTR1-forward]:rna[GFP-forward]:rna[t16-forward]]+protein[RNAP]\\n Kf=k_forward * ordered_polymer_t16_r_RFP_r_UTR1_r_attP_f_dna_pconst_protein_RNAP_f_attB_r_UTR1_f_GFP_f_t16_f\\n k_forward=0.05\\n found_key=(mech=None, partid=None, name=ktx).\\n search_key=(mech=transcription_mm, partid=pconst, name=ktx).\\n\",\"2protein[Bxb1]+dna[dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:dna[attP-forward]:dna[pconst-forward]:dna[attB-reverse]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]] <--> ordered_polymer[dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:dna[attP-forward]:dna[pconst-forward]:[dna[attB]:2x_protein[Bxb1]-reverse]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]]\\n Kf=k_forward * protein_Bxb1^2 * dna_t16_r_RFP_r_UTR1_r_attP_f_pconst_f_attB_r_UTR1_f_GFP_f_t16_f\\n Kr=k_reverse * ordered_polymer_t16_r_RFP_r_UTR1_r_attP_f_pconst_f_dna_attB_protein_Bxb1_2x_r_UTR1_f_GFP_f_t16_f\\n k_forward=100\\n found_key=(mech=None, partid=None, name=kb).\\n search_key=(mech=one_step_cooperative_binding, partid=attB, name=kb).\\n k_reverse=10\\n found_key=(mech=None, partid=None, name=ku).\\n search_key=(mech=one_step_cooperative_binding, partid=attB, name=ku).\\n\",\"rna[rna[attB-reverse]:rna[UTR1-forward]:rna[GFP-forward]:rna[t16-forward]]+protein[Ribo] <--> ordered_polymer[rna[attB-reverse]:complex[protein[Ribo]:rna[UTR1]-forward]:rna[GFP-forward]:rna[t16-forward]]\\n Kf=k_forward * rna_attB_r_UTR1_f_GFP_f_t16_f * protein_Ribo\\n Kr=k_reverse * ordered_polymer_attB_r_protein_Ribo_rna_UTR1_f_GFP_f_t16_f\\n k_forward=100\\n found_key=(mech=None, partid=None, name=kb).\\n search_key=(mech=translation_mm, partid=UTR1, name=kb).\\n k_reverse=10\\n found_key=(mech=None, partid=None, name=ku).\\n search_key=(mech=translation_mm, partid=UTR1, name=ku).\\n\",\"ordered_polymer[rna[attB-reverse]:complex[protein[Ribo]:rna[UTR1]-forward]:rna[GFP-forward]:rna[t16-forward]] --> rna[rna[attB-reverse]:rna[UTR1-forward]:rna[GFP-forward]:rna[t16-forward]]+protein[GFP]+protein[Ribo]\\n Kf=k_forward * ordered_polymer_attB_r_protein_Ribo_rna_UTR1_f_GFP_f_t16_f\\n k_forward=0.2\\n found_key=(mech=None, partid=None, name=ktl).\\n search_key=(mech=translation_mm, partid=UTR1, name=ktl).\\n\",\"ordered_polymer[dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:[dna[attR]:2x_protein[Bxb1]-forward]:dna[pconst-reverse]:dna[attL-reverse]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]]+protein[RNAP] <--> ordered_polymer[dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:[dna[attR]:2x_protein[Bxb1]-forward]:complex[dna[pconst]:protein[RNAP]-reverse]:dna[attL-reverse]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]]\\n Kf=k_forward * ordered_polymer_t16_r_RFP_r_UTR1_r_dna_attR_protein_Bxb1_2x_f_pconst_r_attL_r_UTR1_f_GFP_f_t16_f * protein_RNAP\\n Kr=k_reverse * ordered_polymer_t16_r_RFP_r_UTR1_r_dna_attR_protein_Bxb1_2x_f_dna_pconst_protein_RNAP_r_attL_r_UTR1_f_GFP_f_t16_f\\n k_forward=100\\n found_key=(mech=None, partid=None, name=kb).\\n search_key=(mech=transcription_mm, partid=pconst, name=kb).\\n k_reverse=10\\n found_key=(mech=None, partid=None, name=ku).\\n search_key=(mech=transcription_mm, partid=pconst, name=ku).\\n\",\"ordered_polymer[dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:[dna[attR]:2x_protein[Bxb1]-forward]:complex[dna[pconst]:protein[RNAP]-reverse]:dna[attL-reverse]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]] --> ordered_polymer[dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:[dna[attR]:2x_protein[Bxb1]-forward]:dna[pconst-reverse]:dna[attL-reverse]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]]+rna[rna[attR-reverse]:rna[UTR1-forward]:rna[RFP-forward]:rna[t16-forward]]+protein[RNAP]\\n Kf=k_forward * ordered_polymer_t16_r_RFP_r_UTR1_r_dna_attR_protein_Bxb1_2x_f_dna_pconst_protein_RNAP_r_attL_r_UTR1_f_GFP_f_t16_f\\n k_forward=0.05\\n found_key=(mech=None, partid=None, name=ktx).\\n search_key=(mech=transcription_mm, partid=pconst, name=ktx).\\n\",\"2protein[Bxb1]+ordered_polymer[dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:[dna[attR]:2x_protein[Bxb1]-forward]:dna[pconst-reverse]:dna[attL-reverse]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]] <--> ordered_polymer[dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:[dna[attR]:2x_protein[Bxb1]-forward]:dna[pconst-reverse]:[dna[attL]:2x_protein[Bxb1]-reverse]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]]\\n Kf=k_forward * protein_Bxb1^2 * ordered_polymer_t16_r_RFP_r_UTR1_r_dna_attR_protein_Bxb1_2x_f_pconst_r_attL_r_UTR1_f_GFP_f_t16_f\\n Kr=k_reverse * ordered_polymer_t16_r_RFP_r_UTR1_r_dna_attR_protein_Bxb1_2x_f_pconst_r_dna_attL_protein_Bxb1_2x_r_UTR1_f_GFP_f_t16_f\\n k_forward=100\\n found_key=(mech=None, partid=None, name=kb).\\n search_key=(mech=one_step_cooperative_binding, partid=attL, name=kb).\\n k_reverse=10\\n found_key=(mech=None, partid=None, name=ku).\\n search_key=(mech=one_step_cooperative_binding, partid=attL, name=ku).\\n\",\"2protein[Bxb1]+ordered_polymer[dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:dna[attR-forward]:complex[dna[pconst]:protein[RNAP]-reverse]:dna[attL-reverse]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]] <--> ordered_polymer[dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:[dna[attR]:2x_protein[Bxb1]-forward]:complex[dna[pconst]:protein[RNAP]-reverse]:dna[attL-reverse]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]]\\n Kf=k_forward * protein_Bxb1^2 * ordered_polymer_t16_r_RFP_r_UTR1_r_attR_f_dna_pconst_protein_RNAP_r_attL_r_UTR1_f_GFP_f_t16_f\\n Kr=k_reverse * ordered_polymer_t16_r_RFP_r_UTR1_r_dna_attR_protein_Bxb1_2x_f_dna_pconst_protein_RNAP_r_attL_r_UTR1_f_GFP_f_t16_f\\n k_forward=100\\n found_key=(mech=None, partid=None, name=kb).\\n search_key=(mech=one_step_cooperative_binding, partid=attR, name=kb).\\n k_reverse=10\\n found_key=(mech=None, partid=None, name=ku).\\n search_key=(mech=one_step_cooperative_binding, partid=attR, name=ku).\\n\",\"2protein[Bxb1]+ordered_polymer[dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:dna[attR-forward]:complex[dna[pconst]:protein[RNAP]-reverse]:dna[attL-reverse]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]] <--> ordered_polymer[dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:dna[attR-forward]:complex[dna[pconst]:protein[RNAP]-reverse]:[dna[attL]:2x_protein[Bxb1]-reverse]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]]\\n Kf=k_forward * protein_Bxb1^2 * ordered_polymer_t16_r_RFP_r_UTR1_r_attR_f_dna_pconst_protein_RNAP_r_attL_r_UTR1_f_GFP_f_t16_f\\n Kr=k_reverse * ordered_polymer_t16_r_RFP_r_UTR1_r_attR_f_dna_pconst_protein_RNAP_r_dna_attL_protein_Bxb1_2x_r_UTR1_f_GFP_f_t16_f\\n k_forward=100\\n found_key=(mech=None, partid=None, name=kb).\\n search_key=(mech=one_step_cooperative_binding, partid=attL, name=kb).\\n k_reverse=10\\n found_key=(mech=None, partid=None, name=ku).\\n search_key=(mech=one_step_cooperative_binding, partid=attL, name=ku).\\n\",\"2protein[Bxb1]+ordered_polymer[dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:dna[attR-forward]:dna[pconst-reverse]:[dna[attL]:2x_protein[Bxb1]-reverse]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]] <--> ordered_polymer[dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:[dna[attR]:2x_protein[Bxb1]-forward]:dna[pconst-reverse]:[dna[attL]:2x_protein[Bxb1]-reverse]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]]\\n Kf=k_forward * protein_Bxb1^2 * ordered_polymer_t16_r_RFP_r_UTR1_r_attR_f_pconst_r_dna_attL_protein_Bxb1_2x_r_UTR1_f_GFP_f_t16_f\\n Kr=k_reverse * ordered_polymer_t16_r_RFP_r_UTR1_r_dna_attR_protein_Bxb1_2x_f_pconst_r_dna_attL_protein_Bxb1_2x_r_UTR1_f_GFP_f_t16_f\\n k_forward=100\\n found_key=(mech=None, partid=None, name=kb).\\n search_key=(mech=one_step_cooperative_binding, partid=attR, name=kb).\\n k_reverse=10\\n found_key=(mech=None, partid=None, name=ku).\\n search_key=(mech=one_step_cooperative_binding, partid=attR, name=ku).\\n\",\"ordered_polymer[dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:dna[attR-forward]:dna[pconst-reverse]:[dna[attL]:2x_protein[Bxb1]-reverse]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]]+protein[RNAP] <--> ordered_polymer[dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:dna[attR-forward]:complex[dna[pconst]:protein[RNAP]-reverse]:[dna[attL]:2x_protein[Bxb1]-reverse]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]]\\n Kf=k_forward * ordered_polymer_t16_r_RFP_r_UTR1_r_attR_f_pconst_r_dna_attL_protein_Bxb1_2x_r_UTR1_f_GFP_f_t16_f * protein_RNAP\\n Kr=k_reverse * ordered_polymer_t16_r_RFP_r_UTR1_r_attR_f_dna_pconst_protein_RNAP_r_dna_attL_protein_Bxb1_2x_r_UTR1_f_GFP_f_t16_f\\n k_forward=100\\n found_key=(mech=None, partid=None, name=kb).\\n search_key=(mech=transcription_mm, partid=pconst, name=kb).\\n k_reverse=10\\n found_key=(mech=None, partid=None, name=ku).\\n search_key=(mech=transcription_mm, partid=pconst, name=ku).\\n\",\"ordered_polymer[dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:dna[attR-forward]:complex[dna[pconst]:protein[RNAP]-reverse]:[dna[attL]:2x_protein[Bxb1]-reverse]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]] --> ordered_polymer[dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:dna[attR-forward]:dna[pconst-reverse]:[dna[attL]:2x_protein[Bxb1]-reverse]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]]+rna[rna[attR-reverse]:rna[UTR1-forward]:rna[RFP-forward]:rna[t16-forward]]+protein[RNAP]\\n Kf=k_forward * ordered_polymer_t16_r_RFP_r_UTR1_r_attR_f_dna_pconst_protein_RNAP_r_dna_attL_protein_Bxb1_2x_r_UTR1_f_GFP_f_t16_f\\n k_forward=0.05\\n found_key=(mech=None, partid=None, name=ktx).\\n search_key=(mech=transcription_mm, partid=pconst, name=ktx).\\n\",\"2protein[Bxb1]+ordered_polymer[dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:[dna[attR]:2x_protein[Bxb1]-forward]:complex[dna[pconst]:protein[RNAP]-reverse]:dna[attL-reverse]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]] <--> ordered_polymer[dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:[dna[attR]:2x_protein[Bxb1]-forward]:complex[dna[pconst]:protein[RNAP]-reverse]:[dna[attL]:2x_protein[Bxb1]-reverse]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]]\\n Kf=k_forward * protein_Bxb1^2 * ordered_polymer_t16_r_RFP_r_UTR1_r_dna_attR_protein_Bxb1_2x_f_dna_pconst_protein_RNAP_r_attL_r_UTR1_f_GFP_f_t16_f\\n Kr=k_reverse * ordered_polymer_t16_r_RFP_r_UTR1_r_dna_attR_protein_Bxb1_2x_f_dna_pconst_protein_RNAP_r_dna_attL_protein_Bxb1_2x_r_UTR1_f_GFP_f_t16_f\\n k_forward=100\\n found_key=(mech=None, partid=None, name=kb).\\n search_key=(mech=one_step_cooperative_binding, partid=attL, name=kb).\\n k_reverse=10\\n found_key=(mech=None, partid=None, name=ku).\\n search_key=(mech=one_step_cooperative_binding, partid=attL, name=ku).\\n\",\"ordered_polymer[dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:[dna[attR]:2x_protein[Bxb1]-forward]:dna[pconst-reverse]:[dna[attL]:2x_protein[Bxb1]-reverse]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]]+protein[RNAP] <--> ordered_polymer[dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:[dna[attR]:2x_protein[Bxb1]-forward]:complex[dna[pconst]:protein[RNAP]-reverse]:[dna[attL]:2x_protein[Bxb1]-reverse]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]]\\n Kf=k_forward * ordered_polymer_t16_r_RFP_r_UTR1_r_dna_attR_protein_Bxb1_2x_f_pconst_r_dna_attL_protein_Bxb1_2x_r_UTR1_f_GFP_f_t16_f * protein_RNAP\\n Kr=k_reverse * ordered_polymer_t16_r_RFP_r_UTR1_r_dna_attR_protein_Bxb1_2x_f_dna_pconst_protein_RNAP_r_dna_attL_protein_Bxb1_2x_r_UTR1_f_GFP_f_t16_f\\n k_forward=100\\n found_key=(mech=None, partid=None, name=kb).\\n search_key=(mech=transcription_mm, partid=pconst, name=kb).\\n k_reverse=10\\n found_key=(mech=None, partid=None, name=ku).\\n search_key=(mech=transcription_mm, partid=pconst, name=ku).\\n\",\"ordered_polymer[dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:[dna[attR]:2x_protein[Bxb1]-forward]:complex[dna[pconst]:protein[RNAP]-reverse]:[dna[attL]:2x_protein[Bxb1]-reverse]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]] --> ordered_polymer[dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:[dna[attR]:2x_protein[Bxb1]-forward]:dna[pconst-reverse]:[dna[attL]:2x_protein[Bxb1]-reverse]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]]+rna[rna[attR-reverse]:rna[UTR1-forward]:rna[RFP-forward]:rna[t16-forward]]+protein[RNAP]\\n Kf=k_forward * ordered_polymer_t16_r_RFP_r_UTR1_r_dna_attR_protein_Bxb1_2x_f_dna_pconst_protein_RNAP_r_dna_attL_protein_Bxb1_2x_r_UTR1_f_GFP_f_t16_f\\n k_forward=0.05\\n found_key=(mech=None, partid=None, name=ktx).\\n search_key=(mech=transcription_mm, partid=pconst, name=ktx).\\n\",\"2protein[Bxb1]+ordered_polymer[dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:dna[attR-forward]:complex[dna[pconst]:protein[RNAP]-reverse]:[dna[attL]:2x_protein[Bxb1]-reverse]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]] <--> ordered_polymer[dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:[dna[attR]:2x_protein[Bxb1]-forward]:complex[dna[pconst]:protein[RNAP]-reverse]:[dna[attL]:2x_protein[Bxb1]-reverse]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]]\\n Kf=k_forward * protein_Bxb1^2 * ordered_polymer_t16_r_RFP_r_UTR1_r_attR_f_dna_pconst_protein_RNAP_r_dna_attL_protein_Bxb1_2x_r_UTR1_f_GFP_f_t16_f\\n Kr=k_reverse * ordered_polymer_t16_r_RFP_r_UTR1_r_dna_attR_protein_Bxb1_2x_f_dna_pconst_protein_RNAP_r_dna_attL_protein_Bxb1_2x_r_UTR1_f_GFP_f_t16_f\\n k_forward=100\\n found_key=(mech=None, partid=None, name=kb).\\n search_key=(mech=one_step_cooperative_binding, partid=attR, name=kb).\\n k_reverse=10\\n found_key=(mech=None, partid=None, name=ku).\\n search_key=(mech=one_step_cooperative_binding, partid=attR, name=ku).\\n\",\"2protein[Bxb1]+dna[dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:dna[attR-forward]:dna[pconst-reverse]:dna[attL-reverse]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]] <--> ordered_polymer[dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:[dna[attR]:2x_protein[Bxb1]-forward]:dna[pconst-reverse]:dna[attL-reverse]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]]\\n Kf=k_forward * protein_Bxb1^2 * dna_t16_r_RFP_r_UTR1_r_attR_f_pconst_r_attL_r_UTR1_f_GFP_f_t16_f\\n Kr=k_reverse * ordered_polymer_t16_r_RFP_r_UTR1_r_dna_attR_protein_Bxb1_2x_f_pconst_r_attL_r_UTR1_f_GFP_f_t16_f\\n k_forward=100\\n found_key=(mech=None, partid=None, name=kb).\\n search_key=(mech=one_step_cooperative_binding, partid=attR, name=kb).\\n k_reverse=10\\n found_key=(mech=None, partid=None, name=ku).\\n search_key=(mech=one_step_cooperative_binding, partid=attR, name=ku).\\n\",\"dna[dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:dna[attR-forward]:dna[pconst-reverse]:dna[attL-reverse]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]]+protein[RNAP] <--> ordered_polymer[dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:dna[attR-forward]:complex[dna[pconst]:protein[RNAP]-reverse]:dna[attL-reverse]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]]\\n Kf=k_forward * dna_t16_r_RFP_r_UTR1_r_attR_f_pconst_r_attL_r_UTR1_f_GFP_f_t16_f * protein_RNAP\\n Kr=k_reverse * ordered_polymer_t16_r_RFP_r_UTR1_r_attR_f_dna_pconst_protein_RNAP_r_attL_r_UTR1_f_GFP_f_t16_f\\n k_forward=100\\n found_key=(mech=None, partid=None, name=kb).\\n search_key=(mech=transcription_mm, partid=pconst, name=kb).\\n k_reverse=10\\n found_key=(mech=None, partid=None, name=ku).\\n search_key=(mech=transcription_mm, partid=pconst, name=ku).\\n\",\"ordered_polymer[dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:dna[attR-forward]:complex[dna[pconst]:protein[RNAP]-reverse]:dna[attL-reverse]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]] --> dna[dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:dna[attR-forward]:dna[pconst-reverse]:dna[attL-reverse]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]]+rna[rna[attR-reverse]:rna[UTR1-forward]:rna[RFP-forward]:rna[t16-forward]]+protein[RNAP]\\n Kf=k_forward * ordered_polymer_t16_r_RFP_r_UTR1_r_attR_f_dna_pconst_protein_RNAP_r_attL_r_UTR1_f_GFP_f_t16_f\\n k_forward=0.05\\n found_key=(mech=None, partid=None, name=ktx).\\n search_key=(mech=transcription_mm, partid=pconst, name=ktx).\\n\",\"2protein[Bxb1]+dna[dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:dna[attR-forward]:dna[pconst-reverse]:dna[attL-reverse]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]] <--> ordered_polymer[dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:dna[attR-forward]:dna[pconst-reverse]:[dna[attL]:2x_protein[Bxb1]-reverse]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]]\\n Kf=k_forward * protein_Bxb1^2 * dna_t16_r_RFP_r_UTR1_r_attR_f_pconst_r_attL_r_UTR1_f_GFP_f_t16_f\\n Kr=k_reverse * ordered_polymer_t16_r_RFP_r_UTR1_r_attR_f_pconst_r_dna_attL_protein_Bxb1_2x_r_UTR1_f_GFP_f_t16_f\\n k_forward=100\\n found_key=(mech=None, partid=None, name=kb).\\n search_key=(mech=one_step_cooperative_binding, partid=attL, name=kb).\\n k_reverse=10\\n found_key=(mech=None, partid=None, name=ku).\\n search_key=(mech=one_step_cooperative_binding, partid=attL, name=ku).\\n\",\"rna[rna[attR-reverse]:rna[UTR1-forward]:rna[RFP-forward]:rna[t16-forward]]+protein[Ribo] <--> ordered_polymer[rna[attR-reverse]:complex[protein[Ribo]:rna[UTR1]-forward]:rna[RFP-forward]:rna[t16-forward]]\\n Kf=k_forward * rna_attR_r_UTR1_f_RFP_f_t16_f * protein_Ribo\\n Kr=k_reverse * ordered_polymer_attR_r_protein_Ribo_rna_UTR1_f_RFP_f_t16_f\\n k_forward=100\\n found_key=(mech=None, partid=None, name=kb).\\n search_key=(mech=translation_mm, partid=UTR1, name=kb).\\n k_reverse=10\\n found_key=(mech=None, partid=None, name=ku).\\n search_key=(mech=translation_mm, partid=UTR1, name=ku).\\n\",\"ordered_polymer[rna[attR-reverse]:complex[protein[Ribo]:rna[UTR1]-forward]:rna[RFP-forward]:rna[t16-forward]] --> rna[rna[attR-reverse]:rna[UTR1-forward]:rna[RFP-forward]:rna[t16-forward]]+protein[RFP]+protein[Ribo]\\n Kf=k_forward * ordered_polymer_attR_r_protein_Ribo_rna_UTR1_f_RFP_f_t16_f\\n k_forward=0.2\\n found_key=(mech=None, partid=None, name=ktl).\\n search_key=(mech=translation_mm, partid=UTR1, name=ktl).\\n\"],\"type\":[\"nothing\",\"ordered_polymer\",\"rna\",\"dna\",\"protein\",\"ordered_polymer\",\"ordered_polymer\",\"protein\",\"rna\",\"ordered_polymer\",\"ordered_polymer\",\"ordered_polymer\",\"ordered_polymer\",\"protein\",\"dna\",\"protein\",\"ordered_polymer\",\"ordered_polymer\",\"protein\",\"ordered_polymer\",\"protein\",\"ordered_polymer\",\"ordered_polymer\",\"ordered_polymer\",\"ordered_polymer\",\"ordered_polymer\",\"ordered_polymer\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\"]},\"selected\":{\"id\":\"2284\",\"type\":\"Selection\"},\"selection_policy\":{\"id\":\"2283\",\"type\":\"UnionRenderers\"}},\"id\":\"2070\",\"type\":\"ColumnDataSource\"},{\"attributes\":{\"callback\":null,\"data\":{\"color\":[\"purple\",\"grey\",\"orange\",\"white\",\"green\",\"grey\",\"grey\",\"lightgreen\",\"orange\",\"grey\",\"grey\",\"grey\",\"grey\",\"green\",\"white\",\"red\",\"grey\",\"grey\",\"green\",\"grey\",\"green\",\"grey\",\"grey\",\"grey\",\"grey\",\"grey\",\"grey\"],\"index\":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26],\"species\":[\"nothing\",\"ordered_polymer[dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:[dna[attR]:2x_protein[Bxb1]-forward]:dna[pconst-reverse]:[dna[attL]:2x_protein[Bxb1]-reverse]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]]\",\"rna[rna[attB-reverse]:rna[UTR1-forward]:rna[GFP-forward]:rna[t16-forward]]\",\"dna[dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:dna[attR-forward]:dna[pconst-reverse]:dna[attL-reverse]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]]\",\"protein[Bxb1]\",\"ordered_polymer[dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:dna[attR-forward]:dna[pconst-reverse]:[dna[attL]:2x_protein[Bxb1]-reverse]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]]\",\"ordered_polymer[dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:[dna[attP]:2x_protein[Bxb1]-forward]:complex[dna[pconst]:protein[RNAP]-forward]:[dna[attB]:2x_protein[Bxb1]-reverse]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]]\",\"protein[GFP]\",\"rna[rna[attR-reverse]:rna[UTR1-forward]:rna[RFP-forward]:rna[t16-forward]]\",\"ordered_polymer[rna[attR-reverse]:complex[protein[Ribo]:rna[UTR1]-forward]:rna[RFP-forward]:rna[t16-forward]]\",\"ordered_polymer[dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:dna[attP-forward]:complex[dna[pconst]:protein[RNAP]-forward]:dna[attB-reverse]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]]\",\"ordered_polymer[rna[attB-reverse]:complex[protein[Ribo]:rna[UTR1]-forward]:rna[GFP-forward]:rna[t16-forward]]\",\"ordered_polymer[dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:[dna[attR]:2x_protein[Bxb1]-forward]:complex[dna[pconst]:protein[RNAP]-reverse]:dna[attL-reverse]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]]\",\"protein[RNAP]\",\"dna[dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:dna[attP-forward]:dna[pconst-forward]:dna[attB-reverse]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]]\",\"protein[RFP]\",\"ordered_polymer[dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:dna[attP-forward]:complex[dna[pconst]:protein[RNAP]-forward]:[dna[attB]:2x_protein[Bxb1]-reverse]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]]\",\"ordered_polymer[dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:[dna[attP]:2x_protein[Bxb1]-forward]:dna[pconst-forward]:dna[attB-reverse]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]]\",\"protein[Ribo]\",\"ordered_polymer[dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:[dna[attR]:2x_protein[Bxb1]-forward]:complex[dna[pconst]:protein[RNAP]-reverse]:[dna[attL]:2x_protein[Bxb1]-reverse]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]]\",\"protein[RNAase]\",\"ordered_polymer[dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:[dna[attR]:2x_protein[Bxb1]-forward]:dna[pconst-reverse]:dna[attL-reverse]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]]\",\"ordered_polymer[dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:dna[attP-forward]:dna[pconst-forward]:[dna[attB]:2x_protein[Bxb1]-reverse]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]]\",\"ordered_polymer[dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:[dna[attP]:2x_protein[Bxb1]-forward]:dna[pconst-forward]:[dna[attB]:2x_protein[Bxb1]-reverse]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]]\",\"ordered_polymer[dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:dna[attR-forward]:complex[dna[pconst]:protein[RNAP]-reverse]:dna[attL-reverse]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]]\",\"ordered_polymer[dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:dna[attR-forward]:complex[dna[pconst]:protein[RNAP]-reverse]:[dna[attL]:2x_protein[Bxb1]-reverse]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]]\",\"ordered_polymer[dna[t16-reverse]:dna[RFP-reverse]:dna[UTR1-reverse]:[dna[attP]:2x_protein[Bxb1]-forward]:complex[dna[pconst]:protein[RNAP]-forward]:dna[attB-reverse]:dna[UTR1-forward]:dna[GFP-forward]:dna[t16-forward]]\"],\"type\":[\"nothing\",\"ordered_polymer\",\"rna\",\"dna\",\"protein\",\"ordered_polymer\",\"ordered_polymer\",\"protein\",\"rna\",\"ordered_polymer\",\"ordered_polymer\",\"ordered_polymer\",\"ordered_polymer\",\"protein\",\"dna\",\"protein\",\"ordered_polymer\",\"ordered_polymer\",\"protein\",\"ordered_polymer\",\"protein\",\"ordered_polymer\",\"ordered_polymer\",\"ordered_polymer\",\"ordered_polymer\",\"ordered_polymer\",\"ordered_polymer\"]},\"selected\":{\"id\":\"2292\",\"type\":\"Selection\"},\"selection_policy\":{\"id\":\"2291\",\"type\":\"UnionRenderers\"}},\"id\":\"2054\",\"type\":\"ColumnDataSource\"}],\"root_ids\":[\"2031\"]},\"title\":\"Bokeh Application\",\"version\":\"1.4.0\"}};\n var render_items = [{\"docid\":\"536c913c-73cc-42a7-939f-583c0cbb3df0\",\"roots\":{\"2031\":\"16bbfee1-9e0e-4792-a250-eff3ed675d99\"}}];\n root.Bokeh.embed.embed_items_notebook(docs_json, render_items);\n\n }\n if (root.Bokeh !== undefined) {\n embed_document(root);\n } else {\n var attempts = 0;\n var timer = setInterval(function(root) {\n if (root.Bokeh !== undefined) {\n clearInterval(timer);\n embed_document(root);\n } else {\n attempts++;\n if (attempts > 100) {\n clearInterval(timer);\n console.log(\"Bokeh: ERROR: Unable to run BokehJS code because BokehJS library is missing\");\n }\n }\n }, 10, root)\n }\n})(window);", + "application/vnd.bokehjs_exec.v0+json": "" + }, + "metadata": { + "application/vnd.bokehjs_exec.v0+json": { + "id": "2031" + } + } + } + ], + "source": [ + "\n", + "\n", + "# plotNetwork(myCRN)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Overview for developers\n", + "Several key additions had to be made to biocrnpyler to make this possible. \n", + "\n", + "1. `Complex()` is a new function that you should use every time you want to make a ComplexSpecies. It should do exactly the same thing as the ComplexSpecies constructor, unless one of the species that you gave it is an OrderedComplexSpecies that has a 'bindloc' attribute, then instead of making a ComplexSpecies the function will make an OrderedComplexSpecies that is correctly formed.\n", + "\n", + "2. `OrderedPolymer` `OrderedMonomer` and `OrderedPolymerSpecies` are new data members that represent sequences of parts. A piece of DNA with many binding sites is represented as an OrderedPolymerSpecies. Because mechanisms and Components are agnostic of binding location; that is to say, they usually have code that looks like this: `make_complex([dna,protein])`, we must give them some way of knowing _where_ on that `dna` the `protein` should end up. To do this, you must pass an `OrderedMonomer` into a `Component` which belongs to an `OrderedPolymer`. Through the use of the `Complex()` function, the proper complex will be made, to the correct member of the `OrderedPolymer` which the `OrderedMonomer` belongs to.\n", + "\n", + "3. `DNA_part` inherits from `Component`, and every dna part such as `Promoter` now inherits from `DNA_part` instead of `Component`. This allows the storage of things like position, direction, and parent construct inside anything that used to be a `Component`\n", + "\n", + "4. `CDS` is a `DNA_part` which gives rise to a `Species`. It felt weird to put `Protein` objects into a DNA sequence so I created this. It only makes the protein if it is read in the 'forward' direction.\n", + "\n", + "4. `DNA_construct` contains a list of `DNA_part`s together with their directions. `DNA_construct` also has `update_species()` and `update_reactions()` so that it can generate the necessary species and reactions if it will be part of a CRN. Likewise, `RNA_construct` does the same thing for RNA. A `DNA_construct` can give rise to many `RNA_construct`s when it compiles. This is done through the action of `explore_txtl()`\n", + "\n", + "5. `explore_txtl()` is a function of `DNA_construct` which figures out the RNA and Proteins that a DNA produces. It works basically by going along a DNA part by part, remembering which parts came before, and taking into account the directions of parts. In general it will traverse a `DNA_construct` in the \"forward\" and \"reverse\" directions. It is hard coded to know that `RBS` parts make proteins and `Promoter` parts make RNAs, but only when their orientation is \"forward\" relative to the direction it's currently looking at. Other things are taken account too, for example, an `RBS` can only make a `Protein` if it is part of an RNA. Most of this logic is encapsulated in an object called `TxTl_explorer`.\n", + "\n", + "6. `update_components()` is a function of `DNA_construct` which creates many copies of the `DNA_part`s which make up the `DNA_construct`. This is necessary for making all combinatorial complexes. First, every `DNA_part` is fed in an `OrderedComplexSpecies` corresponding to the unbound DNA, which has the appropriate \"bindloc_\". Then, the `Species` produced by `update_species()` each have complexes in only one location. All possible combinations of bound species are then generated from this set of `OrderedComplexSpecies`. Then, these combinatorial complexes are fed _back_ into the `DNA_part`s, generating a new `DNA_part` that is responsible for generating species and reactions that include that combinatorial complex. For example, if you have `DNA_construct` containing a `Promoter` and an `AttachmentSite`, then `update_components()` should generate two `Promoter` parts, one that has the unbound `OrderedComplexSpecies` and one that has an `OrderedComplexSpecies` that has integrases bound to it. Then, these new `Component`s can be used to make species and reactions using their respective `update_species()` and `update_reactions()`\n" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": { + "tags": [] + }, + "outputs": [ + { + "output_type": "display_data", + "data": { + "text/plain": "
", + "image/svg+xml": "\r\n\r\n\r\n\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n\r\n", + "image/png": "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\n" + }, + "metadata": { + "needs_background": "light" + } + }, + { + "output_type": "display_data", + "data": { + "text/plain": "
", + "image/svg+xml": "\r\n\r\n\r\n\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n\r\n", + "image/png": "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\n" + }, + "metadata": { + "needs_background": "light" + } + }, + { + "output_type": "display_data", + "data": { + "text/plain": "
", + "image/svg+xml": "\r\n\r\n\r\n\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n\r\n", + "image/png": "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\n" + }, + "metadata": { + "needs_background": "light" + } + } + ], + "source": [ + "#Another complex DNA_construct example, where both DNA and RNA can be bound combinatorially\n", + "ptet.color=\"forestgreen\"\n", + "utr1.color = \"tan\"\n", + "t16.color=\"black\"\n", + "gfp.color=\"green\"\n", + "rfp.color=\"red\"\n", + "polycis_construct = DNA_construct([[t16,\"reverse\"],[cfp,\"reverse\"],[utr1,\"reverse\"],[pconst,\"reverse\"],[ptet,\"forward\"],[utr1,\"forward\"],[gfp,\"forward\"],[utr1,\"forward\"],[rfp,\"forward\"],[t16,\"forward\"]],circular=True)\n", + "if(dpl_enabled):\n", + " plotConstruct(polycis_construct,debug=False,plot_rnas=True,showlabels=[RegulatedPromoter,RBS,CDS,Terminator])\n", + "\n", + "\n", + "#some very basic parameters are defined\n", + "parameters={\"cooperativity\":2,\"kb\":100, \"ku\":10, \"ktx\":.05, \"ktl\":.2, \"kdeg\":2,\"kint\":.05,\"kdil\":.5}\n", + "\n", + "components = [polycis_construct]\n", + "myMixture = TxTlDilutionMixture(name = \"txtl\", parameters = parameters, components = components)\n", + "myCRN = myMixture.compile_crn()\n" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": { + "tags": [] + }, + "outputs": [ + { + "output_type": "display_data", + "data": { + "text/html": "\n
\n \n Loading BokehJS ...\n
" + }, + "metadata": {} + }, + { + "output_type": "display_data", + "data": { + "application/javascript": "\n(function(root) {\n function now() {\n return new Date();\n }\n\n var force = true;\n\n if (typeof root._bokeh_onload_callbacks === \"undefined\" || force === true) {\n root._bokeh_onload_callbacks = [];\n root._bokeh_is_loading = undefined;\n }\n\n var JS_MIME_TYPE = 'application/javascript';\n var HTML_MIME_TYPE = 'text/html';\n var EXEC_MIME_TYPE = 'application/vnd.bokehjs_exec.v0+json';\n var CLASS_NAME = 'output_bokeh rendered_html';\n\n /**\n * Render data to the DOM node\n */\n function render(props, node) {\n var script = document.createElement(\"script\");\n node.appendChild(script);\n }\n\n /**\n * Handle when an output is cleared or removed\n */\n function handleClearOutput(event, handle) {\n var cell = handle.cell;\n\n var id = cell.output_area._bokeh_element_id;\n var server_id = cell.output_area._bokeh_server_id;\n // Clean up Bokeh references\n if (id != null && id in Bokeh.index) {\n Bokeh.index[id].model.document.clear();\n delete Bokeh.index[id];\n }\n\n if (server_id !== undefined) {\n // Clean up Bokeh references\n var cmd = \"from bokeh.io.state import curstate; print(curstate().uuid_to_server['\" + server_id + \"'].get_sessions()[0].document.roots[0]._id)\";\n cell.notebook.kernel.execute(cmd, {\n iopub: {\n output: function(msg) {\n var id = msg.content.text.trim();\n if (id in Bokeh.index) {\n Bokeh.index[id].model.document.clear();\n delete Bokeh.index[id];\n }\n }\n }\n });\n // Destroy server and session\n var cmd = \"import bokeh.io.notebook as ion; ion.destroy_server('\" + server_id + \"')\";\n cell.notebook.kernel.execute(cmd);\n }\n }\n\n /**\n * Handle when a new output is added\n */\n function handleAddOutput(event, handle) {\n var output_area = handle.output_area;\n var output = handle.output;\n\n // limit handleAddOutput to display_data with EXEC_MIME_TYPE content only\n if ((output.output_type != \"display_data\") || (!output.data.hasOwnProperty(EXEC_MIME_TYPE))) {\n return\n }\n\n var toinsert = output_area.element.find(\".\" + CLASS_NAME.split(' ')[0]);\n\n if (output.metadata[EXEC_MIME_TYPE][\"id\"] !== undefined) {\n toinsert[toinsert.length - 1].firstChild.textContent = output.data[JS_MIME_TYPE];\n // store reference to embed id on output_area\n output_area._bokeh_element_id = output.metadata[EXEC_MIME_TYPE][\"id\"];\n }\n if (output.metadata[EXEC_MIME_TYPE][\"server_id\"] !== undefined) {\n var bk_div = document.createElement(\"div\");\n bk_div.innerHTML = output.data[HTML_MIME_TYPE];\n var script_attrs = bk_div.children[0].attributes;\n for (var i = 0; i < script_attrs.length; i++) {\n toinsert[toinsert.length - 1].firstChild.setAttribute(script_attrs[i].name, script_attrs[i].value);\n }\n // store reference to server id on output_area\n output_area._bokeh_server_id = output.metadata[EXEC_MIME_TYPE][\"server_id\"];\n }\n }\n\n function register_renderer(events, OutputArea) {\n\n function append_mime(data, metadata, element) {\n // create a DOM node to render to\n var toinsert = this.create_output_subarea(\n metadata,\n CLASS_NAME,\n EXEC_MIME_TYPE\n );\n this.keyboard_manager.register_events(toinsert);\n // Render to node\n var props = {data: data, metadata: metadata[EXEC_MIME_TYPE]};\n render(props, toinsert[toinsert.length - 1]);\n element.append(toinsert);\n return toinsert\n }\n\n /* Handle when an output is cleared or removed */\n events.on('clear_output.CodeCell', handleClearOutput);\n events.on('delete.Cell', handleClearOutput);\n\n /* Handle when a new output is added */\n events.on('output_added.OutputArea', handleAddOutput);\n\n /**\n * Register the mime type and append_mime function with output_area\n */\n OutputArea.prototype.register_mime_type(EXEC_MIME_TYPE, append_mime, {\n /* Is output safe? */\n safe: true,\n /* Index of renderer in `output_area.display_order` */\n index: 0\n });\n }\n\n // register the mime type if in Jupyter Notebook environment and previously unregistered\n if (root.Jupyter !== undefined) {\n var events = require('base/js/events');\n var OutputArea = require('notebook/js/outputarea').OutputArea;\n\n if (OutputArea.prototype.mime_types().indexOf(EXEC_MIME_TYPE) == -1) {\n register_renderer(events, OutputArea);\n }\n }\n\n \n if (typeof (root._bokeh_timeout) === \"undefined\" || force === true) {\n root._bokeh_timeout = Date.now() + 5000;\n root._bokeh_failed_load = false;\n }\n\n var NB_LOAD_WARNING = {'data': {'text/html':\n \"
\\n\"+\n \"

\\n\"+\n \"BokehJS does not appear to have successfully loaded. If loading BokehJS from CDN, this \\n\"+\n \"may be due to a slow or bad network connection. Possible fixes:\\n\"+\n \"

\\n\"+\n \"
    \\n\"+\n \"
  • re-rerun `output_notebook()` to attempt to load from CDN again, or
  • \\n\"+\n \"
  • use INLINE resources instead, as so:
  • \\n\"+\n \"
\\n\"+\n \"\\n\"+\n \"from bokeh.resources import INLINE\\n\"+\n \"output_notebook(resources=INLINE)\\n\"+\n \"\\n\"+\n \"
\"}};\n\n function display_loaded() {\n var el = document.getElementById(\"2609\");\n if (el != null) {\n el.textContent = \"BokehJS is loading...\";\n }\n if (root.Bokeh !== undefined) {\n if (el != null) {\n el.textContent = \"BokehJS \" + root.Bokeh.version + \" successfully loaded.\";\n }\n } else if (Date.now() < root._bokeh_timeout) {\n setTimeout(display_loaded, 100)\n }\n }\n\n\n function run_callbacks() {\n try {\n root._bokeh_onload_callbacks.forEach(function(callback) {\n if (callback != null)\n callback();\n });\n } finally {\n delete root._bokeh_onload_callbacks\n }\n console.debug(\"Bokeh: all callbacks have finished\");\n }\n\n function load_libs(css_urls, js_urls, callback) {\n if (css_urls == null) css_urls = [];\n if (js_urls == null) js_urls = [];\n\n root._bokeh_onload_callbacks.push(callback);\n if (root._bokeh_is_loading > 0) {\n console.debug(\"Bokeh: BokehJS is being loaded, scheduling callback at\", now());\n return null;\n }\n if (js_urls == null || js_urls.length === 0) {\n run_callbacks();\n return null;\n }\n console.debug(\"Bokeh: BokehJS not loaded, scheduling load and callback at\", now());\n root._bokeh_is_loading = css_urls.length + js_urls.length;\n\n function on_load() {\n root._bokeh_is_loading--;\n if (root._bokeh_is_loading === 0) {\n console.debug(\"Bokeh: all BokehJS libraries/stylesheets loaded\");\n run_callbacks()\n }\n }\n\n function on_error() {\n console.error(\"failed to load \" + url);\n }\n\n for (var i = 0; i < css_urls.length; i++) {\n var url = css_urls[i];\n const element = document.createElement(\"link\");\n element.onload = on_load;\n element.onerror = on_error;\n element.rel = \"stylesheet\";\n element.type = \"text/css\";\n element.href = url;\n console.debug(\"Bokeh: injecting link tag for BokehJS stylesheet: \", url);\n document.body.appendChild(element);\n }\n\n for (var i = 0; i < js_urls.length; i++) {\n var url = js_urls[i];\n var element = document.createElement('script');\n element.onload = on_load;\n element.onerror = on_error;\n element.async = false;\n element.src = url;\n console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n document.head.appendChild(element);\n }\n };var element = document.getElementById(\"2609\");\n if (element == null) {\n console.error(\"Bokeh: ERROR: autoload.js configured with elementid '2609' but no matching script tag was found. \")\n return false;\n }\n\n function inject_raw_css(css) {\n const element = document.createElement(\"style\");\n element.appendChild(document.createTextNode(css));\n document.body.appendChild(element);\n }\n\n \n var js_urls = [\"https://cdn.pydata.org/bokeh/release/bokeh-1.4.0.min.js\", \"https://cdn.pydata.org/bokeh/release/bokeh-widgets-1.4.0.min.js\", \"https://cdn.pydata.org/bokeh/release/bokeh-tables-1.4.0.min.js\", \"https://cdn.pydata.org/bokeh/release/bokeh-gl-1.4.0.min.js\"];\n var css_urls = [];\n \n\n var inline_js = [\n function(Bokeh) {\n Bokeh.set_log_level(\"info\");\n },\n function(Bokeh) {\n \n \n }\n ];\n\n function run_inline_js() {\n \n if (root.Bokeh !== undefined || force === true) {\n \n for (var i = 0; i < inline_js.length; i++) {\n inline_js[i].call(root, root.Bokeh);\n }\n if (force === true) {\n display_loaded();\n }} else if (Date.now() < root._bokeh_timeout) {\n setTimeout(run_inline_js, 100);\n } else if (!root._bokeh_failed_load) {\n console.log(\"Bokeh: BokehJS failed to load within specified timeout.\");\n root._bokeh_failed_load = true;\n } else if (force !== true) {\n var cell = $(document.getElementById(\"2609\")).parents('.cell').data().cell;\n cell.output_area.append_execute_result(NB_LOAD_WARNING)\n }\n\n }\n\n if (root._bokeh_is_loading === 0) {\n console.debug(\"Bokeh: BokehJS loaded, going straight to plotting\");\n run_inline_js();\n } else {\n load_libs(css_urls, js_urls, function() {\n console.debug(\"Bokeh: BokehJS plotting callback run at\", now());\n run_inline_js();\n });\n }\n}(window));", + "application/vnd.bokehjs_load.v0+json": "\n(function(root) {\n function now() {\n return new Date();\n }\n\n var force = true;\n\n if (typeof root._bokeh_onload_callbacks === \"undefined\" || force === true) {\n root._bokeh_onload_callbacks = [];\n root._bokeh_is_loading = undefined;\n }\n\n \n\n \n if (typeof (root._bokeh_timeout) === \"undefined\" || force === true) {\n root._bokeh_timeout = Date.now() + 5000;\n root._bokeh_failed_load = false;\n }\n\n var NB_LOAD_WARNING = {'data': {'text/html':\n \"
\\n\"+\n \"

\\n\"+\n \"BokehJS does not appear to have successfully loaded. If loading BokehJS from CDN, this \\n\"+\n \"may be due to a slow or bad network connection. Possible fixes:\\n\"+\n \"

\\n\"+\n \"
    \\n\"+\n \"
  • re-rerun `output_notebook()` to attempt to load from CDN again, or
  • \\n\"+\n \"
  • use INLINE resources instead, as so:
  • \\n\"+\n \"
\\n\"+\n \"\\n\"+\n \"from bokeh.resources import INLINE\\n\"+\n \"output_notebook(resources=INLINE)\\n\"+\n \"\\n\"+\n \"
\"}};\n\n function display_loaded() {\n var el = document.getElementById(\"2609\");\n if (el != null) {\n el.textContent = \"BokehJS is loading...\";\n }\n if (root.Bokeh !== undefined) {\n if (el != null) {\n el.textContent = \"BokehJS \" + root.Bokeh.version + \" successfully loaded.\";\n }\n } else if (Date.now() < root._bokeh_timeout) {\n setTimeout(display_loaded, 100)\n }\n }\n\n\n function run_callbacks() {\n try {\n root._bokeh_onload_callbacks.forEach(function(callback) {\n if (callback != null)\n callback();\n });\n } finally {\n delete root._bokeh_onload_callbacks\n }\n console.debug(\"Bokeh: all callbacks have finished\");\n }\n\n function load_libs(css_urls, js_urls, callback) {\n if (css_urls == null) css_urls = [];\n if (js_urls == null) js_urls = [];\n\n root._bokeh_onload_callbacks.push(callback);\n if (root._bokeh_is_loading > 0) {\n console.debug(\"Bokeh: BokehJS is being loaded, scheduling callback at\", now());\n return null;\n }\n if (js_urls == null || js_urls.length === 0) {\n run_callbacks();\n return null;\n }\n console.debug(\"Bokeh: BokehJS not loaded, scheduling load and callback at\", now());\n root._bokeh_is_loading = css_urls.length + js_urls.length;\n\n function on_load() {\n root._bokeh_is_loading--;\n if (root._bokeh_is_loading === 0) {\n console.debug(\"Bokeh: all BokehJS libraries/stylesheets loaded\");\n run_callbacks()\n }\n }\n\n function on_error() {\n console.error(\"failed to load \" + url);\n }\n\n for (var i = 0; i < css_urls.length; i++) {\n var url = css_urls[i];\n const element = document.createElement(\"link\");\n element.onload = on_load;\n element.onerror = on_error;\n element.rel = \"stylesheet\";\n element.type = \"text/css\";\n element.href = url;\n console.debug(\"Bokeh: injecting link tag for BokehJS stylesheet: \", url);\n document.body.appendChild(element);\n }\n\n for (var i = 0; i < js_urls.length; i++) {\n var url = js_urls[i];\n var element = document.createElement('script');\n element.onload = on_load;\n element.onerror = on_error;\n element.async = false;\n element.src = url;\n console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n document.head.appendChild(element);\n }\n };var element = document.getElementById(\"2609\");\n if (element == null) {\n console.error(\"Bokeh: ERROR: autoload.js configured with elementid '2609' but no matching script tag was found. \")\n return false;\n }\n\n function inject_raw_css(css) {\n const element = document.createElement(\"style\");\n element.appendChild(document.createTextNode(css));\n document.body.appendChild(element);\n }\n\n \n var js_urls = [\"https://cdn.pydata.org/bokeh/release/bokeh-1.4.0.min.js\", \"https://cdn.pydata.org/bokeh/release/bokeh-widgets-1.4.0.min.js\", \"https://cdn.pydata.org/bokeh/release/bokeh-tables-1.4.0.min.js\", \"https://cdn.pydata.org/bokeh/release/bokeh-gl-1.4.0.min.js\"];\n var css_urls = [];\n \n\n var inline_js = [\n function(Bokeh) {\n Bokeh.set_log_level(\"info\");\n },\n function(Bokeh) {\n \n \n }\n ];\n\n function run_inline_js() {\n \n if (root.Bokeh !== undefined || force === true) {\n \n for (var i = 0; i < inline_js.length; i++) {\n inline_js[i].call(root, root.Bokeh);\n }\n if (force === true) {\n display_loaded();\n }} else if (Date.now() < root._bokeh_timeout) {\n setTimeout(run_inline_js, 100);\n } else if (!root._bokeh_failed_load) {\n console.log(\"Bokeh: BokehJS failed to load within specified timeout.\");\n root._bokeh_failed_load = true;\n } else if (force !== true) {\n var cell = $(document.getElementById(\"2609\")).parents('.cell').data().cell;\n cell.output_area.append_execute_result(NB_LOAD_WARNING)\n }\n\n }\n\n if (root._bokeh_is_loading === 0) {\n console.debug(\"Bokeh: BokehJS loaded, going straight to plotting\");\n run_inline_js();\n } else {\n load_libs(css_urls, js_urls, function() {\n console.debug(\"Bokeh: BokehJS plotting callback run at\", now());\n run_inline_js();\n });\n }\n}(window));" + }, + "metadata": {} + }, + { + "output_type": "stream", + "name": "stderr", + "text": "D:\\anaconda3\\lib\\site-packages\\bokeh\\models\\graphs.py:164: UserWarning: Node keys in 'layout_function' don't match node keys in the graph. These nodes may not be displayed correctly.\n warn(\"Node keys in 'layout_function' don't match node keys in the graph. \"\n" + }, + { + "output_type": "display_data", + "data": { + "text/html": "\n\n\n\n\n\n
\n" + }, + "metadata": {} + }, + { + "output_type": "display_data", + "data": { + "application/javascript": "(function(root) {\n function embed_document(root) {\n \n var docs_json = {\"0725f7ce-26e5-46dc-9741-eb447f03bef7\":{\"roots\":{\"references\":[{\"attributes\":{\"plot_height\":500,\"plot_width\":500,\"renderers\":[{\"id\":\"2649\",\"type\":\"GraphRenderer\"},{\"id\":\"2617\",\"type\":\"GraphRenderer\"},{\"id\":\"2633\",\"type\":\"GraphRenderer\"}],\"title\":{\"id\":\"2879\",\"type\":\"Title\"},\"toolbar\":{\"id\":\"2730\",\"type\":\"Toolbar\"},\"x_range\":{\"id\":\"2691\",\"type\":\"Range1d\"},\"x_scale\":{\"id\":\"2878\",\"type\":\"LinearScale\"},\"y_range\":{\"id\":\"2692\",\"type\":\"Range1d\"},\"y_scale\":{\"id\":\"2876\",\"type\":\"LinearScale\"}},\"id\":\"2612\",\"type\":\"Plot\"},{\"attributes\":{},\"id\":\"2918\",\"type\":\"Selection\"},{\"attributes\":{\"callback\":null,\"end\":85.9156295791733,\"start\":-122.57878347807778},\"id\":\"2691\",\"type\":\"Range1d\"},{\"attributes\":{},\"id\":\"2915\",\"type\":\"UnionRenderers\"},{\"attributes\":{\"edge_renderer\":{\"id\":\"2640\",\"type\":\"GlyphRenderer\"},\"inspection_policy\":{\"id\":\"2902\",\"type\":\"NodesOnly\"},\"layout_provider\":{\"id\":\"2646\",\"type\":\"StaticLayoutProvider\"},\"node_renderer\":{\"id\":\"2636\",\"type\":\"GlyphRenderer\"},\"selection_policy\":{\"id\":\"2903\",\"type\":\"NodesOnly\"}},\"id\":\"2633\",\"type\":\"GraphRenderer\"},{\"attributes\":{\"data_source\":{\"id\":\"2655\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"2668\",\"type\":\"MultiLine\"},\"hover_glyph\":{\"id\":\"2678\",\"type\":\"MultiLine\"},\"muted_glyph\":null,\"selection_glyph\":{\"id\":\"2673\",\"type\":\"MultiLine\"},\"view\":{\"id\":\"2657\",\"type\":\"CDSView\"}},\"id\":\"2656\",\"type\":\"GlyphRenderer\"},{\"attributes\":{},\"id\":\"2916\",\"type\":\"Selection\"},{\"attributes\":{},\"id\":\"2903\",\"type\":\"NodesOnly\"},{\"attributes\":{\"callback\":null,\"data\":{\"end\":[],\"start\":[]},\"selected\":{\"id\":\"2916\",\"type\":\"Selection\"},\"selection_policy\":{\"id\":\"2915\",\"type\":\"UnionRenderers\"}},\"id\":\"2623\",\"type\":\"ColumnDataSource\"},{\"attributes\":{\"fill_color\":{\"value\":\"#fdae61\"},\"size\":{\"units\":\"screen\",\"value\":15}},\"id\":\"2713\",\"type\":\"Circle\"},{\"attributes\":{},\"id\":\"2638\",\"type\":\"MultiLine\"},{\"attributes\":{\"callback\":null,\"renderers\":[{\"id\":\"2649\",\"type\":\"GraphRenderer\"}],\"tooltips\":null},\"id\":\"2723\",\"type\":\"HoverTool\"},{\"attributes\":{\"callback\":null,\"data\":{\"color\":[\"purple\",\"orange\",\"grey\",\"cyan\",\"grey\",\"cyan\",\"lightgreen\",\"grey\",\"green\",\"grey\",\"pink\",\"skyblue\",\"grey\",\"grey\",\"white\",\"grey\",\"grey\",\"red\",\"green\",\"blue\",\"white\",\"grey\",\"grey\",\"orange\",\"cyan\",\"orange\",\"green\",\"grey\",\"blue\",\"blue\",\"blue\",\"blue\",\"blue\",\"blue\",\"blue\",\"blue\",\"blue\",\"blue\",\"blue\",\"blue\",\"blue\",\"blue\",\"blue\",\"blue\",\"blue\",\"blue\",\"blue\",\"blue\",\"blue\",\"blue\",\"blue\",\"blue\",\"blue\",\"blue\",\"blue\",\"blue\",\"blue\",\"blue\",\"blue\",\"blue\",\"blue\",\"blue\",\"blue\",\"blue\",\"blue\",\"blue\",\"blue\",\"blue\",\"blue\",\"blue\"],\"index\":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69],\"k\":[null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,\"100\",\"0.05\",\"100\",\"100\",\"0.05\",\"100\",\"0.05\",\"100\",\"0.05\",\"100\",\"0.05\",\"100\",\"0.05\",\"100\",\"0.05\",\"100\",\"100\",\"0.05\",\"100\",\"0.2\",\"100\",\"0.2\",\"100\",\"0.2\",\"100\",\"0.2\",\"100\",\"0.2\",\"500\",\"0.1\",\"500\",\"0.1\",\"500\",\"0.1\",\"0.5\",\"0.5\",\"0.5\",\"0.5\",\"0.5\",\"0.5\",\"0.5\",\"0.5\"],\"k_r\":[null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,\"10\",\"None\",\"10\",\"10\",\"None\",\"10\",\"None\",\"10\",\"None\",\"10\",\"None\",\"10\",\"None\",\"10\",\"None\",\"10\",\"10\",\"None\",\"10\",\"None\",\"10\",\"None\",\"10\",\"None\",\"10\",\"None\",\"10\",\"None\",\"50\",\"None\",\"5\",\"None\",\"50\",\"None\",\"None\",\"None\",\"None\",\"None\",\"None\",\"None\",\"None\",\"None\"],\"species\":[\"nothing\",\"rna[rna[UTR1-forward]:rna[GFP-forward]:rna[UTR1-forward]:rna[RFP-forward]:rna[t16-forward]]\",\"ordered_polymer[rna[UTR1-forward]:rna[GFP-forward]:complex[protein[Ribo]:rna[UTR1]-forward]:rna[RFP-forward]:rna[t16-forward]]\",\"complex[protein[Ribo]:rna[cellular_processes]]\",\"ordered_polymer[complex[protein[Ribo]:rna[UTR1]-forward]:rna[CFP-forward]:rna[t16-forward]]\",\"complex[protein[RNAase]:rna[cellular_processes]]\",\"protein[GFP]\",\"ordered_polymer[complex[protein[Ribo]:rna[UTR1]-forward]:rna[GFP-forward]:rna[UTR1-forward]:rna[RFP-forward]:rna[t16-forward]]\",\"protein[RNAase(machinery)]\",\"ordered_polymer[dna[t16-reverse]:dna[CFP-reverse]:dna[UTR1-reverse]:complex[dna[pconst]:protein[RNAP]-reverse]:complex[dna[ptet]:protein[RNAP]-forward]:dna[UTR1-forward]:dna[GFP-forward]:dna[UTR1-forward]:dna[RFP-forward]:dna[t16-forward](circular)]\",\"protein[Ribo(machinery)]\",\"protein[RNAP(machinery)]\",\"ordered_polymer[dna[t16-reverse]:dna[CFP-reverse]:dna[UTR1-reverse]:complex[dna[pconst]:protein[RNAP]-reverse]:[dna[ptet]:2x_protein[tetr]-forward]:dna[UTR1-forward]:dna[GFP-forward]:dna[UTR1-forward]:dna[RFP-forward]:dna[t16-forward](circular)]\",\"ordered_polymer[dna[t16-reverse]:dna[CFP-reverse]:dna[UTR1-reverse]:dna[pconst-reverse]:[dna[ptet]:2x_protein[tetr]-forward]:dna[UTR1-forward]:dna[GFP-forward]:dna[UTR1-forward]:dna[RFP-forward]:dna[t16-forward](circular)]\",\"dna[dna[t16-reverse]:dna[CFP-reverse]:dna[UTR1-reverse]:dna[pconst-reverse]:dna[ptet-forward]:dna[UTR1-forward]:dna[GFP-forward]:dna[UTR1-forward]:dna[RFP-forward]:dna[t16-forward](circular)]\",\"ordered_polymer[dna[t16-reverse]:dna[CFP-reverse]:dna[UTR1-reverse]:dna[pconst-reverse]:complex[dna[ptet]:protein[RNAP]-forward]:dna[UTR1-forward]:dna[GFP-forward]:dna[UTR1-forward]:dna[RFP-forward]:dna[t16-forward](circular)]\",\"ordered_polymer[complex[protein[Ribo]:rna[UTR1]-forward]:rna[GFP-forward]:complex[protein[Ribo]:rna[UTR1]-forward]:rna[RFP-forward]:rna[t16-forward]]\",\"protein[RFP]\",\"protein[tetr]\",\"protein[CFP]\",\"dna[cellular_processes]\",\"ordered_polymer[dna[t16-reverse]:dna[CFP-reverse]:dna[UTR1-reverse]:complex[dna[pconst]:protein[RNAP]-reverse]:complex[[dna[ptet]:2x_protein[tetr]]:protein[RNAP]-forward]:dna[UTR1-forward]:dna[GFP-forward]:dna[UTR1-forward]:dna[RFP-forward]:dna[t16-forward](circular)]\",\"ordered_polymer[dna[t16-reverse]:dna[CFP-reverse]:dna[UTR1-reverse]:complex[dna[pconst]:protein[RNAP]-reverse]:dna[ptet-forward]:dna[UTR1-forward]:dna[GFP-forward]:dna[UTR1-forward]:dna[RFP-forward]:dna[t16-forward](circular)]\",\"rna[rna[UTR1-forward]:rna[CFP-forward]:rna[t16-forward]]\",\"complex[dna[cellular_processes]:protein[RNAP]]\",\"rna[cellular_processes]\",\"protein[cellular_processes]\",\"ordered_polymer[dna[t16-reverse]:dna[CFP-reverse]:dna[UTR1-reverse]:dna[pconst-reverse]:complex[[dna[ptet]:2x_protein[tetr]]:protein[RNAP]-forward]:dna[UTR1-forward]:dna[GFP-forward]:dna[UTR1-forward]:dna[RFP-forward]:dna[t16-forward](circular)]\",\"ordered_polymer[dna[t16-reverse]:dna[CFP-reverse]:dna[UTR1-reverse]:complex[dna[pconst]:protein[RNAP]-reverse]:dna[ptet-forward]:dna[UTR1-forward]:dna[GFP-forward]:dna[UTR1-forward]:dna[RFP-forward]:dna[t16-forward](circular)]+protein[RNAP(machinery)] <--> ordered_polymer[dna[t16-reverse]:dna[CFP-reverse]:dna[UTR1-reverse]:complex[dna[pconst]:protein[RNAP]-reverse]:complex[dna[ptet]:protein[RNAP]-forward]:dna[UTR1-forward]:dna[GFP-forward]:dna[UTR1-forward]:dna[RFP-forward]:dna[t16-forward](circular)]\\n Kf=k_forward * ordered_polymer_t16_r_CFP_r_UTR1_r_dna_pconst_protein_RNAP_machinery_r_ptet_f_UTR1_f_GFP_f_UTR1_f_RFP_f_t16_f_o_circular * protein_RNAP_machinery\\n Kr=k_reverse * ordered_polymer_t16_r_CFP_r_UTR1_r_dna_pconst_protein_RNAP_machinery_r_dna_ptet_protein_RNAP_machinery_f_UTR1_f_GFP_f_UTR1_f_RFP_f_t16_f_o_circular\\n k_forward=100\\n found_key=(mech=None, partid=None, name=kb).\\n search_key=(mech=transcription_mm, partid=ptet_leak, name=kb).\\n k_reverse=10\\n found_key=(mech=None, partid=None, name=ku).\\n search_key=(mech=transcription_mm, partid=ptet_leak, name=ku).\\n\",\"ordered_polymer[dna[t16-reverse]:dna[CFP-reverse]:dna[UTR1-reverse]:complex[dna[pconst]:protein[RNAP]-reverse]:complex[dna[ptet]:protein[RNAP]-forward]:dna[UTR1-forward]:dna[GFP-forward]:dna[UTR1-forward]:dna[RFP-forward]:dna[t16-forward](circular)] --> ordered_polymer[dna[t16-reverse]:dna[CFP-reverse]:dna[UTR1-reverse]:complex[dna[pconst]:protein[RNAP]-reverse]:dna[ptet-forward]:dna[UTR1-forward]:dna[GFP-forward]:dna[UTR1-forward]:dna[RFP-forward]:dna[t16-forward](circular)]+rna[rna[UTR1-forward]:rna[GFP-forward]:rna[UTR1-forward]:rna[RFP-forward]:rna[t16-forward]]+protein[RNAP(machinery)]\\n Kf=k_forward * ordered_polymer_t16_r_CFP_r_UTR1_r_dna_pconst_protein_RNAP_machinery_r_dna_ptet_protein_RNAP_machinery_f_UTR1_f_GFP_f_UTR1_f_RFP_f_t16_f_o_circular\\n k_forward=0.05\\n found_key=(mech=None, partid=None, name=ktx).\\n search_key=(mech=transcription_mm, partid=ptet_leak, name=ktx).\\n\",\"2protein[tetr]+ordered_polymer[dna[t16-reverse]:dna[CFP-reverse]:dna[UTR1-reverse]:complex[dna[pconst]:protein[RNAP]-reverse]:dna[ptet-forward]:dna[UTR1-forward]:dna[GFP-forward]:dna[UTR1-forward]:dna[RFP-forward]:dna[t16-forward](circular)] <--> ordered_polymer[dna[t16-reverse]:dna[CFP-reverse]:dna[UTR1-reverse]:complex[dna[pconst]:protein[RNAP]-reverse]:[dna[ptet]:2x_protein[tetr]-forward]:dna[UTR1-forward]:dna[GFP-forward]:dna[UTR1-forward]:dna[RFP-forward]:dna[t16-forward](circular)]\\n Kf=k_forward * protein_tetr^2 * ordered_polymer_t16_r_CFP_r_UTR1_r_dna_pconst_protein_RNAP_machinery_r_ptet_f_UTR1_f_GFP_f_UTR1_f_RFP_f_t16_f_o_circular\\n Kr=k_reverse * ordered_polymer_t16_r_CFP_r_UTR1_r_dna_pconst_protein_RNAP_machinery_r_dna_ptet_protein_tetr_2x_f_UTR1_f_GFP_f_UTR1_f_RFP_f_t16_f_o_circular\\n k_forward=100\\n found_key=(mech=None, partid=None, name=kb).\\n search_key=(mech=one_step_cooperative_binding, partid=ptet_tetr, name=kb).\\n k_reverse=10\\n found_key=(mech=None, partid=None, name=ku).\\n search_key=(mech=one_step_cooperative_binding, partid=ptet_tetr, name=ku).\\n\",\"ordered_polymer[dna[t16-reverse]:dna[CFP-reverse]:dna[UTR1-reverse]:complex[dna[pconst]:protein[RNAP]-reverse]:[dna[ptet]:2x_protein[tetr]-forward]:dna[UTR1-forward]:dna[GFP-forward]:dna[UTR1-forward]:dna[RFP-forward]:dna[t16-forward](circular)]+protein[RNAP(machinery)] <--> ordered_polymer[dna[t16-reverse]:dna[CFP-reverse]:dna[UTR1-reverse]:complex[dna[pconst]:protein[RNAP]-reverse]:complex[[dna[ptet]:2x_protein[tetr]]:protein[RNAP]-forward]:dna[UTR1-forward]:dna[GFP-forward]:dna[UTR1-forward]:dna[RFP-forward]:dna[t16-forward](circular)]\\n Kf=k_forward * ordered_polymer_t16_r_CFP_r_UTR1_r_dna_pconst_protein_RNAP_machinery_r_dna_ptet_protein_tetr_2x_f_UTR1_f_GFP_f_UTR1_f_RFP_f_t16_f_o_circular * protein_RNAP_machinery\\n Kr=k_reverse * ordered_polymer_t16_r_CFP_r_UTR1_r_dna_pconst_protein_RNAP_machinery_r_dna_ptet_protein_tetr_2x_protein_RNAP_machinery_f_UTR1_f_GFP_f_UTR1_f_RFP_f_t16_f_o_circular\\n k_forward=100\\n found_key=(mech=None, partid=None, name=kb).\\n search_key=(mech=transcription_mm, partid=ptet_tetr, name=kb).\\n k_reverse=10\\n found_key=(mech=None, partid=None, name=ku).\\n search_key=(mech=transcription_mm, partid=ptet_tetr, name=ku).\\n\",\"ordered_polymer[dna[t16-reverse]:dna[CFP-reverse]:dna[UTR1-reverse]:complex[dna[pconst]:protein[RNAP]-reverse]:complex[[dna[ptet]:2x_protein[tetr]]:protein[RNAP]-forward]:dna[UTR1-forward]:dna[GFP-forward]:dna[UTR1-forward]:dna[RFP-forward]:dna[t16-forward](circular)] --> ordered_polymer[dna[t16-reverse]:dna[CFP-reverse]:dna[UTR1-reverse]:complex[dna[pconst]:protein[RNAP]-reverse]:[dna[ptet]:2x_protein[tetr]-forward]:dna[UTR1-forward]:dna[GFP-forward]:dna[UTR1-forward]:dna[RFP-forward]:dna[t16-forward](circular)]+rna[rna[UTR1-forward]:rna[GFP-forward]:rna[UTR1-forward]:rna[RFP-forward]:rna[t16-forward]]+protein[RNAP(machinery)]\\n Kf=k_forward * ordered_polymer_t16_r_CFP_r_UTR1_r_dna_pconst_protein_RNAP_machinery_r_dna_ptet_protein_tetr_2x_protein_RNAP_machinery_f_UTR1_f_GFP_f_UTR1_f_RFP_f_t16_f_o_circular\\n k_forward=0.05\\n found_key=(mech=None, partid=None, name=ktx).\\n search_key=(mech=transcription_mm, partid=ptet_tetr, name=ktx).\\n\",\"ordered_polymer[dna[t16-reverse]:dna[CFP-reverse]:dna[UTR1-reverse]:dna[pconst-reverse]:complex[dna[ptet]:protein[RNAP]-forward]:dna[UTR1-forward]:dna[GFP-forward]:dna[UTR1-forward]:dna[RFP-forward]:dna[t16-forward](circular)]+protein[RNAP(machinery)] <--> ordered_polymer[dna[t16-reverse]:dna[CFP-reverse]:dna[UTR1-reverse]:complex[dna[pconst]:protein[RNAP]-reverse]:complex[dna[ptet]:protein[RNAP]-forward]:dna[UTR1-forward]:dna[GFP-forward]:dna[UTR1-forward]:dna[RFP-forward]:dna[t16-forward](circular)]\\n Kf=k_forward * ordered_polymer_t16_r_CFP_r_UTR1_r_pconst_r_dna_ptet_protein_RNAP_machinery_f_UTR1_f_GFP_f_UTR1_f_RFP_f_t16_f_o_circular * protein_RNAP_machinery\\n Kr=k_reverse * ordered_polymer_t16_r_CFP_r_UTR1_r_dna_pconst_protein_RNAP_machinery_r_dna_ptet_protein_RNAP_machinery_f_UTR1_f_GFP_f_UTR1_f_RFP_f_t16_f_o_circular\\n k_forward=100\\n found_key=(mech=None, partid=None, name=kb).\\n search_key=(mech=transcription_mm, partid=pconst, name=kb).\\n k_reverse=10\\n found_key=(mech=None, partid=None, name=ku).\\n search_key=(mech=transcription_mm, partid=pconst, name=ku).\\n\",\"ordered_polymer[dna[t16-reverse]:dna[CFP-reverse]:dna[UTR1-reverse]:complex[dna[pconst]:protein[RNAP]-reverse]:complex[dna[ptet]:protein[RNAP]-forward]:dna[UTR1-forward]:dna[GFP-forward]:dna[UTR1-forward]:dna[RFP-forward]:dna[t16-forward](circular)] --> ordered_polymer[dna[t16-reverse]:dna[CFP-reverse]:dna[UTR1-reverse]:dna[pconst-reverse]:complex[dna[ptet]:protein[RNAP]-forward]:dna[UTR1-forward]:dna[GFP-forward]:dna[UTR1-forward]:dna[RFP-forward]:dna[t16-forward](circular)]+rna[rna[UTR1-forward]:rna[CFP-forward]:rna[t16-forward]]+protein[RNAP(machinery)]\\n Kf=k_forward * ordered_polymer_t16_r_CFP_r_UTR1_r_dna_pconst_protein_RNAP_machinery_r_dna_ptet_protein_RNAP_machinery_f_UTR1_f_GFP_f_UTR1_f_RFP_f_t16_f_o_circular\\n k_forward=0.05\\n found_key=(mech=None, partid=None, name=ktx).\\n search_key=(mech=transcription_mm, partid=pconst, name=ktx).\\n\",\"ordered_polymer[dna[t16-reverse]:dna[CFP-reverse]:dna[UTR1-reverse]:dna[pconst-reverse]:[dna[ptet]:2x_protein[tetr]-forward]:dna[UTR1-forward]:dna[GFP-forward]:dna[UTR1-forward]:dna[RFP-forward]:dna[t16-forward](circular)]+protein[RNAP(machinery)] <--> ordered_polymer[dna[t16-reverse]:dna[CFP-reverse]:dna[UTR1-reverse]:complex[dna[pconst]:protein[RNAP]-reverse]:[dna[ptet]:2x_protein[tetr]-forward]:dna[UTR1-forward]:dna[GFP-forward]:dna[UTR1-forward]:dna[RFP-forward]:dna[t16-forward](circular)]\\n Kf=k_forward * ordered_polymer_t16_r_CFP_r_UTR1_r_pconst_r_dna_ptet_protein_tetr_2x_f_UTR1_f_GFP_f_UTR1_f_RFP_f_t16_f_o_circular * protein_RNAP_machinery\\n Kr=k_reverse * ordered_polymer_t16_r_CFP_r_UTR1_r_dna_pconst_protein_RNAP_machinery_r_dna_ptet_protein_tetr_2x_f_UTR1_f_GFP_f_UTR1_f_RFP_f_t16_f_o_circular\\n k_forward=100\\n found_key=(mech=None, partid=None, name=kb).\\n search_key=(mech=transcription_mm, partid=pconst, name=kb).\\n k_reverse=10\\n found_key=(mech=None, partid=None, name=ku).\\n search_key=(mech=transcription_mm, partid=pconst, name=ku).\\n\",\"ordered_polymer[dna[t16-reverse]:dna[CFP-reverse]:dna[UTR1-reverse]:complex[dna[pconst]:protein[RNAP]-reverse]:[dna[ptet]:2x_protein[tetr]-forward]:dna[UTR1-forward]:dna[GFP-forward]:dna[UTR1-forward]:dna[RFP-forward]:dna[t16-forward](circular)] --> ordered_polymer[dna[t16-reverse]:dna[CFP-reverse]:dna[UTR1-reverse]:dna[pconst-reverse]:[dna[ptet]:2x_protein[tetr]-forward]:dna[UTR1-forward]:dna[GFP-forward]:dna[UTR1-forward]:dna[RFP-forward]:dna[t16-forward](circular)]+rna[rna[UTR1-forward]:rna[CFP-forward]:rna[t16-forward]]+protein[RNAP(machinery)]\\n Kf=k_forward * ordered_polymer_t16_r_CFP_r_UTR1_r_dna_pconst_protein_RNAP_machinery_r_dna_ptet_protein_tetr_2x_f_UTR1_f_GFP_f_UTR1_f_RFP_f_t16_f_o_circular\\n k_forward=0.05\\n found_key=(mech=None, partid=None, name=ktx).\\n search_key=(mech=transcription_mm, partid=pconst, name=ktx).\\n\",\"ordered_polymer[dna[t16-reverse]:dna[CFP-reverse]:dna[UTR1-reverse]:dna[pconst-reverse]:complex[[dna[ptet]:2x_protein[tetr]]:protein[RNAP]-forward]:dna[UTR1-forward]:dna[GFP-forward]:dna[UTR1-forward]:dna[RFP-forward]:dna[t16-forward](circular)]+protein[RNAP(machinery)] <--> ordered_polymer[dna[t16-reverse]:dna[CFP-reverse]:dna[UTR1-reverse]:complex[dna[pconst]:protein[RNAP]-reverse]:complex[[dna[ptet]:2x_protein[tetr]]:protein[RNAP]-forward]:dna[UTR1-forward]:dna[GFP-forward]:dna[UTR1-forward]:dna[RFP-forward]:dna[t16-forward](circular)]\\n Kf=k_forward * ordered_polymer_t16_r_CFP_r_UTR1_r_pconst_r_dna_ptet_protein_tetr_2x_protein_RNAP_machinery_f_UTR1_f_GFP_f_UTR1_f_RFP_f_t16_f_o_circular * protein_RNAP_machinery\\n Kr=k_reverse * ordered_polymer_t16_r_CFP_r_UTR1_r_dna_pconst_protein_RNAP_machinery_r_dna_ptet_protein_tetr_2x_protein_RNAP_machinery_f_UTR1_f_GFP_f_UTR1_f_RFP_f_t16_f_o_circular\\n k_forward=100\\n found_key=(mech=None, partid=None, name=kb).\\n search_key=(mech=transcription_mm, partid=pconst, name=kb).\\n k_reverse=10\\n found_key=(mech=None, partid=None, name=ku).\\n search_key=(mech=transcription_mm, partid=pconst, name=ku).\\n\",\"ordered_polymer[dna[t16-reverse]:dna[CFP-reverse]:dna[UTR1-reverse]:complex[dna[pconst]:protein[RNAP]-reverse]:complex[[dna[ptet]:2x_protein[tetr]]:protein[RNAP]-forward]:dna[UTR1-forward]:dna[GFP-forward]:dna[UTR1-forward]:dna[RFP-forward]:dna[t16-forward](circular)] --> ordered_polymer[dna[t16-reverse]:dna[CFP-reverse]:dna[UTR1-reverse]:dna[pconst-reverse]:complex[[dna[ptet]:2x_protein[tetr]]:protein[RNAP]-forward]:dna[UTR1-forward]:dna[GFP-forward]:dna[UTR1-forward]:dna[RFP-forward]:dna[t16-forward](circular)]+rna[rna[UTR1-forward]:rna[CFP-forward]:rna[t16-forward]]+protein[RNAP(machinery)]\\n Kf=k_forward * ordered_polymer_t16_r_CFP_r_UTR1_r_dna_pconst_protein_RNAP_machinery_r_dna_ptet_protein_tetr_2x_protein_RNAP_machinery_f_UTR1_f_GFP_f_UTR1_f_RFP_f_t16_f_o_circular\\n k_forward=0.05\\n found_key=(mech=None, partid=None, name=ktx).\\n search_key=(mech=transcription_mm, partid=pconst, name=ktx).\\n\",\"dna[dna[t16-reverse]:dna[CFP-reverse]:dna[UTR1-reverse]:dna[pconst-reverse]:dna[ptet-forward]:dna[UTR1-forward]:dna[GFP-forward]:dna[UTR1-forward]:dna[RFP-forward]:dna[t16-forward](circular)]+protein[RNAP(machinery)] <--> ordered_polymer[dna[t16-reverse]:dna[CFP-reverse]:dna[UTR1-reverse]:complex[dna[pconst]:protein[RNAP]-reverse]:dna[ptet-forward]:dna[UTR1-forward]:dna[GFP-forward]:dna[UTR1-forward]:dna[RFP-forward]:dna[t16-forward](circular)]\\n Kf=k_forward * dna_t16_r_CFP_r_UTR1_r_pconst_r_ptet_f_UTR1_f_GFP_f_UTR1_f_RFP_f_t16_f_o_circular * protein_RNAP_machinery\\n Kr=k_reverse * ordered_polymer_t16_r_CFP_r_UTR1_r_dna_pconst_protein_RNAP_machinery_r_ptet_f_UTR1_f_GFP_f_UTR1_f_RFP_f_t16_f_o_circular\\n k_forward=100\\n found_key=(mech=None, partid=None, name=kb).\\n search_key=(mech=transcription_mm, partid=pconst, name=kb).\\n k_reverse=10\\n found_key=(mech=None, partid=None, name=ku).\\n search_key=(mech=transcription_mm, partid=pconst, name=ku).\\n\",\"ordered_polymer[dna[t16-reverse]:dna[CFP-reverse]:dna[UTR1-reverse]:complex[dna[pconst]:protein[RNAP]-reverse]:dna[ptet-forward]:dna[UTR1-forward]:dna[GFP-forward]:dna[UTR1-forward]:dna[RFP-forward]:dna[t16-forward](circular)] --> dna[dna[t16-reverse]:dna[CFP-reverse]:dna[UTR1-reverse]:dna[pconst-reverse]:dna[ptet-forward]:dna[UTR1-forward]:dna[GFP-forward]:dna[UTR1-forward]:dna[RFP-forward]:dna[t16-forward](circular)]+rna[rna[UTR1-forward]:rna[CFP-forward]:rna[t16-forward]]+protein[RNAP(machinery)]\\n Kf=k_forward * ordered_polymer_t16_r_CFP_r_UTR1_r_dna_pconst_protein_RNAP_machinery_r_ptet_f_UTR1_f_GFP_f_UTR1_f_RFP_f_t16_f_o_circular\\n k_forward=0.05\\n found_key=(mech=None, partid=None, name=ktx).\\n search_key=(mech=transcription_mm, partid=pconst, name=ktx).\\n\",\"dna[dna[t16-reverse]:dna[CFP-reverse]:dna[UTR1-reverse]:dna[pconst-reverse]:dna[ptet-forward]:dna[UTR1-forward]:dna[GFP-forward]:dna[UTR1-forward]:dna[RFP-forward]:dna[t16-forward](circular)]+protein[RNAP(machinery)] <--> ordered_polymer[dna[t16-reverse]:dna[CFP-reverse]:dna[UTR1-reverse]:dna[pconst-reverse]:complex[dna[ptet]:protein[RNAP]-forward]:dna[UTR1-forward]:dna[GFP-forward]:dna[UTR1-forward]:dna[RFP-forward]:dna[t16-forward](circular)]\\n Kf=k_forward * dna_t16_r_CFP_r_UTR1_r_pconst_r_ptet_f_UTR1_f_GFP_f_UTR1_f_RFP_f_t16_f_o_circular * protein_RNAP_machinery\\n Kr=k_reverse * ordered_polymer_t16_r_CFP_r_UTR1_r_pconst_r_dna_ptet_protein_RNAP_machinery_f_UTR1_f_GFP_f_UTR1_f_RFP_f_t16_f_o_circular\\n k_forward=100\\n found_key=(mech=None, partid=None, name=kb).\\n search_key=(mech=transcription_mm, partid=ptet_leak, name=kb).\\n k_reverse=10\\n found_key=(mech=None, partid=None, name=ku).\\n search_key=(mech=transcription_mm, partid=ptet_leak, name=ku).\\n\",\"ordered_polymer[dna[t16-reverse]:dna[CFP-reverse]:dna[UTR1-reverse]:dna[pconst-reverse]:complex[dna[ptet]:protein[RNAP]-forward]:dna[UTR1-forward]:dna[GFP-forward]:dna[UTR1-forward]:dna[RFP-forward]:dna[t16-forward](circular)] --> dna[dna[t16-reverse]:dna[CFP-reverse]:dna[UTR1-reverse]:dna[pconst-reverse]:dna[ptet-forward]:dna[UTR1-forward]:dna[GFP-forward]:dna[UTR1-forward]:dna[RFP-forward]:dna[t16-forward](circular)]+rna[rna[UTR1-forward]:rna[GFP-forward]:rna[UTR1-forward]:rna[RFP-forward]:rna[t16-forward]]+protein[RNAP(machinery)]\\n Kf=k_forward * ordered_polymer_t16_r_CFP_r_UTR1_r_pconst_r_dna_ptet_protein_RNAP_machinery_f_UTR1_f_GFP_f_UTR1_f_RFP_f_t16_f_o_circular\\n k_forward=0.05\\n found_key=(mech=None, partid=None, name=ktx).\\n search_key=(mech=transcription_mm, partid=ptet_leak, name=ktx).\\n\",\"2protein[tetr]+dna[dna[t16-reverse]:dna[CFP-reverse]:dna[UTR1-reverse]:dna[pconst-reverse]:dna[ptet-forward]:dna[UTR1-forward]:dna[GFP-forward]:dna[UTR1-forward]:dna[RFP-forward]:dna[t16-forward](circular)] <--> ordered_polymer[dna[t16-reverse]:dna[CFP-reverse]:dna[UTR1-reverse]:dna[pconst-reverse]:[dna[ptet]:2x_protein[tetr]-forward]:dna[UTR1-forward]:dna[GFP-forward]:dna[UTR1-forward]:dna[RFP-forward]:dna[t16-forward](circular)]\\n Kf=k_forward * protein_tetr^2 * dna_t16_r_CFP_r_UTR1_r_pconst_r_ptet_f_UTR1_f_GFP_f_UTR1_f_RFP_f_t16_f_o_circular\\n Kr=k_reverse * ordered_polymer_t16_r_CFP_r_UTR1_r_pconst_r_dna_ptet_protein_tetr_2x_f_UTR1_f_GFP_f_UTR1_f_RFP_f_t16_f_o_circular\\n k_forward=100\\n found_key=(mech=None, partid=None, name=kb).\\n search_key=(mech=one_step_cooperative_binding, partid=ptet_tetr, name=kb).\\n k_reverse=10\\n found_key=(mech=None, partid=None, name=ku).\\n search_key=(mech=one_step_cooperative_binding, partid=ptet_tetr, name=ku).\\n\",\"ordered_polymer[dna[t16-reverse]:dna[CFP-reverse]:dna[UTR1-reverse]:dna[pconst-reverse]:[dna[ptet]:2x_protein[tetr]-forward]:dna[UTR1-forward]:dna[GFP-forward]:dna[UTR1-forward]:dna[RFP-forward]:dna[t16-forward](circular)]+protein[RNAP(machinery)] <--> ordered_polymer[dna[t16-reverse]:dna[CFP-reverse]:dna[UTR1-reverse]:dna[pconst-reverse]:complex[[dna[ptet]:2x_protein[tetr]]:protein[RNAP]-forward]:dna[UTR1-forward]:dna[GFP-forward]:dna[UTR1-forward]:dna[RFP-forward]:dna[t16-forward](circular)]\\n Kf=k_forward * ordered_polymer_t16_r_CFP_r_UTR1_r_pconst_r_dna_ptet_protein_tetr_2x_f_UTR1_f_GFP_f_UTR1_f_RFP_f_t16_f_o_circular * protein_RNAP_machinery\\n Kr=k_reverse * ordered_polymer_t16_r_CFP_r_UTR1_r_pconst_r_dna_ptet_protein_tetr_2x_protein_RNAP_machinery_f_UTR1_f_GFP_f_UTR1_f_RFP_f_t16_f_o_circular\\n k_forward=100\\n found_key=(mech=None, partid=None, name=kb).\\n search_key=(mech=transcription_mm, partid=ptet_tetr, name=kb).\\n k_reverse=10\\n found_key=(mech=None, partid=None, name=ku).\\n search_key=(mech=transcription_mm, partid=ptet_tetr, name=ku).\\n\",\"ordered_polymer[dna[t16-reverse]:dna[CFP-reverse]:dna[UTR1-reverse]:dna[pconst-reverse]:complex[[dna[ptet]:2x_protein[tetr]]:protein[RNAP]-forward]:dna[UTR1-forward]:dna[GFP-forward]:dna[UTR1-forward]:dna[RFP-forward]:dna[t16-forward](circular)] --> ordered_polymer[dna[t16-reverse]:dna[CFP-reverse]:dna[UTR1-reverse]:dna[pconst-reverse]:[dna[ptet]:2x_protein[tetr]-forward]:dna[UTR1-forward]:dna[GFP-forward]:dna[UTR1-forward]:dna[RFP-forward]:dna[t16-forward](circular)]+rna[rna[UTR1-forward]:rna[GFP-forward]:rna[UTR1-forward]:rna[RFP-forward]:rna[t16-forward]]+protein[RNAP(machinery)]\\n Kf=k_forward * ordered_polymer_t16_r_CFP_r_UTR1_r_pconst_r_dna_ptet_protein_tetr_2x_protein_RNAP_machinery_f_UTR1_f_GFP_f_UTR1_f_RFP_f_t16_f_o_circular\\n k_forward=0.05\\n found_key=(mech=None, partid=None, name=ktx).\\n search_key=(mech=transcription_mm, partid=ptet_tetr, name=ktx).\\n\",\"ordered_polymer[complex[protein[Ribo]:rna[UTR1]-forward]:rna[GFP-forward]:rna[UTR1-forward]:rna[RFP-forward]:rna[t16-forward]]+protein[Ribo(machinery)] <--> ordered_polymer[complex[protein[Ribo]:rna[UTR1]-forward]:rna[GFP-forward]:complex[protein[Ribo]:rna[UTR1]-forward]:rna[RFP-forward]:rna[t16-forward]]\\n Kf=k_forward * ordered_polymer_protein_Ribo_machinery_rna_UTR1_f_GFP_f_UTR1_f_RFP_f_t16_f * protein_Ribo_machinery\\n Kr=k_reverse * ordered_polymer_protein_Ribo_machinery_rna_UTR1_f_GFP_f_protein_Ribo_machinery_rna_UTR1_f_RFP_f_t16_f\\n k_forward=100\\n found_key=(mech=None, partid=None, name=kb).\\n search_key=(mech=translation_mm, partid=UTR1, name=kb).\\n k_reverse=10\\n found_key=(mech=None, partid=None, name=ku).\\n search_key=(mech=translation_mm, partid=UTR1, name=ku).\\n\",\"ordered_polymer[complex[protein[Ribo]:rna[UTR1]-forward]:rna[GFP-forward]:complex[protein[Ribo]:rna[UTR1]-forward]:rna[RFP-forward]:rna[t16-forward]] --> ordered_polymer[complex[protein[Ribo]:rna[UTR1]-forward]:rna[GFP-forward]:rna[UTR1-forward]:rna[RFP-forward]:rna[t16-forward]]+protein[RFP]+protein[Ribo(machinery)]\\n Kf=k_forward * ordered_polymer_protein_Ribo_machinery_rna_UTR1_f_GFP_f_protein_Ribo_machinery_rna_UTR1_f_RFP_f_t16_f\\n k_forward=0.2\\n found_key=(mech=None, partid=None, name=ktl).\\n search_key=(mech=translation_mm, partid=UTR1, name=ktl).\\n\",\"ordered_polymer[rna[UTR1-forward]:rna[GFP-forward]:complex[protein[Ribo]:rna[UTR1]-forward]:rna[RFP-forward]:rna[t16-forward]]+protein[Ribo(machinery)] <--> ordered_polymer[complex[protein[Ribo]:rna[UTR1]-forward]:rna[GFP-forward]:complex[protein[Ribo]:rna[UTR1]-forward]:rna[RFP-forward]:rna[t16-forward]]\\n Kf=k_forward * ordered_polymer_UTR1_f_GFP_f_protein_Ribo_machinery_rna_UTR1_f_RFP_f_t16_f * protein_Ribo_machinery\\n Kr=k_reverse * ordered_polymer_protein_Ribo_machinery_rna_UTR1_f_GFP_f_protein_Ribo_machinery_rna_UTR1_f_RFP_f_t16_f\\n k_forward=100\\n found_key=(mech=None, partid=None, name=kb).\\n search_key=(mech=translation_mm, partid=UTR1, name=kb).\\n k_reverse=10\\n found_key=(mech=None, partid=None, name=ku).\\n search_key=(mech=translation_mm, partid=UTR1, name=ku).\\n\",\"ordered_polymer[complex[protein[Ribo]:rna[UTR1]-forward]:rna[GFP-forward]:complex[protein[Ribo]:rna[UTR1]-forward]:rna[RFP-forward]:rna[t16-forward]] --> ordered_polymer[rna[UTR1-forward]:rna[GFP-forward]:complex[protein[Ribo]:rna[UTR1]-forward]:rna[RFP-forward]:rna[t16-forward]]+protein[GFP]+protein[Ribo(machinery)]\\n Kf=k_forward * ordered_polymer_protein_Ribo_machinery_rna_UTR1_f_GFP_f_protein_Ribo_machinery_rna_UTR1_f_RFP_f_t16_f\\n k_forward=0.2\\n found_key=(mech=None, partid=None, name=ktl).\\n search_key=(mech=translation_mm, partid=UTR1, name=ktl).\\n\",\"rna[rna[UTR1-forward]:rna[GFP-forward]:rna[UTR1-forward]:rna[RFP-forward]:rna[t16-forward]]+protein[Ribo(machinery)] <--> ordered_polymer[complex[protein[Ribo]:rna[UTR1]-forward]:rna[GFP-forward]:rna[UTR1-forward]:rna[RFP-forward]:rna[t16-forward]]\\n Kf=k_forward * rna_UTR1_f_GFP_f_UTR1_f_RFP_f_t16_f * protein_Ribo_machinery\\n Kr=k_reverse * ordered_polymer_protein_Ribo_machinery_rna_UTR1_f_GFP_f_UTR1_f_RFP_f_t16_f\\n k_forward=100\\n found_key=(mech=None, partid=None, name=kb).\\n search_key=(mech=translation_mm, partid=UTR1, name=kb).\\n k_reverse=10\\n found_key=(mech=None, partid=None, name=ku).\\n search_key=(mech=translation_mm, partid=UTR1, name=ku).\\n\",\"ordered_polymer[complex[protein[Ribo]:rna[UTR1]-forward]:rna[GFP-forward]:rna[UTR1-forward]:rna[RFP-forward]:rna[t16-forward]] --> rna[rna[UTR1-forward]:rna[GFP-forward]:rna[UTR1-forward]:rna[RFP-forward]:rna[t16-forward]]+protein[GFP]+protein[Ribo(machinery)]\\n Kf=k_forward * ordered_polymer_protein_Ribo_machinery_rna_UTR1_f_GFP_f_UTR1_f_RFP_f_t16_f\\n k_forward=0.2\\n found_key=(mech=None, partid=None, name=ktl).\\n search_key=(mech=translation_mm, partid=UTR1, name=ktl).\\n\",\"rna[rna[UTR1-forward]:rna[GFP-forward]:rna[UTR1-forward]:rna[RFP-forward]:rna[t16-forward]]+protein[Ribo(machinery)] <--> ordered_polymer[rna[UTR1-forward]:rna[GFP-forward]:complex[protein[Ribo]:rna[UTR1]-forward]:rna[RFP-forward]:rna[t16-forward]]\\n Kf=k_forward * rna_UTR1_f_GFP_f_UTR1_f_RFP_f_t16_f * protein_Ribo_machinery\\n Kr=k_reverse * ordered_polymer_UTR1_f_GFP_f_protein_Ribo_machinery_rna_UTR1_f_RFP_f_t16_f\\n k_forward=100\\n found_key=(mech=None, partid=None, name=kb).\\n search_key=(mech=translation_mm, partid=UTR1, name=kb).\\n k_reverse=10\\n found_key=(mech=None, partid=None, name=ku).\\n search_key=(mech=translation_mm, partid=UTR1, name=ku).\\n\",\"ordered_polymer[rna[UTR1-forward]:rna[GFP-forward]:complex[protein[Ribo]:rna[UTR1]-forward]:rna[RFP-forward]:rna[t16-forward]] --> rna[rna[UTR1-forward]:rna[GFP-forward]:rna[UTR1-forward]:rna[RFP-forward]:rna[t16-forward]]+protein[RFP]+protein[Ribo(machinery)]\\n Kf=k_forward * ordered_polymer_UTR1_f_GFP_f_protein_Ribo_machinery_rna_UTR1_f_RFP_f_t16_f\\n k_forward=0.2\\n found_key=(mech=None, partid=None, name=ktl).\\n search_key=(mech=translation_mm, partid=UTR1, name=ktl).\\n\",\"rna[rna[UTR1-forward]:rna[CFP-forward]:rna[t16-forward]]+protein[Ribo(machinery)] <--> ordered_polymer[complex[protein[Ribo]:rna[UTR1]-forward]:rna[CFP-forward]:rna[t16-forward]]\\n Kf=k_forward * rna_UTR1_f_CFP_f_t16_f * protein_Ribo_machinery\\n Kr=k_reverse * ordered_polymer_protein_Ribo_machinery_rna_UTR1_f_CFP_f_t16_f\\n k_forward=100\\n found_key=(mech=None, partid=None, name=kb).\\n search_key=(mech=translation_mm, partid=UTR1, name=kb).\\n k_reverse=10\\n found_key=(mech=None, partid=None, name=ku).\\n search_key=(mech=translation_mm, partid=UTR1, name=ku).\\n\",\"ordered_polymer[complex[protein[Ribo]:rna[UTR1]-forward]:rna[CFP-forward]:rna[t16-forward]] --> rna[rna[UTR1-forward]:rna[CFP-forward]:rna[t16-forward]]+protein[CFP]+protein[Ribo(machinery)]\\n Kf=k_forward * ordered_polymer_protein_Ribo_machinery_rna_UTR1_f_CFP_f_t16_f\\n k_forward=0.2\\n found_key=(mech=None, partid=None, name=ktl).\\n search_key=(mech=translation_mm, partid=UTR1, name=ktl).\\n\",\"dna[cellular_processes]+protein[RNAP(machinery)] <--> complex[dna[cellular_processes]:protein[RNAP]]\\n Kf=k_forward * dna_cellular_processes * protein_RNAP_machinery\\n Kr=k_reverse * complex_dna_cellular_processes_protein_RNAP_machinery\\n k_forward=500\\n found_key=(mech=transcription, partid=None, name=kb).\\n search_key=(mech=transcription_mm, partid=average_promoter, name=kb).\\n k_reverse=50\\n found_key=(mech=transcription, partid=None, name=ku).\\n search_key=(mech=transcription_mm, partid=average_promoter, name=ku).\\n\",\"complex[dna[cellular_processes]:protein[RNAP]] --> dna[cellular_processes]+rna[cellular_processes]+protein[RNAP(machinery)]\\n Kf=k_forward * complex_dna_cellular_processes_protein_RNAP_machinery\\n k_forward=0.1\\n found_key=(mech=transcription, partid=None, name=ktx).\\n search_key=(mech=transcription_mm, partid=average_promoter, name=ktx).\\n\",\"rna[cellular_processes]+protein[Ribo(machinery)] <--> complex[protein[Ribo]:rna[cellular_processes]]\\n Kf=k_forward * rna_cellular_processes * protein_Ribo_machinery\\n Kr=k_reverse * complex_protein_Ribo_machinery_rna_cellular_processes\\n k_forward=500\\n found_key=(mech=translation, partid=None, name=kb).\\n search_key=(mech=translation_mm, partid=average_rbs, name=kb).\\n k_reverse=5\\n found_key=(mech=translation, partid=None, name=ku).\\n search_key=(mech=translation_mm, partid=average_rbs, name=ku).\\n\",\"complex[protein[Ribo]:rna[cellular_processes]] --> rna[cellular_processes]+protein[cellular_processes]+protein[Ribo(machinery)]\\n Kf=k_forward * complex_protein_Ribo_machinery_rna_cellular_processes\\n k_forward=0.1\\n found_key=(mech=translation, partid=None, name=ktl).\\n search_key=(mech=translation_mm, partid=average_rbs, name=ktl).\\n\",\"rna[cellular_processes]+protein[RNAase(machinery)] <--> complex[protein[RNAase]:rna[cellular_processes]]\\n Kf=k_forward * rna_cellular_processes * protein_RNAase_machinery\\n Kr=k_reverse * complex_protein_RNAase_machinery_rna_cellular_processes\\n k_forward=500\\n found_key=(mech=rna_degredation, partid=None, name=kb).\\n search_key=(mech=rna_degredation_mm, partid=cellular_processes, name=kb).\\n k_reverse=50\\n found_key=(mech=rna_degredation, partid=None, name=ku).\\n search_key=(mech=rna_degredation_mm, partid=cellular_processes, name=ku).\\n\",\"complex[protein[RNAase]:rna[cellular_processes]] --> protein[RNAase(machinery)]\\n Kf=k_forward * complex_protein_RNAase_machinery_rna_cellular_processes\\n k_forward=0.1\\n found_key=(mech=rna_degredation, partid=None, name=kdeg).\\n search_key=(mech=rna_degredation_mm, partid=cellular_processes, name=kdeg).\\n\",\"rna[rna[UTR1-forward]:rna[GFP-forward]:rna[UTR1-forward]:rna[RFP-forward]:rna[t16-forward]] --> \\n Kf=k_forward * rna_UTR1_f_GFP_f_UTR1_f_RFP_f_t16_f\\n k_forward=0.5\\n found_key=(mech=None, partid=None, name=kdil).\\n search_key=(mech=global_degredation_via_dilution, partid=rna_UTR1_f_GFP_f_UTR1_f_RFP_f_t16_f, name=kdil).\\n\",\"protein[GFP] --> \\n Kf=k_forward * protein_GFP\\n k_forward=0.5\\n found_key=(mech=None, partid=None, name=kdil).\\n search_key=(mech=global_degredation_via_dilution, partid=protein_GFP, name=kdil).\\n\",\"protein[RFP] --> \\n Kf=k_forward * protein_RFP\\n k_forward=0.5\\n found_key=(mech=None, partid=None, name=kdil).\\n search_key=(mech=global_degredation_via_dilution, partid=protein_RFP, name=kdil).\\n\",\"protein[tetr] --> \\n Kf=k_forward * protein_tetr\\n k_forward=0.5\\n found_key=(mech=None, partid=None, name=kdil).\\n search_key=(mech=global_degredation_via_dilution, partid=protein_tetr, name=kdil).\\n\",\"protein[CFP] --> \\n Kf=k_forward * protein_CFP\\n k_forward=0.5\\n found_key=(mech=None, partid=None, name=kdil).\\n search_key=(mech=global_degredation_via_dilution, partid=protein_CFP, name=kdil).\\n\",\"rna[rna[UTR1-forward]:rna[CFP-forward]:rna[t16-forward]] --> \\n Kf=k_forward * rna_UTR1_f_CFP_f_t16_f\\n k_forward=0.5\\n found_key=(mech=None, partid=None, name=kdil).\\n search_key=(mech=global_degredation_via_dilution, partid=rna_UTR1_f_CFP_f_t16_f, name=kdil).\\n\",\"rna[cellular_processes] --> \\n Kf=k_forward * rna_cellular_processes\\n k_forward=0.5\\n found_key=(mech=None, partid=None, name=kdil).\\n search_key=(mech=global_degredation_via_dilution, partid=rna_cellular_processes, name=kdil).\\n\",\"protein[cellular_processes] --> \\n Kf=k_forward * protein_cellular_processes\\n k_forward=0.5\\n found_key=(mech=None, partid=None, name=kdil).\\n search_key=(mech=global_degredation_via_dilution, partid=protein_cellular_processes, name=kdil).\\n\"],\"type\":[\"nothing\",\"rna\",\"ordered_polymer\",\"complex\",\"ordered_polymer\",\"complex\",\"protein\",\"ordered_polymer\",\"protein\",\"ordered_polymer\",\"protein\",\"protein\",\"ordered_polymer\",\"ordered_polymer\",\"dna\",\"ordered_polymer\",\"ordered_polymer\",\"protein\",\"protein\",\"protein\",\"dna\",\"ordered_polymer\",\"ordered_polymer\",\"rna\",\"complex\",\"rna\",\"protein\",\"ordered_polymer\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\"]},\"selected\":{\"id\":\"2910\",\"type\":\"Selection\"},\"selection_policy\":{\"id\":\"2909\",\"type\":\"UnionRenderers\"}},\"id\":\"2651\",\"type\":\"ColumnDataSource\"},{\"attributes\":{\"line_color\":{\"value\":\"#abdda4\"},\"line_join\":\"round\",\"line_width\":{\"value\":5}},\"id\":\"2678\",\"type\":\"MultiLine\"},{\"attributes\":{},\"id\":\"2914\",\"type\":\"Selection\"},{\"attributes\":{\"fill_color\":{\"value\":\"#fdae61\"},\"size\":{\"units\":\"screen\",\"value\":8}},\"id\":\"2698\",\"type\":\"Square\"},{\"attributes\":{\"data_source\":{\"id\":\"2651\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"2663\",\"type\":\"Circle\"},\"hover_glyph\":null,\"muted_glyph\":null,\"view\":{\"id\":\"2653\",\"type\":\"CDSView\"}},\"id\":\"2652\",\"type\":\"GlyphRenderer\"},{\"attributes\":{},\"id\":\"2622\",\"type\":\"MultiLine\"},{\"attributes\":{\"fill_alpha\":{\"value\":0},\"fill_color\":{\"field\":\"color\"},\"line_alpha\":{\"value\":0},\"size\":{\"units\":\"screen\",\"value\":12}},\"id\":\"2663\",\"type\":\"Circle\"},{\"attributes\":{\"fill_color\":{\"value\":\"#2b83ba\"},\"size\":{\"units\":\"screen\",\"value\":8}},\"id\":\"2693\",\"type\":\"Square\"},{\"attributes\":{},\"id\":\"2913\",\"type\":\"UnionRenderers\"},{\"attributes\":{},\"id\":\"2739\",\"type\":\"EdgesAndLinkedNodes\"},{\"attributes\":{\"graph_layout\":{\"0\":[-40.488698255587884,-99.98952472799688],\"1\":[49.767898243079706,-10.735542748413387],\"10\":[47.30577950999651,-19.722072745306033],\"11\":[-18.972672268659107,0.7224877146550948],\"12\":[-38.97590329134622,13.706671906581116],\"13\":[-26.696823497511414,2.0198918985199303],\"14\":[-13.580372442442618,7.942510540105816],\"15\":[-1.522992093191837,2.410324244969439],\"16\":[51.9401620102646,7.188589525735296],\"17\":[-88.77554217777883,-42.33994511672994],\"18\":[-22.785000824122843,18.63983422158091],\"19\":[-17.75865238066117,98.57658294557555],\"2\":[39.822162176963296,-3.169631346880351],\"20\":[-0.999696774275828,38.24616633012679],\"21\":[-47.309180478026114,-6.9368259637582605],\"22\":[-11.0257956154718,18.558740697820543],\"23\":[61.0083309040473,-35.28880913795553],\"24\":[-0.33725646529628595,45.7600197635441],\"25\":[20.91244754068218,-46.940533105728846],\"26\":[-108.14760273559631,0.6386626690079918],\"27\":[-33.958674477233366,-18.19174915727836],\"28\":[-3.2204830526287833,8.920283443327545],\"29\":[2.6692336714589935,-9.810640833347529],\"3\":[33.595548668889585,-46.31505693503453],\"30\":[-26.506129037015288,18.56229030146137],\"31\":[-40.81082856915895,2.6617955850989308],\"32\":[-52.26719757077504,-13.527570500433503],\"33\":[-3.64165140314341,-1.9213288908724198],\"34\":[7.93913477198736,-3.244215121968057],\"35\":[-30.726842861111997,6.6118505212654135],\"36\":[-50.125463104851065,21.270517739865284],\"37\":[-37.065874978864876,-11.758585803016725],\"38\":[-54.929942818866245,-5.140186577053265],\"39\":[-11.598851698563433,12.139473742098522],\"4\":[68.11599882163907,-34.223578386314124],\"40\":[-7.502176425196686,27.17300349098635],\"41\":[-9.242723146867734,3.4099756555704372],\"42\":[4.3510147815826885,6.068020923643697],\"43\":[-21.82687972050324,10.327497982394673],\"44\":[-27.359455282844813,-8.151480263902494],\"45\":[-38.07706448880218,-28.27660824918838],\"46\":[55.003127335040276,-3.1763271004972435],\"47\":[50.567426344157354,16.618499455204944],\"48\":[45.40904618327813,-1.2811070115462924],\"49\":[57.540009004652376,13.1526144535564],\"5\":[9.284244879111066,-55.85437784744294],\"50\":[56.01129701377114,-13.030345413668693],\"51\":[68.00394889835104,-4.298487602280719],\"52\":[42.91385402950879,-10.15674328516365],\"53\":[34.45705055107074,0.7585426486960841],\"54\":[61.33222563727731,-31.275605461882986],\"55\":[72.92093486564866,-36.72102316186766],\"56\":[-3.1444933574144245,37.18549741272463],\"57\":[1.6536693582973179,52.12244558392136],\"58\":[31.3188000210444,-40.76642655885539],\"59\":[35.98453448478318,-50.37006150959009],\"6\":[-70.57673646194051,68.3354959677419],\"60\":[13.053514151447013,-52.585046793052776],\"61\":[6.7952691710658915,-57.81776133513421],\"62\":[52.27534534702393,-8.68356477340083],\"63\":[-71.59751122638255,67.30696163392028],\"64\":[-89.8284254911928,-41.34388446478372],\"65\":[-23.381653206516084,23.766736482913657],\"66\":[-19.194185826317618,98.38032450453473],\"67\":[60.69707820360041,-38.312536337529956],\"68\":[17.618330479043003,-46.43364417095276],\"69\":[-109.58408876455316,0.478196266169271],\"7\":[61.06261872553295,-6.546093065519916],\"8\":[10.738556388975034,-52.5968428985783],\"9\":[1.9206148002173835,-2.130222189331091]}},\"id\":\"2646\",\"type\":\"StaticLayoutProvider\"},{\"attributes\":{\"source\":{\"id\":\"2619\",\"type\":\"ColumnDataSource\"}},\"id\":\"2621\",\"type\":\"CDSView\"},{\"attributes\":{\"bottom_units\":\"screen\",\"fill_alpha\":{\"value\":0.5},\"fill_color\":{\"value\":\"lightgrey\"},\"left_units\":\"screen\",\"level\":\"overlay\",\"line_alpha\":{\"value\":1.0},\"line_color\":{\"value\":\"black\"},\"line_dash\":[4,4],\"line_width\":{\"value\":2},\"render_mode\":\"css\",\"right_units\":\"screen\",\"top_units\":\"screen\"},\"id\":\"2908\",\"type\":\"BoxAnnotation\"},{\"attributes\":{\"data_source\":{\"id\":\"2639\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"2638\",\"type\":\"MultiLine\"},\"hover_glyph\":null,\"muted_glyph\":null,\"view\":{\"id\":\"2641\",\"type\":\"CDSView\"}},\"id\":\"2640\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"attachment\":\"right\",\"callback\":null,\"renderers\":[{\"id\":\"2633\",\"type\":\"GraphRenderer\"}],\"tooltips\":[[\"name\",\"@species\"],[\"type\",\"@type\"]]},\"id\":\"2724\",\"type\":\"HoverTool\"},{\"attributes\":{},\"id\":\"2912\",\"type\":\"Selection\"},{\"attributes\":{\"attachment\":\"right\",\"callback\":null,\"renderers\":[{\"id\":\"2617\",\"type\":\"GraphRenderer\"}],\"tooltips\":[[\"reaction\",\"@species\"],[\"type\",\"@type\"],[\"k_f\",\"@k\"],[\"k_r\",\"@k_r\"]]},\"id\":\"2725\",\"type\":\"HoverTool\"},{\"attributes\":{\"line_alpha\":{\"value\":0.2},\"line_join\":\"round\",\"line_width\":{\"value\":4}},\"id\":\"2668\",\"type\":\"MultiLine\"},{\"attributes\":{},\"id\":\"2878\",\"type\":\"LinearScale\"},{\"attributes\":{\"data_source\":{\"id\":\"2619\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"2693\",\"type\":\"Square\"},\"hover_glyph\":{\"id\":\"2703\",\"type\":\"Square\"},\"muted_glyph\":null,\"selection_glyph\":{\"id\":\"2698\",\"type\":\"Square\"},\"view\":{\"id\":\"2621\",\"type\":\"CDSView\"}},\"id\":\"2620\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"text\":\"\"},\"id\":\"2879\",\"type\":\"Title\"},{\"attributes\":{\"source\":{\"id\":\"2635\",\"type\":\"ColumnDataSource\"}},\"id\":\"2637\",\"type\":\"CDSView\"},{\"attributes\":{\"edge_renderer\":{\"id\":\"2656\",\"type\":\"GlyphRenderer\"},\"inspection_policy\":{\"id\":\"2739\",\"type\":\"EdgesAndLinkedNodes\"},\"layout_provider\":{\"id\":\"2662\",\"type\":\"StaticLayoutProvider\"},\"node_renderer\":{\"id\":\"2652\",\"type\":\"GlyphRenderer\"},\"selection_policy\":{\"id\":\"2737\",\"type\":\"NodesAndLinkedEdges\"}},\"id\":\"2649\",\"type\":\"GraphRenderer\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"size\":{\"units\":\"screen\",\"value\":12}},\"id\":\"2708\",\"type\":\"Circle\"},{\"attributes\":{},\"id\":\"2917\",\"type\":\"UnionRenderers\"},{\"attributes\":{\"source\":{\"id\":\"2655\",\"type\":\"ColumnDataSource\"}},\"id\":\"2657\",\"type\":\"CDSView\"},{\"attributes\":{},\"id\":\"2909\",\"type\":\"UnionRenderers\"},{\"attributes\":{\"callback\":null},\"id\":\"2726\",\"type\":\"TapTool\"},{\"attributes\":{\"callback\":null,\"data\":{\"end\":[50,52,62,48,52,53,58,59,54,55,60,61,63,46,50,51,60,28,29,33,34,46,48,50,52,54,58,28,31,33,35,37,39,41,44,56,30,31,35,36,35,43,44,39,41,43,33,41,42,46,47,48,49,64,30,43,65,66,56,31,32,37,38,28,30,39,40,54,67,56,57,58,60,68,69,37,44,45,22,11,9,22,1,11,18,22,12,12,11,21,12,1,11,15,11,9,15,23,11,13,11,12,13,23,11,27,11,21,27,23,11,14,11,22,14,23,11,14,11,15,14,1,11,18,14,13,13,11,27,13,1,11,7,10,16,7,17,10,2,10,16,2,6,10,1,10,7,1,6,10,1,10,2,1,17,10,23,10,4,23,19,10,20,11,24,20,25,11,25,10,3,25,26,10,25,8,5,8,0,0,0,0,0,0,0,0],\"start\":[1,1,1,2,2,2,3,3,4,4,5,5,6,7,7,7,8,9,9,9,9,10,10,10,10,10,10,11,11,11,11,11,11,11,11,11,12,12,12,12,13,13,13,14,14,14,15,15,15,16,16,16,16,17,18,18,18,19,20,21,21,21,21,22,22,22,22,23,23,24,24,25,25,25,26,27,27,27,28,28,28,29,29,29,30,30,30,31,31,31,32,32,32,33,33,33,34,34,34,35,35,35,36,36,36,37,37,37,38,38,38,39,39,39,40,40,40,41,41,41,42,42,42,43,43,43,44,44,44,45,45,45,46,46,46,47,47,47,48,48,48,49,49,49,50,50,50,51,51,51,52,52,52,53,53,53,54,54,54,55,55,55,56,56,56,57,57,57,58,58,58,59,59,59,60,60,60,61,62,63,64,65,66,67,68,69],\"weight\":[1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1],\"xs\":[[49.767898243079706,52.7261758840939,51.084536452872236,56.01129701377114,52.809490852357115,52.7261758840939],[49.767898243079706,46.40144078634582,47.43899092797581,42.91385402950879,47.01825635767906,46.40144078634582],[49.767898243079706,49.56672264722972,50.50758719152091,52.27534534702393,47.34100045312986,49.56672264722972],[39.822162176963296,42.09335421514959,42.10751077713164,45.40904618327813,40.506371659357946,42.09335421514959],[39.822162176963296,41.49760849175166,38.875516173317465,42.91385402950879,43.447892989431466,41.49760849175166],[39.822162176963296,37.28103383154158,39.42770660385063,34.45705055107074,36.4739409575773,37.28103383154158],[33.595548668889585,32.6474408052307,35.27543152165834,31.3188000210444,30.649701867885934,32.6474408052307],[33.595548668889585,34.20792629819497,31.632573200551533,35.98453448478318,35.94053056285255,34.20792629819497],[68.11599882163907,64.54222922417188,66.29996581398042,61.33222563727731,64.30718446768809,64.54222922417188],[68.11599882163907,69.81537929269503,67.92583216618375,72.92093486564866,70.23178036785018,69.81537929269503],[9.284244879111066,10.409515982704427,11.420493776380564,13.053514151447013,8.144335721683131,10.409515982704427],[9.284244879111066,9.54321632654533,8.646637498134684,6.7952691710658915,11.743306686575332,9.54321632654533],[-70.57673646194051,-69.13202610697866,-70.32171220834054,-71.59751122638255,-66.77281668426376,-69.13202610697866],[61.06261872553295,58.061952785923175,60.00248142390369,55.003127335040276,57.572403378196796,58.061952785923175],[61.06261872553295,58.16221483998635,56.70016902531166,56.01129701377114,60.64456637067398,58.16221483998635],[61.06261872553295,64.6741574505119,64.6545344878563,68.00394889835104,63.11426621418045,64.6741574505119],[10.738556388975034,9.55355958960805,8.73618218957888,13.053514151447013,8.710704505761496,9.55355958960805],[1.9206148002173835,-1.744111950736012,0.8727511105231991,-3.2204830526287833,-3.660646131059727,-1.744111950736012],[1.9206148002173835,2.329693918988488,-0.23904601648989088,2.6692336714589935,4.73737035588177,2.329693918988488],[1.9206148002173835,-0.1441170133587515,0.7792476482194428,-3.64165140314341,0.5916027802457919,-0.1441170133587515],[1.9206148002173835,4.497591682414594,3.22632260463108,7.93913477198736,4.136336242804214,4.497591682414594],[47.30577950999651,53.52680919503913,55.44337353629353,55.003127335040276,50.90994109576192,53.52680919503913],[47.30577950999651,45.76714717251526,48.338961495870265,45.40904618327813,43.3652010243994,45.76714717251526],[47.30577950999651,53.236370014768575,54.101801883052666,56.01129701377114,51.05462850225094,53.236370014768575],[47.30577950999651,44.37429306764286,46.99263711797913,42.91385402950879,42.44872039161736,44.37429306764286],[47.30577950999651,58.63069115874734,56.40048341554221,61.33222563727731,59.57940360870812,58.63069115874734],[47.30577950999651,33.43602650169995,31.947476364036834,31.3188000210444,35.928900586088616,33.43602650169995],[-18.972672268659107,-6.325204597617457,-5.907460273813593,-3.2204830526287833,-8.215699344692723,-6.325204597617457],[-18.972672268659107,-37.324548129796106,-36.276536240972064,-40.81082856915895,-36.718813968188705,-37.324548129796106],[-18.972672268659107,-7.09074157252475,-8.333644957647781,-3.64165140314341,-7.4839427247173615,-7.09074157252475],[-18.972672268659107,-27.59765618857056,-25.735577040192155,-30.726842861111997,-27.975379677447325,-27.59765618857056],[-18.972672268659107,-34.18485370479837,-34.92109935249677,-37.065874978864876,-32.081971713275834,-34.18485370479837],[-18.972672268659107,-13.497754388928058,-11.848065444222753,-11.598851698563433,-16.048203579105206,-13.497754388928058],[-18.972672268659107,-12.616398120835669,-12.750966779747822,-9.242723146867734,-14.082160175610607,-12.616398120835669],[-18.972672268659107,-24.95539230775285,-26.2021373122166,-27.359455282844813,-22.56826008568092,-24.95539230775285],[-18.972672268659107,-4.538160745329283,-2.5754529250259197,-3.1444933574144245,-7.161966253689128,-4.538160745329283],[-38.97590329134622,-29.767591840972905,-29.634011096016142,-26.506129037015288,-31.448274525801068,-29.767591840972905],[-38.97590329134622,-40.23722288965558,-42.56737323942703,-40.81082856915895,-37.634977926876715,-40.23722288965558],[-38.97590329134622,-33.38039095146834,-35.63993853262026,-30.726842861111997,-32.37957592221025,-33.38039095146834],[-38.97590329134622,-47.2290653385996,-45.13859146436639,-50.125463104851065,-47.945608902369244,-47.2290653385996],[-26.696823497511414,-28.418167760564465,-25.99160320074947,-30.726842861111997,-29.749593132449508,-28.418167760564465],[-26.696823497511414,-23.59688925848634,-21.859950040423936,-21.82687972050324,-26.173447185822894,-23.59688925848634],[-26.696823497511414,-27.131923997818824,-29.57267002559956,-27.359455282844813,-24.583246617266564,-27.131923997818824],[-13.580372442442618,-13.09314034764559,-11.186854114464587,-11.598851698563433,-15.708254798924788,-13.09314034764559],[-13.580372442442618,-11.662637774112714,-14.042761496719466,-9.242723146867734,-10.43042063182658,-11.662637774112714],[-13.580372442442618,-18.464669740425997,-16.972658717100323,-21.82687972050324,-18.361788565036264,-18.464669740425997],[-1.522992093191837,-2.103852279080908,-3.9848824158524336,-3.64165140314341,0.5066456305815703,-2.103852279080908],[-1.522992093191837,-5.77170396064324,-4.62739857777019,-9.242723146867734,-5.269502595126418,-5.77170396064324],[-1.522992093191837,1.3799428178403201,1.9967397398869418,4.3510147815826885,-0.6462067397861642,1.3799428178403201],[51.9401620102646,54.01123607159885,51.37847381860621,55.003127335040276,56.17348647452545,54.01123607159885],[51.9401620102646,51.07161590840037,53.66512367189362,50.567426344157354,48.717274647728104,51.07161590840037],[51.9401620102646,47.54631455501827,46.073474869023094,45.40904618327813,50.032985225053075,47.54631455501827],[51.9401620102646,55.14426355521488,56.39857789191313,57.540009004652376,52.753507488209216,55.14426355521488],[-88.77554217777883,-87.28589447388651,-84.96477761697344,-89.8284254911928,-88.40094064856322,-87.28589447388651],[-22.785000824122843,-23.006888738310856,-22.229027646030318,-26.506129037015288,-22.12485616335944,-23.006888738310856],[-22.785000824122843,-22.227653522443042,-24.806264872247553,-21.82687972050324,-19.839152550619335,-22.227653522443042],[-22.785000824122843,-22.9770650393099,-20.397864560865337,-23.381653206516084,-25.364345763963566,-22.9770650393099],[-17.75865238066117,-15.726443395367312,-15.242603745517327,-19.194185826317618,-14.565330652877424,-15.726443395367312],[-0.999696774275828,-0.007165364464728707,-0.37127566034413606,-3.1444933574144245,1.8451624937966664,-0.007165364464728707],[-47.309180478026114,-42.772981519842325,-41.16817205424818,-40.81082856915895,-45.308554516648,-42.772981519842325],[-47.309180478026114,-50.16313699716349,-51.66191910546232,-52.26719757077504,-47.66627629937675,-50.16313699716349],[-47.309180478026114,-40.23257595895293,-42.04839360881333,-37.065874978864876,-39.918909191617374,-40.23257595895293],[-47.309180478026114,-51.52333375265364,-50.141694220648105,-54.929942818866245,-51.28902001107724,-51.52333375265364],[-11.0257956154718,-5.423145968983029,-7.888412554771394,-3.2204830526287833,-4.002730812019588,-5.423145968983029],[-11.0257956154718,-23.006129129025734,-22.17542888788665,-26.506129037015288,-22.17657537596635,-23.006129129025734],[-11.0257956154718,-11.287639888625792,-13.703924386695379,-11.598851698563433,-8.723729486535113,-11.287639888625792],[-11.0257956154718,-8.827263361255852,-6.827641554121158,-7.502176425196686,-11.45545115012971,-8.827263361255852],[61.0083309040473,61.050665679442425,63.47578300953465,61.33222563727731,58.49198804738144,61.050665679442425],[61.0083309040473,61.05546316969371,58.65360524636345,60.69707820360041,63.627323975040866,61.05546316969371],[-0.33725646529628595,-2.055495893512338,-4.173116877962819,-3.1444933574144245,0.5787000728369263,-2.055495893512338],[-0.33725646529628595,0.6084309904004737,2.746437201301501,1.6536693582973179,-2.0253927121607282,0.6084309904004737],[20.91244754068218,28.308716193007413,28.87042124012711,31.3188000210444,26.319152908816715,28.308716193007413],[20.91244754068218,15.896269728040584,15.112119624970921,13.053514151447013,18.028904523865712,15.896269728040584],[20.91244754068218,21.077615369355097,22.27830309105766,17.618330479043003,21.517868135422464,21.077615369355097],[-108.14760273559631,-106.10572401851665,-105.55827112233483,-109.58408876455316,-105.00318573906917,-106.10572401851665],[-33.958674477233366,-35.54364323471897,-32.931432916831525,-37.065874978864876,-37.43377029553409,-35.54364323471897],[-33.958674477233366,-29.281848100729302,-27.648662740827035,-27.359455282844813,-31.826936442978933,-29.281848100729302],[-33.958674477233366,-36.75384086932988,-38.75444858381747,-38.07706448880218,-34.12555105278515,-36.75384086932988],[-3.2204830526287833,-8.823132699117554,-6.35786611332919,-11.0257956154718,-10.243547856080994,-8.823132699117554],[-3.2204830526287833,-15.867950723670432,-16.2856950474743,-18.972672268659107,-13.977455976595166,-15.867950723670432],[-3.2204830526287833,0.4442436983246121,-2.172619362934599,1.9206148002173835,2.3607778786483253,0.4442436983246121],[2.6692336714589935,-9.504222020127667,-6.891940801877743,-11.0257956154718,-11.394732179649736,-9.504222020127667],[2.6692336714589935,46.26857290567522,45.38952151572285,49.767898243079706,45.48769028958274,46.26857290567522],[2.6692336714589935,-15.825614575225655,-13.985144641128176,-18.972672268659107,-16.173251582793952,-15.825614575225655],[-26.506129037015288,-26.284241122827275,-27.062102215107814,-22.785000824122843,-27.166273697778692,-26.284241122827275],[-26.506129037015288,-14.525795523461355,-15.356495764600439,-11.0257956154718,-15.35534927652074,-14.525795523461355],[-26.506129037015288,-35.71444048738861,-35.84802123234537,-38.97590329134622,-34.033757802560444,-35.71444048738861],[-40.81082856915895,-39.549508970849594,-37.21935862107814,-38.97590329134622,-42.151753933628456,-39.549508970849594],[-40.81082856915895,-22.458952708021947,-23.50696459684599,-18.972672268659107,-23.06468686962935,-22.458952708021947],[-40.81082856915895,-45.34702752734274,-46.95183699293688,-47.309180478026114,-42.81145453053706,-45.34702752734274],[-52.26719757077504,-40.510973544634936,-38.62834385244066,-38.97590329134622,-43.121776547228464,-40.510973544634936],[-52.26719757077504,46.26920783068235,45.507774337338766,49.767898243079706,45.37100849992588,46.26920783068235],[-52.26719757077504,-22.19034517568923,-21.969821425072904,-18.972672268659107,-23.937198765265343,-22.19034517568923],[-3.64165140314341,-3.060791217254339,-1.1797610804828131,-1.522992093191837,-5.671289126916816,-3.060791217254339],[-3.64165140314341,-15.523582099277768,-14.280678714154735,-18.972672268659107,-15.130380947085156,-15.523582099277768],[-3.64165140314341,-1.5769195895672752,-2.5002842511454695,1.9206148002173835,-2.3126393831718195,-1.5769195895672752],[7.93913477198736,1.4814134605255298,3.4764415109600346,-1.522992093191837,0.9115501106285568,1.4814134605255298],[7.93913477198736,58.012175674681494,56.00929418355259,61.0083309040473,58.59380607507807,58.012175674681494],[7.93913477198736,-15.51008372863664,-14.32427778270759,-18.972672268659107,-15.053382073146835,-15.51008372863664],[-30.726842861111997,-29.005498598058946,-31.43206315787394,-26.696823497511414,-27.674073226173903,-29.005498598058946],[-30.726842861111997,-22.101858941200543,-23.963938089578953,-18.972672268659107,-21.72413545232378,-22.101858941200543],[-30.726842861111997,-36.322355200989875,-34.062807619837955,-38.97590329134622,-37.32317023024797,-36.322355200989875],[-50.125463104851065,-29.401044258028882,-31.629556795741248,-26.696823497511414,-28.45530127370844,-29.401044258028882],[-50.125463104851065,57.88905715382995,56.01530751066454,61.0083309040473,58.28315341444097,57.88905715382995],[-50.125463104851065,-21.894357481540005,-23.963827909992926,-18.972672268659107,-21.2108126736573,-21.894357481540005],[-37.065874978864876,-35.48090622137927,-38.09311653926672,-33.958674477233366,-33.59077916056416,-35.48090622137927],[-37.065874978864876,-21.85369354272561,-21.117447895027215,-18.972672268659107,-23.956575534248145,-21.85369354272561],[-37.065874978864876,-44.14247949793806,-42.32666184807766,-47.309180478026114,-44.45614626527362,-44.14247949793806],[-54.929942818866245,-36.93019630468305,-38.95593638509692,-33.958674477233366,-36.3140222564309,-36.93019630468305],[-54.929942818866245,57.62098537138726,56.1884016990396,61.0083309040473,57.44675358711407,57.62098537138726],[-54.929942818866245,-22.427057972295728,-22.844064555875057,-18.972672268659107,-23.64866790664058,-22.427057972295728],[-11.598851698563433,-12.08608379336046,-13.992370026541463,-13.580372442442618,-9.470969342081261,-12.08608379336046],[-11.598851698563433,-17.07376957829448,-18.72345852299979,-18.972672268659107,-14.523320388117336,-17.07376957829448],[-11.598851698563433,-11.33700742540944,-8.920722927339854,-11.0257956154718,-13.90091782750012,-11.33700742540944],[-7.502176425196686,-12.525559164486591,-14.659143510168581,-13.580372442442618,-9.89161538911935,-12.525559164486591],[-7.502176425196686,58.42191684800952,56.124142466267344,61.0083309040473,59.49280426401622,58.42191684800952],[-7.502176425196686,-17.58016673126252,-19.543510187088593,-18.972672268659107,-14.956276720812635,-17.58016673126252],[-9.242723146867734,-11.160457815197638,-8.780334092590884,-13.580372442442618,-12.39267495748377,-11.160457815197638],[-9.242723146867734,-15.598997294691173,-15.464428635779019,-18.972672268659107,-14.133235239916235,-15.598997294691173],[-9.242723146867734,-4.9940112794163305,-6.13831666228938,-1.522992093191837,-5.496212644933154,-4.9940112794163305],[4.3510147815826885,-10.099341012613579,-9.013787340875545,-13.580372442442618,-9.533638545141077,-10.099341012613579],[4.3510147815826885,46.485365723661765,44.839326275940536,49.767898243079706,46.57430863717752,46.485365723661765],[4.3510147815826885,-15.561125766058414,-15.310470239043687,-18.972672268659107,-14.193485905576939,-15.561125766058414],[-21.82687972050324,-22.38422702218304,-19.805615672378533,-22.785000824122843,-24.772727994006747,-22.38422702218304],[-21.82687972050324,-16.94258242251986,-18.434593445845536,-13.580372442442618,-17.045463597909595,-16.94258242251986],[-21.82687972050324,-24.926813959528314,-26.663753177590717,-26.696823497511414,-22.35025603219176,-24.926813959528314],[-27.359455282844813,-26.924354782537403,-24.483608754756666,-26.696823497511414,-29.473032163089663,-26.924354782537403],[-27.359455282844813,-21.37673524375107,-20.129990239287324,-18.972672268659107,-23.763867465822997,-21.37673524375107],[-27.359455282844813,-32.03628165934887,-33.669467019251144,-33.958674477233366,-29.491193317099246,-32.03628165934887],[-38.07706448880218,-27.92756188438053,-25.879128669887454,-26.696823497511414,-30.55980606353919,-27.92756188438053],[-38.07706448880218,46.33565620122948,46.01114085310783,49.767898243079706,45.03205906111083,46.33565620122948],[-38.07706448880218,-20.898161324030006,-19.267165633135285,-18.972672268659107,-23.44252872321179,-20.898161324030006],[55.003127335040276,58.00379327465005,56.06326463666954,61.06261872553295,58.49334268237642,58.00379327465005],[55.003127335040276,48.78209764999766,46.86553330874325,47.30577950999651,51.398965749274865,48.78209764999766],[55.003127335040276,52.932053273706025,55.564815526698666,51.9401620102646,50.76980287077943,52.932053273706025],[50.567426344157354,59.61820668798465,56.99844246037922,61.06261872553295,61.55280208197563,59.61820668798465],[50.567426344157354,-85.55220370303314,-85.76187419088691,-88.77554217777883,-83.81351586716916,-85.55220370303314],[50.567426344157354,47.618654612247994,45.20287095827591,47.30577950999651,50.1828531667498,47.618654612247994],[45.40904618327813,43.137854145091836,43.12369758310979,39.822162176963296,44.72483670088348,43.137854145091836],[45.40904618327813,46.94767852075938,44.37586419740438,47.30577950999651,49.349624668875244,46.94767852075938],[45.40904618327813,49.80289363852446,51.275733324519635,51.9401620102646,47.316222968489654,49.80289363852446],[57.540009004652376,42.39634006906757,41.313013670772676,39.822162176963296,44.70074910721842,42.39634006906757],[57.540009004652376,-67.36223879176093,-65.61085597321191,-70.57673646194051,-67.58879797129364,-67.36223879176093],[57.540009004652376,48.34611940617282,46.205859319441075,47.30577950999651,50.97987335386379,48.34611940617282],[56.01129701377114,53.05301937275695,54.69465880397861,49.767898243079706,52.96970440449374,53.05301937275695],[56.01129701377114,50.08070650899908,49.21527464071499,47.30577950999651,52.26244802151671,50.08070650899908],[56.01129701377114,58.911700899317744,60.37374671399243,61.06261872553295,56.42934936863011,58.911700899317744],[68.00394889835104,53.06831885525927,53.01896732100038,49.767898243079706,54.683252288934156,53.06831885525927],[68.00394889835104,-67.47673167628932,-65.5809047885702,-70.57673646194051,-67.90204557466149,-67.47673167628932],[68.00394889835104,50.112277174468446,49.2841281797997,47.30577950999651,52.271711620463016,50.112277174468446],[42.91385402950879,46.280311486242674,45.24276134461269,49.767898243079706,45.66349591490943,46.280311486242674],[42.91385402950879,45.84534047186244,43.226996421526174,47.30577950999651,47.770913147887946,45.84534047186244],[42.91385402950879,41.238407714720424,43.86050003315462,39.822162176963296,39.28812321704062,41.238407714720424],[34.45705055107074,46.96885937444713,44.80407079255625,49.767898243079706,47.80590064670068,46.96885937444713],[34.45705055107074,-85.47176284025423,-85.51348970975364,-88.77554217777883,-83.86286083210564,-85.47176284025423],[34.45705055107074,45.445753262669385,42.88684781639571,47.30577950999651,47.12233982676551,45.445753262669385],[61.33222563727731,61.289890861882185,58.86477353178996,61.0083309040473,63.84856849394317,61.289890861882185],[61.33222563727731,50.007313988526484,52.23752173173161,47.30577950999651,49.0586015385657,50.007313988526484],[61.33222563727731,64.90599523474451,63.14825864493596,68.11599882163907,65.1410399912283,64.90599523474451],[72.92093486564866,64.4833065274634,65.60591623761296,61.0083309040473,65.00908033451023,64.4833065274634],[72.92093486564866,-15.810049035190294,-13.27117032314527,-17.75865238066117,-17.424591583671003,-15.810049035190294],[72.92093486564866,50.222038175539346,52.29608016370609,47.30577950999651,49.53134768019151,50.222038175539346],[-3.1444933574144245,-4.137024767225524,-3.7729144713461173,-0.999696774275828,-5.989352625486919,-4.137024767225524],[-3.1444933574144245,-17.579004880744247,-19.54171270104761,-18.972672268659107,-14.955199372384403,-17.579004880744247],[-3.1444933574144245,-1.426253929198372,0.6913670552521098,-0.33725646529628595,-4.060449895547636,-1.426253929198372],[1.6536693582973179,-0.3423504647756582,-2.6419535264490968,-0.999696774275828,2.2690702725005694,-0.3423504647756582],[1.6536693582973179,20.244519617767466,17.63204647419436,20.91244754068218,22.54015560962395,20.244519617767466],[1.6536693582973179,-17.66919059873868,-19.680189329685366,-18.972672268659107,-15.039874523294412,-17.66919059873868],[31.3188000210444,23.922531368719167,23.36082632159947,20.91244754068218,25.912094652909865,23.922531368719167],[31.3188000210444,45.188553029340966,46.67710316700408,47.30577950999651,42.69567894495229,45.188553029340966],[31.3188000210444,32.26690788470328,29.638917168275643,33.595548668889585,34.26464682204805,32.26690788470328],[35.98453448478318,24.325214042281857,25.68932732164461,20.91244754068218,24.57997486706223,24.325214042281857],[35.98453448478318,-104.84813325205764,-103.23150324021437,-108.14760273559631,-104.89963254024678,-104.84813325205764],[35.98453448478318,46.09299278432455,48.15046030168577,47.30577950999651,43.46022982172306,46.09299278432455],[13.053514151447013,18.06969196408861,18.853842067158272,20.91244754068218,15.937057168263479,18.06969196408861],[13.053514151447013,14.238510950814,15.055888350843167,10.738556388975034,15.081366034660551,14.238510950814],[13.053514151447013,11.928243047853652,10.917265254177513,9.284244879111066,14.193423308874946,11.928243047853652],[6.7952691710658915,8.629119651008756,10.123732053856726,10.738556388975034,6.133878430507696,8.629119651008756],[52.27534534702393,-37.99429842851187,-39.156387627480356,-40.488698255587884,-35.64896997671443,-37.99429842851187],[-71.59751122638255,-41.128555594839206,-43.738184100000126,-40.488698255587884,-38.82244872714582,-41.128555594839206],[-89.8284254911928,-42.741942009474855,-45.1893827590464,-40.488698255587884,-41.36334612865715,-42.741942009474855],[-23.381653206516084,-40.00944424741118,-42.372227103355826,-40.488698255587884,-37.41932327654412,-40.00944424741118],[-19.194185826317618,-40.11512816713603,-42.51224407560027,-40.488698255587884,-37.540806187880335,-40.11512816713603],[60.69707820360041,-37.50012737284371,-38.09248617952734,-40.488698255587884,-35.490115173171446,-37.50012737284371],[17.618330479043003,-37.91509057224117,-38.9989942221821,-40.488698255587884,-35.61037476569918,-37.91509057224117],[-109.58408876455316,-42.47201363352834,-45.00229135513908,-40.488698255587884,-40.88253801607317,-42.47201363352834]],\"ys\":[[-10.735542748413387,-11.822877334029279,-13.88300617597166,-13.030345413668693,-9.189975990718454,-11.822877334029279],[-10.735542748413387,-10.451257484371373,-8.029976713550226,-10.15674328516365,-13.012243509031698,-10.451257484371373],[-10.735542748413387,-10.900175490274567,-13.360639831987399,-8.68356477340083,-9.49117883228138,-10.900175490274567],[-3.169631346880351,-2.401904393987878,-5.036085568337413,-1.2811070115462924,-0.29938275672521864,-2.401904393987878],[-3.169631346880351,-6.956079513883852,-7.208552762274726,-10.15674328516365,-5.185344851193113,-6.956079513883852],[-3.169631346880351,-1.309093303695247,0.21763747681964163,0.7585426486960841,-3.8166243524244012,-1.309093303695247],[-46.31505693503453,-44.00443731649608,-43.823396818499646,-40.76642655885539,-45.72145508162294,-44.00443731649608],[-46.31505693503453,-47.35449135597938,-47.90826684298021,-50.37006150959009,-45.370255147854195,-47.35449135597938],[-34.223578386314124,-32.670552404287626,-30.70854502703522,-31.275605461882986,-35.294264436884596,-32.670552404287626],[-34.223578386314124,-35.10685942070117,-36.94226742009467,-36.72102316186766,-32.505759458732335,-35.10685942070117],[-55.85437784744294,-54.87835743134098,-57.31085301576418,-52.585046793052776,-53.533712774703346,-54.87835743134098],[-55.85437784744294,-55.650092903225755,-53.173147754057034,-57.81776133513421,-57.09878654759909,-55.650092903225755],[68.3354959677419,69.79118850077403,72.14145611272187,67.30696163392028,68.61933451357345,69.79118850077403],[-6.546093065519916,-4.877381732492067,-3.095961099199041,-3.1763271004972435,-7.465711743317465,-4.877381732492067],[-6.546093065519916,-10.26926727191507,-8.078027234097016,-13.030345413668693,-11.150766985833027,-10.26926727191507],[-6.546093065519916,-5.376675393853813,-8.010821518669454,-4.298487602280719,-3.253976593184958,-5.376675393853813],[-52.5968428985783,-52.602881171724945,-55.107078658638905,-52.585046793052776,-50.10714357029753,-52.602881171724945],[-2.130222189331091,5.746905374219496,6.0487970537366955,8.920283443327545,3.9396954796041657,5.746905374219496],[-2.130222189331091,-6.3271493726873675,-5.7434662296866605,-9.810640833347529,-5.2584094404430815,-6.3271493726873675],[-2.130222189331091,-2.052680298453975,0.4144047364188066,-1.9213288908724198,-4.582072963273562,-2.052680298453975],[-2.130222189331091,-2.607205575246863,-4.914365257500368,-3.244215121968057,0.002124870460724626,-2.607205575246863],[-19.722072745306033,-6.349729808869371,-8.156907717481781,-3.1763271004972435,-6.047881803194429,-6.349729808869371],[-19.722072745306033,-4.7627393415759,-5.332723511295267,-1.2811070115462924,-5.844296353062593,-4.7627393415759],[-19.722072745306033,-15.163366780229897,-17.651365684751955,-13.030345413668693,-13.687184257605436,-15.163366780229897],[-19.722072745306033,-13.33748499361689,-13.048719861349632,-10.15674328516365,-15.135061344398302,-13.33748499361689],[-19.722072745306033,-29.050361326666852,-30.45224730266224,-31.275605461882986,-26.59291233333371,-29.050361326666852],[-19.722072745306033,-37.97942960341914,-35.80610741027618,-40.76642655885539,-38.83071666835553,-37.97942960341914],[0.7224877146550948,7.304516093712153,4.703631523517948,8.920283443327545,9.138948016358908,7.304516093712153],[0.7224877146550948,2.352201176047284,4.7689721516318775,2.6617955850989308,-0.21142847602932235,2.352201176047284],[0.7224877146550948,-1.3265373278211257,-3.649101006774698,-1.9213288908724198,1.2781706637700712,-1.3265373278211257],[0.7224877146550948,5.043988675186792,6.907257875468648,6.6118505212654135,2.436991200409455,5.043988675186792],[0.7224877146550948,-9.771196455562075,-7.241956804245929,-11.758585803016725,-11.35770148148379,-9.771196455562075],[0.7224877146550948,9.199377047680805,7.145688353340366,12.139473742098522,9.858406482432688,9.199377047680805],[0.7224877146550948,2.478140278466488,-0.1526394811453331,3.4099756555704372,4.666896195951714,2.478140278466488],[0.7224877146550948,-5.607766205327519,-3.287262432137454,-8.151480263902494,-6.72163811084026,-5.607766205327519],[0.7224877146550948,33.97493808266039,32.21798364965289,37.18549741272463,34.20893706095983,33.97493808266039],[13.706671906581116,17.29230590061192,14.661475793569387,18.56229030146137,19.320708370651694,17.29230590061192],[13.706671906581116,6.114472303884151,7.343093569777199,2.6617955850989308,6.523656884772379,6.114472303884151],[13.706671906581116,8.89410434855242,7.540015874317751,6.6118505212654135,11.330798860541103,8.89410434855242],[13.706671906581116,19.30560553326329,20.90842487701138,21.270517739865284,16.770713782366432,19.30560553326329],[2.0198918985199303,3.981257569075386,5.006389416495269,6.6118505212654135,1.7082821299987954,3.981257569075386],[2.0198918985199303,7.308049980615399,5.327607348196727,10.327497982394673,7.8561924024583,7.308049980615399],[2.0198918985199303,-4.658883878069395,-3.6679904956022433,-8.151480263902494,-3.993035188496515,-4.658883878069395],[7.942510540105816,8.974493262976381,7.156476853608954,12.139473742098522,9.29117492372632,8.974493262976381],[7.942510540105816,5.9386142609954575,4.8098441636642,3.4099756555704372,8.266865059728456,5.9386142609954575],[7.942510540105816,9.355107088839514,11.526054802124962,10.327497982394673,6.722897687728905,9.355107088839514],[2.410324244969439,1.2227407416313834,3.0668764449086505,-1.9213288908724198,0.8700205533907899,1.2227407416313834],[2.410324244969439,2.960502843421078,5.333196683399681,3.4099756555704372,0.37459784593611856,2.960502843421078],[2.410324244969439,4.217958387872523,1.656967871588158,6.068020923643697,5.901356391220111,4.217958387872523],[7.188589525735296,0.18018175864622332,0.26778191139569296,-3.1763271004972435,1.6847694305977252,0.18018175864622332],[7.188589525735296,13.155005138289086,12.693671909218288,16.618499455204944,11.973401103156844,13.155005138289086],[7.188589525735296,1.4905502376746917,3.6745498088519097,-1.2811070115462924,0.621309277794561,1.4905502376746917],[7.188589525735296,10.601065170963663,8.284644135767799,13.1526144535564,11.707137634964228,10.601065170963663],[-42.33994511672994,-43.74919858689656,-42.503595357895215,-41.34388446478372,-46.13578252547562,-43.74919858689656],[18.63983422158091,18.635210339330985,21.151962808021693,18.56229030146137,16.15304809558679,18.635210339330985],[18.63983422158091,13.804476607534424,14.342876434989837,10.327497982394673,14.915410437760983,13.804476607534424],[18.63983422158091,20.290199640744895,19.75462914161711,23.766736482913657,19.17664604560827,20.290199640744895],[98.57658294557555,98.85441566938266,101.44381908731076,98.38032450453473,96.48990132881032,98.85441566938266],[38.24616633012679,38.73700412062319,41.34593772652029,37.18549741272463,36.86404059373501,38.73700412062319],[-6.9368259637582605,-0.23647213858094274,-2.3254186306395788,2.6617955850989308,0.4776570131938165,-0.23647213858094274],[-6.9368259637582605,-10.730620536173603,-8.564341916192326,-13.527570500433503,-11.570142735637392,-10.730620536173603],[-6.9368259637582605,-10.267946710979562,-12.176327472253398,-11.758585803016725,-7.65246892927047,-10.267946710979562],[-6.9368259637582605,-5.94331463035366,-3.7005076678300965,-5.140186577053265,-8.567092048133818,-5.94331463035366],[18.558740697820543,11.640260663253809,10.712051889033253,8.920283443327545,13.858713198110745,11.640260663253809],[18.558740697820543,18.56148775980558,21.06129734793747,18.56229030146137,16.06129747938096,18.56148775980558],[18.558740697820543,15.625610172210708,16.674743191390476,12.139473742098522,16.23015489147956,15.625610172210708],[18.558740697820543,23.93353677378036,22.218712148351855,27.17300349098635,24.11169348557923,23.93353677378036],[-35.28880913795553,-34.76426193539023,-35.79281276195692,-31.275605461882986,-35.39058425076422,-34.76426193539023],[-35.28880913795553,-34.83093322745576,-33.74918030572165,-38.312536337529956,-34.261158828712084,-34.83093322745576],[45.7600197635441,40.511769278284454,42.07854693760935,37.18549741272463,40.522836274892086,40.511769278284454],[45.7600197635441,48.782164644497804,47.24332082211254,52.12244558392136,48.736518490536604,48.782164644497804],[-46.940533105728846,-42.55231439077267,-45.12594962281021,-40.76642655885539,-40.82582986847166,-42.55231439077267],[-46.940533105728846,-50.54329736382642,-48.02849727566822,-52.585046793052776,-52.0895766708019,-50.54329736382642],[-46.940533105728846,-46.9659486398974,-44.62128238166418,-46.43364417095276,-49.563117939252884,-46.9659486398974],[0.6386626690079918,0.8667560344552347,3.4434605565156837,0.478196266169271,-1.5256319378221712,0.8667560344552347],[-18.19174915727836,-14.91022196810852,-14.570415960705734,-11.758585803016725,-16.74503273805703,-14.91022196810852],[-18.19174915727836,-11.076271855408825,-13.143109160990845,-8.151480263902494,-10.396833706870146,-11.076271855408825],[-18.19174915727836,-25.036379977465753,-23.322705667604815,-28.27660824918838,-25.213025123993823,-25.036379977465753],[8.920283443327545,15.838763477894279,16.766972252114837,18.558740697820543,13.620310943037342,15.838763477894279],[8.920283443327545,2.3382550642704865,4.939139634464693,0.7224877146550948,0.5038231416237312,2.3382550642704865],[8.920283443327545,1.0431558797769571,0.7412642002597583,-2.130222189331091,2.850365774392288,1.0431558797769571],[-9.810640833347529,15.406786733380148,15.746047259117129,18.558740697820543,13.572370694339796,15.406786733380148],[-9.810640833347529,-10.666824606711465,-13.150044194538417,-10.735542748413387,-8.151007998246293,-10.666824606711465],[-9.810640833347529,-0.80918714451095,1.0754298694279212,0.7224877146550948,-3.4203668354770094,-0.80918714451095],[18.56229030146137,18.566914183711294,16.050161715020586,18.63983422158091,21.04907642745549,18.566914183711294],[18.56229030146137,18.559543239476334,16.059733651344445,18.558740697820543,21.059733519900952,18.559543239476334],[18.56229030146137,14.976656307430563,17.6074864144731,13.706671906581116,12.948253837390792,14.976656307430563],[2.6617955850989308,10.253995187795896,9.025373921902847,13.706671906581116,9.844810606907668,10.253995187795896],[2.6617955850989308,1.0320821237067423,-1.384688851877851,0.7224877146550948,3.5957117757833488,1.0320821237067423],[2.6617955850989308,-4.0385582400783875,-1.949611748019751,-6.9368259637582605,-4.752687391853147,-4.0385582400783875],[-13.527570500433503,10.56126902022965,8.718766290350228,13.706671906581116,10.911723795048387,10.56126902022965],[-13.527570500433503,-10.831278834602406,-13.353050018266625,-10.735542748413387,-8.35492085769897,-10.831278834602406],[-13.527570500433503,-0.6546764234796112,-3.279648831517218,0.7224877146550948,1.3170267499543868,-0.6546764234796112],[-1.9213288908724198,-0.733745387534364,-2.577881090811631,2.410324244969439,-0.3810251992937719,-0.733745387534364],[-1.9213288908724198,0.1276961516038001,2.450259830557373,0.7224877146550948,-2.4770118399873975,0.1276961516038001],[-1.9213288908724198,-1.9988707817495366,-4.465955816622317,-2.130222189331091,0.5305218830700502,-1.9988707817495366],[-3.244215121968057,0.6149002647374047,2.3350671012751127,2.410324244969439,-1.9569408326068403,0.6149002647374047],[-3.244215121968057,-33.479650813887694,-35.190667061629924,-35.28880913795553,-30.91044530539306,-33.479650813887694],[-3.244215121968057,0.21211471134762183,2.5643424057139543,0.7224877146550948,-2.3822126514609963,0.21211471134762183],[6.6118505212654135,4.650484850709958,3.6253530032900763,2.0198918985199303,6.923460289786549,4.650484850709958],[6.6118505212654135,2.290349560733716,0.4270803604518609,0.7224877146550948,4.897347035511052,2.290349560733716],[6.6118505212654135,11.42441807929411,12.778506553528779,13.706671906581116,8.987723567305427,11.42441807929411],[21.270517739865284,4.241870763942897,2.837291561190902,2.0198918985199303,6.700464076215853,4.241870763942897],[21.270517739865284,-33.701317005312035,-35.552849652143344,-35.28880913795553,-31.09674429468999,-33.701317005312035],[21.270517739865284,2.6495983800900333,1.0197508371267257,0.7224877146550948,5.193586855528009,2.6495983800900333],[-11.758585803016725,-15.040112992186566,-15.37991899958935,-18.19174915727836,-13.205302222238053,-15.040112992186566],[-11.758585803016725,-1.2649016327995557,-3.794141284115701,0.7224877146550948,0.3216033931221595,-1.2649016327995557],[-11.758585803016725,-8.427465055795423,-6.519084294521585,-6.9368259637582605,-11.042942837504516,-8.427465055795423],[-5.140186577053265,-16.342409267212147,-18.026299998272044,-18.19174915727836,-13.781268816201074,-16.342409267212147],[-5.140186577053265,-34.4079628163034,-36.618576959311525,-35.28880913795553,-31.779511912654332,-34.4079628163034],[-5.140186577053265,0.15926536911923006,-2.4417375868183715,0.7224877146550948,2.4930991326625156,0.15926536911923006],[12.139473742098522,11.107491019227957,12.925507428595385,7.942510540105816,10.790809358478015,11.107491019227957],[12.139473742098522,3.6625844090728124,5.716273103413251,0.7224877146550948,3.00355497432093,3.6625844090728124],[12.139473742098522,15.072604267708357,14.02347124852859,18.558740697820543,14.468059548439504,15.072604267708357],[27.17300349098635,11.279780224840279,12.82474906187402,7.942510540105816,11.317872950508265,11.279780224840279],[27.17300349098635,-32.930745879531315,-34.2189010558024,-35.28880913795553,-30.52402383289129,-32.930745879531315],[27.17300349098635,3.9335511410482646,5.689795241966353,0.7224877146550948,3.7005016171140874,3.9335511410482646],[3.4099756555704372,5.413871934680795,6.542642032012053,7.942510540105816,3.0856211359477976,5.413871934680795],[3.4099756555704372,1.6543230917590441,4.2851028513708656,0.7224877146550948,-0.534432825726183,1.6543230917590441],[3.4099756555704372,2.8597970571187985,0.4871032171401959,2.410324244969439,5.445702054603757,2.8597970571187985],[6.068020923643697,7.578614697119942,9.978757212330386,7.942510540105816,5.005855169717474,7.578614697119942],[6.068020923643697,-9.521055095547492,-11.577670033762772,-10.735542748413387,-6.888337863165715,-9.521055095547492],[6.068020923643697,1.5043767480818175,4.126643453495593,0.7224877146550948,-0.7469944073625405,1.5043767480818175],[10.327497982394673,15.162855596441158,14.624455768985746,18.63983422158091,14.051921766214598,15.162855596441158],[10.327497982394673,8.914901433660974,6.743953720375527,7.942510540105816,11.547110834771583,8.914901433660974],[10.327497982394673,5.039339900299204,7.019782532717876,2.0198918985199303,4.491197478456304,5.039339900299204],[-8.151480263902494,-1.4727044873131683,-2.463597869780321,2.0198918985199303,-2.1385531768860484,-1.4727044873131683],[-8.151480263902494,-1.82122634391988,-4.141730117109946,0.7224877146550948,-0.7073544384071395,-1.82122634391988],[-8.151480263902494,-15.266957565772028,-13.200120260190008,-18.19174915727836,-15.946395714310707,-15.266957565772028],[-28.27660824918838,-1.2565822770362884,-2.912792479065668,2.0198918985199303,-1.154594783538358,-1.2565822770362884],[-28.27660824918838,-11.420900002811287,-14.035053911130024,-10.735542748413387,-9.131850994201137,-11.420900002811287],[-28.27660824918838,-2.2002664483984584,-4.268832116639981,0.7224877146550948,-1.5181334661101236,-2.2002664483984584],[-3.1763271004972435,-4.845038433525093,-6.626459066818119,-6.546093065519916,-2.2567084226996954,-4.845038433525093],[-3.1763271004972435,-16.548670036933906,-14.741492128321497,-19.722072745306033,-16.850518042608847,-16.548670036933906],[-3.1763271004972435,3.8320806665918288,3.744480513842359,7.188589525735296,2.327492994640327,3.8320806665918288],[16.618499455204944,-3.3580413304024352,-3.633624819210419,-6.546093065519916,-1.5701790512842804,-3.3580413304024352],[16.618499455204944,-40.97609429012751,-38.350232687897154,-42.33994511672994,-42.95500193753385,-40.97609429012751],[16.618499455204944,-16.236085199374305,-15.185799426479186,-19.722072745306033,-15.63276385826702,-16.236085199374305],[-1.2811070115462924,-2.0488339644387654,0.5853472099107693,-3.169631346880351,-4.151355601701426,-2.0488339644387654],[-1.2811070115462924,-16.240440415276424,-15.670456245557055,-19.722072745306033,-15.158883403789732,-16.240440415276424],[-1.2811070115462924,4.416932276514311,2.2329327053370935,7.188589525735296,5.286173236394442,4.416932276514311],[13.1526144535564,-0.7982165413683311,1.6029320967426184,-3.169631346880351,-2.074464891977768,-0.7982165413683311],[13.1526144535564,66.95093656908469,68.91861771460496,68.3354959677419,64.32647818577698,66.95093656908469],[13.1526144535564,-16.380262921210132,-14.844555387632306,-19.722072745306033,-16.33075523931274,-16.380262921210132],[-13.030345413668693,-11.9430108280528,-9.882881986110418,-10.735542748413387,-14.575912171363626,-11.9430108280528],[-13.030345413668693,-17.589051378744827,-15.10105247422277,-19.722072745306033,-19.06523390136929,-17.589051378744827],[-13.030345413668693,-9.307171207273539,-11.498411245091592,-6.546093065519916,-8.425671493355582,-9.307171207273539],[-4.298487602280719,-9.570543270859748,-6.936786392632195,-10.735542748413387,-11.651672981460148,-9.570543270859748],[-4.298487602280719,66.710697417478,68.53961821383466,68.3354959677419,64.11103994861867,66.710697417478],[-4.298487602280719,-17.630764336841715,-15.130108400857358,-19.722072745306033,-19.13939077867441,-17.630764336841715],[-10.15674328516365,-10.441028549205665,-12.86230932002681,-10.735542748413387,-7.88004252454534,-10.441028549205665],[-10.15674328516365,-16.541331036852792,-16.83009616912005,-19.722072745306033,-14.74375468607138,-16.541331036852792],[-10.15674328516365,-6.370295118160149,-6.117821869769275,-3.169631346880351,-8.141029780850888,-6.370295118160149],[0.7585426486960841,-8.634261850512289,-10.135195314480477,-10.735542748413387,-6.136568359291078,-8.634261850512289],[0.7585426486960841,-41.18450490237635,-38.55061619252044,-42.33994511672994,-43.270300960412726,-41.18450490237635],[0.7585426486960841,-16.75722833804717,-17.382619243461995,-19.722072745306033,-14.725438890137525,-16.75722833804717],[-31.275605461882986,-31.800152664448284,-30.7716018378816,-35.28880913795553,-31.173830349074294,-31.800152664448284],[-31.275605461882986,-21.947316880522166,-20.54543090452678,-19.722072745306033,-24.404765873855307,-21.947316880522166],[-31.275605461882986,-32.82863144390949,-34.79063882116189,-34.223578386314124,-30.204919411312517,-32.82863144390949],[-36.72102316186766,-35.70659427012745,-33.32355874663592,-35.28880913795553,-38.287809637230346,-35.70659427012745],[-36.72102316186766,95.66918806320754,96.37147415382108,98.57658294557555,93.58775508886268,95.66918806320754],[-36.72102316186766,-21.657385483766237,-20.033359406738537,-19.722072745306033,-24.199443214656867,-21.657385483766237],[37.18549741272463,36.69465962222823,34.08572601633113,38.24616633012679,38.56762314911641,36.69465962222823],[37.18549741272463,3.9330470447193395,5.690001477726829,0.7224877146550948,3.699048066419888,3.9330470447193395],[37.18549741272463,42.433747897984276,40.86697023865938,45.7600197635441,42.422680901376644,42.433747897984276],[52.12244558392136,41.683882989391556,42.96877077682157,38.24616633012679,42.02970462039276,41.683882989391556],[52.12244558392136,-43.50485671092813,-43.167077283410855,-46.940533105728846,-42.21289453638983,-43.50485671092813],[52.12244558392136,3.9707080791287637,5.67217655420418,0.7224877146550948,3.810059882889283,3.9707080791287637],[-40.76642655885539,-45.15464527381157,-42.581010041774036,-46.940533105728846,-46.88112979611259,-45.15464527381157],[-40.76642655885539,-22.50906970074228,-24.682391893885253,-19.722072745306033,-21.657782635805898,-22.50906970074228],[-40.76642655885539,-43.07704617739384,-43.258086675390274,-46.31505693503453,-41.36002841226698,-43.07704617739384],[-50.37006150959009,-47.717079823936515,-45.463570154862325,-46.940533105728846,-50.3389508714333,-47.717079823936515],[-50.37006150959009,-0.5290278410147001,1.5507842351961012,0.6386626690079918,-3.1627435984305716,-0.5290278410147001],[-50.37006150959009,-23.005234081279927,-24.650207723180646,-19.722072745306033,-22.917655257934985,-23.005234081279927],[-52.585046793052776,-48.9822825349552,-51.4970826231134,-46.940533105728846,-47.436003227979725,-48.9822825349552],[-52.585046793052776,-52.57900851990613,-50.07481103299217,-52.5968428985783,-55.07474612133355,-52.57900851990613],[-52.585046793052776,-53.561067209154736,-51.128571624731535,-55.85437784744294,-54.90571186579237,-53.561067209154736],[-57.81776133513421,-55.38974043492262,-57.558898020898724,-52.5968428985783,-54.54541696666118,-55.38974043492262],[-8.68356477340083,-97.53433237246074,-95.1702977785545,-99.98952472799688,-98.73372610294881,-97.53433237246074],[67.30696163392028,-96.54850996699886,-96.18941397343137,-99.98952472799688,-95.27533206021519,-96.54850996699886],[-41.34388446478372,-97.3112990867244,-98.28553963447494,-99.98952472799688,-95.06661998606499,-97.3112990867244],[23.766736482913657,-96.52249204922869,-95.35785989992199,-99.98952472799688,-96.04250848303157,-96.52249204922869],[98.38032450453473,-96.50951820659293,-95.41729744642936,-99.98952472799688,-95.95096900136058,-96.50951820659293],[-38.312536337529956,-98.16786502354775,-95.60111183874619,-99.98952472799688,-99.87049881409501,-98.16786502354775],[-46.43364417095276,-97.61749110845884,-95.21660299253395,-99.98952472799688,-98.89318539731497,-97.61749110845884],[0.478196266169271,-97.10569739065075,-97.83836752042608,-99.98952472799688,-95.005059837654,-97.10569739065075]]},\"selected\":{\"id\":\"2912\",\"type\":\"Selection\"},\"selection_policy\":{\"id\":\"2911\",\"type\":\"UnionRenderers\"}},\"id\":\"2655\",\"type\":\"ColumnDataSource\"},{\"attributes\":{\"callback\":null,\"data\":{\"color\":[\"blue\",\"blue\",\"blue\",\"blue\",\"blue\",\"blue\",\"blue\",\"blue\",\"blue\",\"blue\",\"blue\",\"blue\",\"blue\",\"blue\",\"blue\",\"blue\",\"blue\",\"blue\",\"blue\",\"blue\",\"blue\",\"blue\",\"blue\",\"blue\",\"blue\",\"blue\",\"blue\",\"blue\",\"blue\",\"blue\",\"blue\",\"blue\",\"blue\",\"blue\",\"blue\",\"blue\",\"blue\",\"blue\",\"blue\",\"blue\",\"blue\",\"blue\"],\"index\":[28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69],\"k\":[\"100\",\"0.05\",\"100\",\"100\",\"0.05\",\"100\",\"0.05\",\"100\",\"0.05\",\"100\",\"0.05\",\"100\",\"0.05\",\"100\",\"0.05\",\"100\",\"100\",\"0.05\",\"100\",\"0.2\",\"100\",\"0.2\",\"100\",\"0.2\",\"100\",\"0.2\",\"100\",\"0.2\",\"500\",\"0.1\",\"500\",\"0.1\",\"500\",\"0.1\",\"0.5\",\"0.5\",\"0.5\",\"0.5\",\"0.5\",\"0.5\",\"0.5\",\"0.5\"],\"k_r\":[\"10\",\"None\",\"10\",\"10\",\"None\",\"10\",\"None\",\"10\",\"None\",\"10\",\"None\",\"10\",\"None\",\"10\",\"None\",\"10\",\"10\",\"None\",\"10\",\"None\",\"10\",\"None\",\"10\",\"None\",\"10\",\"None\",\"10\",\"None\",\"50\",\"None\",\"5\",\"None\",\"50\",\"None\",\"None\",\"None\",\"None\",\"None\",\"None\",\"None\",\"None\",\"None\"],\"species\":[\"ordered_polymer[dna[t16-reverse]:dna[CFP-reverse]:dna[UTR1-reverse]:complex[dna[pconst]:protein[RNAP]-reverse]:dna[ptet-forward]:dna[UTR1-forward]:dna[GFP-forward]:dna[UTR1-forward]:dna[RFP-forward]:dna[t16-forward](circular)]+protein[RNAP(machinery)] <--> ordered_polymer[dna[t16-reverse]:dna[CFP-reverse]:dna[UTR1-reverse]:complex[dna[pconst]:protein[RNAP]-reverse]:complex[dna[ptet]:protein[RNAP]-forward]:dna[UTR1-forward]:dna[GFP-forward]:dna[UTR1-forward]:dna[RFP-forward]:dna[t16-forward](circular)]\\n Kf=k_forward * ordered_polymer_t16_r_CFP_r_UTR1_r_dna_pconst_protein_RNAP_machinery_r_ptet_f_UTR1_f_GFP_f_UTR1_f_RFP_f_t16_f_o_circular * protein_RNAP_machinery\\n Kr=k_reverse * ordered_polymer_t16_r_CFP_r_UTR1_r_dna_pconst_protein_RNAP_machinery_r_dna_ptet_protein_RNAP_machinery_f_UTR1_f_GFP_f_UTR1_f_RFP_f_t16_f_o_circular\\n k_forward=100\\n found_key=(mech=None, partid=None, name=kb).\\n search_key=(mech=transcription_mm, partid=ptet_leak, name=kb).\\n k_reverse=10\\n found_key=(mech=None, partid=None, name=ku).\\n search_key=(mech=transcription_mm, partid=ptet_leak, name=ku).\\n\",\"ordered_polymer[dna[t16-reverse]:dna[CFP-reverse]:dna[UTR1-reverse]:complex[dna[pconst]:protein[RNAP]-reverse]:complex[dna[ptet]:protein[RNAP]-forward]:dna[UTR1-forward]:dna[GFP-forward]:dna[UTR1-forward]:dna[RFP-forward]:dna[t16-forward](circular)] --> ordered_polymer[dna[t16-reverse]:dna[CFP-reverse]:dna[UTR1-reverse]:complex[dna[pconst]:protein[RNAP]-reverse]:dna[ptet-forward]:dna[UTR1-forward]:dna[GFP-forward]:dna[UTR1-forward]:dna[RFP-forward]:dna[t16-forward](circular)]+rna[rna[UTR1-forward]:rna[GFP-forward]:rna[UTR1-forward]:rna[RFP-forward]:rna[t16-forward]]+protein[RNAP(machinery)]\\n Kf=k_forward * ordered_polymer_t16_r_CFP_r_UTR1_r_dna_pconst_protein_RNAP_machinery_r_dna_ptet_protein_RNAP_machinery_f_UTR1_f_GFP_f_UTR1_f_RFP_f_t16_f_o_circular\\n k_forward=0.05\\n found_key=(mech=None, partid=None, name=ktx).\\n search_key=(mech=transcription_mm, partid=ptet_leak, name=ktx).\\n\",\"2protein[tetr]+ordered_polymer[dna[t16-reverse]:dna[CFP-reverse]:dna[UTR1-reverse]:complex[dna[pconst]:protein[RNAP]-reverse]:dna[ptet-forward]:dna[UTR1-forward]:dna[GFP-forward]:dna[UTR1-forward]:dna[RFP-forward]:dna[t16-forward](circular)] <--> ordered_polymer[dna[t16-reverse]:dna[CFP-reverse]:dna[UTR1-reverse]:complex[dna[pconst]:protein[RNAP]-reverse]:[dna[ptet]:2x_protein[tetr]-forward]:dna[UTR1-forward]:dna[GFP-forward]:dna[UTR1-forward]:dna[RFP-forward]:dna[t16-forward](circular)]\\n Kf=k_forward * protein_tetr^2 * ordered_polymer_t16_r_CFP_r_UTR1_r_dna_pconst_protein_RNAP_machinery_r_ptet_f_UTR1_f_GFP_f_UTR1_f_RFP_f_t16_f_o_circular\\n Kr=k_reverse * ordered_polymer_t16_r_CFP_r_UTR1_r_dna_pconst_protein_RNAP_machinery_r_dna_ptet_protein_tetr_2x_f_UTR1_f_GFP_f_UTR1_f_RFP_f_t16_f_o_circular\\n k_forward=100\\n found_key=(mech=None, partid=None, name=kb).\\n search_key=(mech=one_step_cooperative_binding, partid=ptet_tetr, name=kb).\\n k_reverse=10\\n found_key=(mech=None, partid=None, name=ku).\\n search_key=(mech=one_step_cooperative_binding, partid=ptet_tetr, name=ku).\\n\",\"ordered_polymer[dna[t16-reverse]:dna[CFP-reverse]:dna[UTR1-reverse]:complex[dna[pconst]:protein[RNAP]-reverse]:[dna[ptet]:2x_protein[tetr]-forward]:dna[UTR1-forward]:dna[GFP-forward]:dna[UTR1-forward]:dna[RFP-forward]:dna[t16-forward](circular)]+protein[RNAP(machinery)] <--> ordered_polymer[dna[t16-reverse]:dna[CFP-reverse]:dna[UTR1-reverse]:complex[dna[pconst]:protein[RNAP]-reverse]:complex[[dna[ptet]:2x_protein[tetr]]:protein[RNAP]-forward]:dna[UTR1-forward]:dna[GFP-forward]:dna[UTR1-forward]:dna[RFP-forward]:dna[t16-forward](circular)]\\n Kf=k_forward * ordered_polymer_t16_r_CFP_r_UTR1_r_dna_pconst_protein_RNAP_machinery_r_dna_ptet_protein_tetr_2x_f_UTR1_f_GFP_f_UTR1_f_RFP_f_t16_f_o_circular * protein_RNAP_machinery\\n Kr=k_reverse * ordered_polymer_t16_r_CFP_r_UTR1_r_dna_pconst_protein_RNAP_machinery_r_dna_ptet_protein_tetr_2x_protein_RNAP_machinery_f_UTR1_f_GFP_f_UTR1_f_RFP_f_t16_f_o_circular\\n k_forward=100\\n found_key=(mech=None, partid=None, name=kb).\\n search_key=(mech=transcription_mm, partid=ptet_tetr, name=kb).\\n k_reverse=10\\n found_key=(mech=None, partid=None, name=ku).\\n search_key=(mech=transcription_mm, partid=ptet_tetr, name=ku).\\n\",\"ordered_polymer[dna[t16-reverse]:dna[CFP-reverse]:dna[UTR1-reverse]:complex[dna[pconst]:protein[RNAP]-reverse]:complex[[dna[ptet]:2x_protein[tetr]]:protein[RNAP]-forward]:dna[UTR1-forward]:dna[GFP-forward]:dna[UTR1-forward]:dna[RFP-forward]:dna[t16-forward](circular)] --> ordered_polymer[dna[t16-reverse]:dna[CFP-reverse]:dna[UTR1-reverse]:complex[dna[pconst]:protein[RNAP]-reverse]:[dna[ptet]:2x_protein[tetr]-forward]:dna[UTR1-forward]:dna[GFP-forward]:dna[UTR1-forward]:dna[RFP-forward]:dna[t16-forward](circular)]+rna[rna[UTR1-forward]:rna[GFP-forward]:rna[UTR1-forward]:rna[RFP-forward]:rna[t16-forward]]+protein[RNAP(machinery)]\\n Kf=k_forward * ordered_polymer_t16_r_CFP_r_UTR1_r_dna_pconst_protein_RNAP_machinery_r_dna_ptet_protein_tetr_2x_protein_RNAP_machinery_f_UTR1_f_GFP_f_UTR1_f_RFP_f_t16_f_o_circular\\n k_forward=0.05\\n found_key=(mech=None, partid=None, name=ktx).\\n search_key=(mech=transcription_mm, partid=ptet_tetr, name=ktx).\\n\",\"ordered_polymer[dna[t16-reverse]:dna[CFP-reverse]:dna[UTR1-reverse]:dna[pconst-reverse]:complex[dna[ptet]:protein[RNAP]-forward]:dna[UTR1-forward]:dna[GFP-forward]:dna[UTR1-forward]:dna[RFP-forward]:dna[t16-forward](circular)]+protein[RNAP(machinery)] <--> ordered_polymer[dna[t16-reverse]:dna[CFP-reverse]:dna[UTR1-reverse]:complex[dna[pconst]:protein[RNAP]-reverse]:complex[dna[ptet]:protein[RNAP]-forward]:dna[UTR1-forward]:dna[GFP-forward]:dna[UTR1-forward]:dna[RFP-forward]:dna[t16-forward](circular)]\\n Kf=k_forward * ordered_polymer_t16_r_CFP_r_UTR1_r_pconst_r_dna_ptet_protein_RNAP_machinery_f_UTR1_f_GFP_f_UTR1_f_RFP_f_t16_f_o_circular * protein_RNAP_machinery\\n Kr=k_reverse * ordered_polymer_t16_r_CFP_r_UTR1_r_dna_pconst_protein_RNAP_machinery_r_dna_ptet_protein_RNAP_machinery_f_UTR1_f_GFP_f_UTR1_f_RFP_f_t16_f_o_circular\\n k_forward=100\\n found_key=(mech=None, partid=None, name=kb).\\n search_key=(mech=transcription_mm, partid=pconst, name=kb).\\n k_reverse=10\\n found_key=(mech=None, partid=None, name=ku).\\n search_key=(mech=transcription_mm, partid=pconst, name=ku).\\n\",\"ordered_polymer[dna[t16-reverse]:dna[CFP-reverse]:dna[UTR1-reverse]:complex[dna[pconst]:protein[RNAP]-reverse]:complex[dna[ptet]:protein[RNAP]-forward]:dna[UTR1-forward]:dna[GFP-forward]:dna[UTR1-forward]:dna[RFP-forward]:dna[t16-forward](circular)] --> ordered_polymer[dna[t16-reverse]:dna[CFP-reverse]:dna[UTR1-reverse]:dna[pconst-reverse]:complex[dna[ptet]:protein[RNAP]-forward]:dna[UTR1-forward]:dna[GFP-forward]:dna[UTR1-forward]:dna[RFP-forward]:dna[t16-forward](circular)]+rna[rna[UTR1-forward]:rna[CFP-forward]:rna[t16-forward]]+protein[RNAP(machinery)]\\n Kf=k_forward * ordered_polymer_t16_r_CFP_r_UTR1_r_dna_pconst_protein_RNAP_machinery_r_dna_ptet_protein_RNAP_machinery_f_UTR1_f_GFP_f_UTR1_f_RFP_f_t16_f_o_circular\\n k_forward=0.05\\n found_key=(mech=None, partid=None, name=ktx).\\n search_key=(mech=transcription_mm, partid=pconst, name=ktx).\\n\",\"ordered_polymer[dna[t16-reverse]:dna[CFP-reverse]:dna[UTR1-reverse]:dna[pconst-reverse]:[dna[ptet]:2x_protein[tetr]-forward]:dna[UTR1-forward]:dna[GFP-forward]:dna[UTR1-forward]:dna[RFP-forward]:dna[t16-forward](circular)]+protein[RNAP(machinery)] <--> ordered_polymer[dna[t16-reverse]:dna[CFP-reverse]:dna[UTR1-reverse]:complex[dna[pconst]:protein[RNAP]-reverse]:[dna[ptet]:2x_protein[tetr]-forward]:dna[UTR1-forward]:dna[GFP-forward]:dna[UTR1-forward]:dna[RFP-forward]:dna[t16-forward](circular)]\\n Kf=k_forward * ordered_polymer_t16_r_CFP_r_UTR1_r_pconst_r_dna_ptet_protein_tetr_2x_f_UTR1_f_GFP_f_UTR1_f_RFP_f_t16_f_o_circular * protein_RNAP_machinery\\n Kr=k_reverse * ordered_polymer_t16_r_CFP_r_UTR1_r_dna_pconst_protein_RNAP_machinery_r_dna_ptet_protein_tetr_2x_f_UTR1_f_GFP_f_UTR1_f_RFP_f_t16_f_o_circular\\n k_forward=100\\n found_key=(mech=None, partid=None, name=kb).\\n search_key=(mech=transcription_mm, partid=pconst, name=kb).\\n k_reverse=10\\n found_key=(mech=None, partid=None, name=ku).\\n search_key=(mech=transcription_mm, partid=pconst, name=ku).\\n\",\"ordered_polymer[dna[t16-reverse]:dna[CFP-reverse]:dna[UTR1-reverse]:complex[dna[pconst]:protein[RNAP]-reverse]:[dna[ptet]:2x_protein[tetr]-forward]:dna[UTR1-forward]:dna[GFP-forward]:dna[UTR1-forward]:dna[RFP-forward]:dna[t16-forward](circular)] --> ordered_polymer[dna[t16-reverse]:dna[CFP-reverse]:dna[UTR1-reverse]:dna[pconst-reverse]:[dna[ptet]:2x_protein[tetr]-forward]:dna[UTR1-forward]:dna[GFP-forward]:dna[UTR1-forward]:dna[RFP-forward]:dna[t16-forward](circular)]+rna[rna[UTR1-forward]:rna[CFP-forward]:rna[t16-forward]]+protein[RNAP(machinery)]\\n Kf=k_forward * ordered_polymer_t16_r_CFP_r_UTR1_r_dna_pconst_protein_RNAP_machinery_r_dna_ptet_protein_tetr_2x_f_UTR1_f_GFP_f_UTR1_f_RFP_f_t16_f_o_circular\\n k_forward=0.05\\n found_key=(mech=None, partid=None, name=ktx).\\n search_key=(mech=transcription_mm, partid=pconst, name=ktx).\\n\",\"ordered_polymer[dna[t16-reverse]:dna[CFP-reverse]:dna[UTR1-reverse]:dna[pconst-reverse]:complex[[dna[ptet]:2x_protein[tetr]]:protein[RNAP]-forward]:dna[UTR1-forward]:dna[GFP-forward]:dna[UTR1-forward]:dna[RFP-forward]:dna[t16-forward](circular)]+protein[RNAP(machinery)] <--> ordered_polymer[dna[t16-reverse]:dna[CFP-reverse]:dna[UTR1-reverse]:complex[dna[pconst]:protein[RNAP]-reverse]:complex[[dna[ptet]:2x_protein[tetr]]:protein[RNAP]-forward]:dna[UTR1-forward]:dna[GFP-forward]:dna[UTR1-forward]:dna[RFP-forward]:dna[t16-forward](circular)]\\n Kf=k_forward * ordered_polymer_t16_r_CFP_r_UTR1_r_pconst_r_dna_ptet_protein_tetr_2x_protein_RNAP_machinery_f_UTR1_f_GFP_f_UTR1_f_RFP_f_t16_f_o_circular * protein_RNAP_machinery\\n Kr=k_reverse * ordered_polymer_t16_r_CFP_r_UTR1_r_dna_pconst_protein_RNAP_machinery_r_dna_ptet_protein_tetr_2x_protein_RNAP_machinery_f_UTR1_f_GFP_f_UTR1_f_RFP_f_t16_f_o_circular\\n k_forward=100\\n found_key=(mech=None, partid=None, name=kb).\\n search_key=(mech=transcription_mm, partid=pconst, name=kb).\\n k_reverse=10\\n found_key=(mech=None, partid=None, name=ku).\\n search_key=(mech=transcription_mm, partid=pconst, name=ku).\\n\",\"ordered_polymer[dna[t16-reverse]:dna[CFP-reverse]:dna[UTR1-reverse]:complex[dna[pconst]:protein[RNAP]-reverse]:complex[[dna[ptet]:2x_protein[tetr]]:protein[RNAP]-forward]:dna[UTR1-forward]:dna[GFP-forward]:dna[UTR1-forward]:dna[RFP-forward]:dna[t16-forward](circular)] --> ordered_polymer[dna[t16-reverse]:dna[CFP-reverse]:dna[UTR1-reverse]:dna[pconst-reverse]:complex[[dna[ptet]:2x_protein[tetr]]:protein[RNAP]-forward]:dna[UTR1-forward]:dna[GFP-forward]:dna[UTR1-forward]:dna[RFP-forward]:dna[t16-forward](circular)]+rna[rna[UTR1-forward]:rna[CFP-forward]:rna[t16-forward]]+protein[RNAP(machinery)]\\n Kf=k_forward * ordered_polymer_t16_r_CFP_r_UTR1_r_dna_pconst_protein_RNAP_machinery_r_dna_ptet_protein_tetr_2x_protein_RNAP_machinery_f_UTR1_f_GFP_f_UTR1_f_RFP_f_t16_f_o_circular\\n k_forward=0.05\\n found_key=(mech=None, partid=None, name=ktx).\\n search_key=(mech=transcription_mm, partid=pconst, name=ktx).\\n\",\"dna[dna[t16-reverse]:dna[CFP-reverse]:dna[UTR1-reverse]:dna[pconst-reverse]:dna[ptet-forward]:dna[UTR1-forward]:dna[GFP-forward]:dna[UTR1-forward]:dna[RFP-forward]:dna[t16-forward](circular)]+protein[RNAP(machinery)] <--> ordered_polymer[dna[t16-reverse]:dna[CFP-reverse]:dna[UTR1-reverse]:complex[dna[pconst]:protein[RNAP]-reverse]:dna[ptet-forward]:dna[UTR1-forward]:dna[GFP-forward]:dna[UTR1-forward]:dna[RFP-forward]:dna[t16-forward](circular)]\\n Kf=k_forward * dna_t16_r_CFP_r_UTR1_r_pconst_r_ptet_f_UTR1_f_GFP_f_UTR1_f_RFP_f_t16_f_o_circular * protein_RNAP_machinery\\n Kr=k_reverse * ordered_polymer_t16_r_CFP_r_UTR1_r_dna_pconst_protein_RNAP_machinery_r_ptet_f_UTR1_f_GFP_f_UTR1_f_RFP_f_t16_f_o_circular\\n k_forward=100\\n found_key=(mech=None, partid=None, name=kb).\\n search_key=(mech=transcription_mm, partid=pconst, name=kb).\\n k_reverse=10\\n found_key=(mech=None, partid=None, name=ku).\\n search_key=(mech=transcription_mm, partid=pconst, name=ku).\\n\",\"ordered_polymer[dna[t16-reverse]:dna[CFP-reverse]:dna[UTR1-reverse]:complex[dna[pconst]:protein[RNAP]-reverse]:dna[ptet-forward]:dna[UTR1-forward]:dna[GFP-forward]:dna[UTR1-forward]:dna[RFP-forward]:dna[t16-forward](circular)] --> dna[dna[t16-reverse]:dna[CFP-reverse]:dna[UTR1-reverse]:dna[pconst-reverse]:dna[ptet-forward]:dna[UTR1-forward]:dna[GFP-forward]:dna[UTR1-forward]:dna[RFP-forward]:dna[t16-forward](circular)]+rna[rna[UTR1-forward]:rna[CFP-forward]:rna[t16-forward]]+protein[RNAP(machinery)]\\n Kf=k_forward * ordered_polymer_t16_r_CFP_r_UTR1_r_dna_pconst_protein_RNAP_machinery_r_ptet_f_UTR1_f_GFP_f_UTR1_f_RFP_f_t16_f_o_circular\\n k_forward=0.05\\n found_key=(mech=None, partid=None, name=ktx).\\n search_key=(mech=transcription_mm, partid=pconst, name=ktx).\\n\",\"dna[dna[t16-reverse]:dna[CFP-reverse]:dna[UTR1-reverse]:dna[pconst-reverse]:dna[ptet-forward]:dna[UTR1-forward]:dna[GFP-forward]:dna[UTR1-forward]:dna[RFP-forward]:dna[t16-forward](circular)]+protein[RNAP(machinery)] <--> ordered_polymer[dna[t16-reverse]:dna[CFP-reverse]:dna[UTR1-reverse]:dna[pconst-reverse]:complex[dna[ptet]:protein[RNAP]-forward]:dna[UTR1-forward]:dna[GFP-forward]:dna[UTR1-forward]:dna[RFP-forward]:dna[t16-forward](circular)]\\n Kf=k_forward * dna_t16_r_CFP_r_UTR1_r_pconst_r_ptet_f_UTR1_f_GFP_f_UTR1_f_RFP_f_t16_f_o_circular * protein_RNAP_machinery\\n Kr=k_reverse * ordered_polymer_t16_r_CFP_r_UTR1_r_pconst_r_dna_ptet_protein_RNAP_machinery_f_UTR1_f_GFP_f_UTR1_f_RFP_f_t16_f_o_circular\\n k_forward=100\\n found_key=(mech=None, partid=None, name=kb).\\n search_key=(mech=transcription_mm, partid=ptet_leak, name=kb).\\n k_reverse=10\\n found_key=(mech=None, partid=None, name=ku).\\n search_key=(mech=transcription_mm, partid=ptet_leak, name=ku).\\n\",\"ordered_polymer[dna[t16-reverse]:dna[CFP-reverse]:dna[UTR1-reverse]:dna[pconst-reverse]:complex[dna[ptet]:protein[RNAP]-forward]:dna[UTR1-forward]:dna[GFP-forward]:dna[UTR1-forward]:dna[RFP-forward]:dna[t16-forward](circular)] --> dna[dna[t16-reverse]:dna[CFP-reverse]:dna[UTR1-reverse]:dna[pconst-reverse]:dna[ptet-forward]:dna[UTR1-forward]:dna[GFP-forward]:dna[UTR1-forward]:dna[RFP-forward]:dna[t16-forward](circular)]+rna[rna[UTR1-forward]:rna[GFP-forward]:rna[UTR1-forward]:rna[RFP-forward]:rna[t16-forward]]+protein[RNAP(machinery)]\\n Kf=k_forward * ordered_polymer_t16_r_CFP_r_UTR1_r_pconst_r_dna_ptet_protein_RNAP_machinery_f_UTR1_f_GFP_f_UTR1_f_RFP_f_t16_f_o_circular\\n k_forward=0.05\\n found_key=(mech=None, partid=None, name=ktx).\\n search_key=(mech=transcription_mm, partid=ptet_leak, name=ktx).\\n\",\"2protein[tetr]+dna[dna[t16-reverse]:dna[CFP-reverse]:dna[UTR1-reverse]:dna[pconst-reverse]:dna[ptet-forward]:dna[UTR1-forward]:dna[GFP-forward]:dna[UTR1-forward]:dna[RFP-forward]:dna[t16-forward](circular)] <--> ordered_polymer[dna[t16-reverse]:dna[CFP-reverse]:dna[UTR1-reverse]:dna[pconst-reverse]:[dna[ptet]:2x_protein[tetr]-forward]:dna[UTR1-forward]:dna[GFP-forward]:dna[UTR1-forward]:dna[RFP-forward]:dna[t16-forward](circular)]\\n Kf=k_forward * protein_tetr^2 * dna_t16_r_CFP_r_UTR1_r_pconst_r_ptet_f_UTR1_f_GFP_f_UTR1_f_RFP_f_t16_f_o_circular\\n Kr=k_reverse * ordered_polymer_t16_r_CFP_r_UTR1_r_pconst_r_dna_ptet_protein_tetr_2x_f_UTR1_f_GFP_f_UTR1_f_RFP_f_t16_f_o_circular\\n k_forward=100\\n found_key=(mech=None, partid=None, name=kb).\\n search_key=(mech=one_step_cooperative_binding, partid=ptet_tetr, name=kb).\\n k_reverse=10\\n found_key=(mech=None, partid=None, name=ku).\\n search_key=(mech=one_step_cooperative_binding, partid=ptet_tetr, name=ku).\\n\",\"ordered_polymer[dna[t16-reverse]:dna[CFP-reverse]:dna[UTR1-reverse]:dna[pconst-reverse]:[dna[ptet]:2x_protein[tetr]-forward]:dna[UTR1-forward]:dna[GFP-forward]:dna[UTR1-forward]:dna[RFP-forward]:dna[t16-forward](circular)]+protein[RNAP(machinery)] <--> ordered_polymer[dna[t16-reverse]:dna[CFP-reverse]:dna[UTR1-reverse]:dna[pconst-reverse]:complex[[dna[ptet]:2x_protein[tetr]]:protein[RNAP]-forward]:dna[UTR1-forward]:dna[GFP-forward]:dna[UTR1-forward]:dna[RFP-forward]:dna[t16-forward](circular)]\\n Kf=k_forward * ordered_polymer_t16_r_CFP_r_UTR1_r_pconst_r_dna_ptet_protein_tetr_2x_f_UTR1_f_GFP_f_UTR1_f_RFP_f_t16_f_o_circular * protein_RNAP_machinery\\n Kr=k_reverse * ordered_polymer_t16_r_CFP_r_UTR1_r_pconst_r_dna_ptet_protein_tetr_2x_protein_RNAP_machinery_f_UTR1_f_GFP_f_UTR1_f_RFP_f_t16_f_o_circular\\n k_forward=100\\n found_key=(mech=None, partid=None, name=kb).\\n search_key=(mech=transcription_mm, partid=ptet_tetr, name=kb).\\n k_reverse=10\\n found_key=(mech=None, partid=None, name=ku).\\n search_key=(mech=transcription_mm, partid=ptet_tetr, name=ku).\\n\",\"ordered_polymer[dna[t16-reverse]:dna[CFP-reverse]:dna[UTR1-reverse]:dna[pconst-reverse]:complex[[dna[ptet]:2x_protein[tetr]]:protein[RNAP]-forward]:dna[UTR1-forward]:dna[GFP-forward]:dna[UTR1-forward]:dna[RFP-forward]:dna[t16-forward](circular)] --> ordered_polymer[dna[t16-reverse]:dna[CFP-reverse]:dna[UTR1-reverse]:dna[pconst-reverse]:[dna[ptet]:2x_protein[tetr]-forward]:dna[UTR1-forward]:dna[GFP-forward]:dna[UTR1-forward]:dna[RFP-forward]:dna[t16-forward](circular)]+rna[rna[UTR1-forward]:rna[GFP-forward]:rna[UTR1-forward]:rna[RFP-forward]:rna[t16-forward]]+protein[RNAP(machinery)]\\n Kf=k_forward * ordered_polymer_t16_r_CFP_r_UTR1_r_pconst_r_dna_ptet_protein_tetr_2x_protein_RNAP_machinery_f_UTR1_f_GFP_f_UTR1_f_RFP_f_t16_f_o_circular\\n k_forward=0.05\\n found_key=(mech=None, partid=None, name=ktx).\\n search_key=(mech=transcription_mm, partid=ptet_tetr, name=ktx).\\n\",\"ordered_polymer[complex[protein[Ribo]:rna[UTR1]-forward]:rna[GFP-forward]:rna[UTR1-forward]:rna[RFP-forward]:rna[t16-forward]]+protein[Ribo(machinery)] <--> ordered_polymer[complex[protein[Ribo]:rna[UTR1]-forward]:rna[GFP-forward]:complex[protein[Ribo]:rna[UTR1]-forward]:rna[RFP-forward]:rna[t16-forward]]\\n Kf=k_forward * ordered_polymer_protein_Ribo_machinery_rna_UTR1_f_GFP_f_UTR1_f_RFP_f_t16_f * protein_Ribo_machinery\\n Kr=k_reverse * ordered_polymer_protein_Ribo_machinery_rna_UTR1_f_GFP_f_protein_Ribo_machinery_rna_UTR1_f_RFP_f_t16_f\\n k_forward=100\\n found_key=(mech=None, partid=None, name=kb).\\n search_key=(mech=translation_mm, partid=UTR1, name=kb).\\n k_reverse=10\\n found_key=(mech=None, partid=None, name=ku).\\n search_key=(mech=translation_mm, partid=UTR1, name=ku).\\n\",\"ordered_polymer[complex[protein[Ribo]:rna[UTR1]-forward]:rna[GFP-forward]:complex[protein[Ribo]:rna[UTR1]-forward]:rna[RFP-forward]:rna[t16-forward]] --> ordered_polymer[complex[protein[Ribo]:rna[UTR1]-forward]:rna[GFP-forward]:rna[UTR1-forward]:rna[RFP-forward]:rna[t16-forward]]+protein[RFP]+protein[Ribo(machinery)]\\n Kf=k_forward * ordered_polymer_protein_Ribo_machinery_rna_UTR1_f_GFP_f_protein_Ribo_machinery_rna_UTR1_f_RFP_f_t16_f\\n k_forward=0.2\\n found_key=(mech=None, partid=None, name=ktl).\\n search_key=(mech=translation_mm, partid=UTR1, name=ktl).\\n\",\"ordered_polymer[rna[UTR1-forward]:rna[GFP-forward]:complex[protein[Ribo]:rna[UTR1]-forward]:rna[RFP-forward]:rna[t16-forward]]+protein[Ribo(machinery)] <--> ordered_polymer[complex[protein[Ribo]:rna[UTR1]-forward]:rna[GFP-forward]:complex[protein[Ribo]:rna[UTR1]-forward]:rna[RFP-forward]:rna[t16-forward]]\\n Kf=k_forward * ordered_polymer_UTR1_f_GFP_f_protein_Ribo_machinery_rna_UTR1_f_RFP_f_t16_f * protein_Ribo_machinery\\n Kr=k_reverse * ordered_polymer_protein_Ribo_machinery_rna_UTR1_f_GFP_f_protein_Ribo_machinery_rna_UTR1_f_RFP_f_t16_f\\n k_forward=100\\n found_key=(mech=None, partid=None, name=kb).\\n search_key=(mech=translation_mm, partid=UTR1, name=kb).\\n k_reverse=10\\n found_key=(mech=None, partid=None, name=ku).\\n search_key=(mech=translation_mm, partid=UTR1, name=ku).\\n\",\"ordered_polymer[complex[protein[Ribo]:rna[UTR1]-forward]:rna[GFP-forward]:complex[protein[Ribo]:rna[UTR1]-forward]:rna[RFP-forward]:rna[t16-forward]] --> ordered_polymer[rna[UTR1-forward]:rna[GFP-forward]:complex[protein[Ribo]:rna[UTR1]-forward]:rna[RFP-forward]:rna[t16-forward]]+protein[GFP]+protein[Ribo(machinery)]\\n Kf=k_forward * ordered_polymer_protein_Ribo_machinery_rna_UTR1_f_GFP_f_protein_Ribo_machinery_rna_UTR1_f_RFP_f_t16_f\\n k_forward=0.2\\n found_key=(mech=None, partid=None, name=ktl).\\n search_key=(mech=translation_mm, partid=UTR1, name=ktl).\\n\",\"rna[rna[UTR1-forward]:rna[GFP-forward]:rna[UTR1-forward]:rna[RFP-forward]:rna[t16-forward]]+protein[Ribo(machinery)] <--> ordered_polymer[complex[protein[Ribo]:rna[UTR1]-forward]:rna[GFP-forward]:rna[UTR1-forward]:rna[RFP-forward]:rna[t16-forward]]\\n Kf=k_forward * rna_UTR1_f_GFP_f_UTR1_f_RFP_f_t16_f * protein_Ribo_machinery\\n Kr=k_reverse * ordered_polymer_protein_Ribo_machinery_rna_UTR1_f_GFP_f_UTR1_f_RFP_f_t16_f\\n k_forward=100\\n found_key=(mech=None, partid=None, name=kb).\\n search_key=(mech=translation_mm, partid=UTR1, name=kb).\\n k_reverse=10\\n found_key=(mech=None, partid=None, name=ku).\\n search_key=(mech=translation_mm, partid=UTR1, name=ku).\\n\",\"ordered_polymer[complex[protein[Ribo]:rna[UTR1]-forward]:rna[GFP-forward]:rna[UTR1-forward]:rna[RFP-forward]:rna[t16-forward]] --> rna[rna[UTR1-forward]:rna[GFP-forward]:rna[UTR1-forward]:rna[RFP-forward]:rna[t16-forward]]+protein[GFP]+protein[Ribo(machinery)]\\n Kf=k_forward * ordered_polymer_protein_Ribo_machinery_rna_UTR1_f_GFP_f_UTR1_f_RFP_f_t16_f\\n k_forward=0.2\\n found_key=(mech=None, partid=None, name=ktl).\\n search_key=(mech=translation_mm, partid=UTR1, name=ktl).\\n\",\"rna[rna[UTR1-forward]:rna[GFP-forward]:rna[UTR1-forward]:rna[RFP-forward]:rna[t16-forward]]+protein[Ribo(machinery)] <--> ordered_polymer[rna[UTR1-forward]:rna[GFP-forward]:complex[protein[Ribo]:rna[UTR1]-forward]:rna[RFP-forward]:rna[t16-forward]]\\n Kf=k_forward * rna_UTR1_f_GFP_f_UTR1_f_RFP_f_t16_f * protein_Ribo_machinery\\n Kr=k_reverse * ordered_polymer_UTR1_f_GFP_f_protein_Ribo_machinery_rna_UTR1_f_RFP_f_t16_f\\n k_forward=100\\n found_key=(mech=None, partid=None, name=kb).\\n search_key=(mech=translation_mm, partid=UTR1, name=kb).\\n k_reverse=10\\n found_key=(mech=None, partid=None, name=ku).\\n search_key=(mech=translation_mm, partid=UTR1, name=ku).\\n\",\"ordered_polymer[rna[UTR1-forward]:rna[GFP-forward]:complex[protein[Ribo]:rna[UTR1]-forward]:rna[RFP-forward]:rna[t16-forward]] --> rna[rna[UTR1-forward]:rna[GFP-forward]:rna[UTR1-forward]:rna[RFP-forward]:rna[t16-forward]]+protein[RFP]+protein[Ribo(machinery)]\\n Kf=k_forward * ordered_polymer_UTR1_f_GFP_f_protein_Ribo_machinery_rna_UTR1_f_RFP_f_t16_f\\n k_forward=0.2\\n found_key=(mech=None, partid=None, name=ktl).\\n search_key=(mech=translation_mm, partid=UTR1, name=ktl).\\n\",\"rna[rna[UTR1-forward]:rna[CFP-forward]:rna[t16-forward]]+protein[Ribo(machinery)] <--> ordered_polymer[complex[protein[Ribo]:rna[UTR1]-forward]:rna[CFP-forward]:rna[t16-forward]]\\n Kf=k_forward * rna_UTR1_f_CFP_f_t16_f * protein_Ribo_machinery\\n Kr=k_reverse * ordered_polymer_protein_Ribo_machinery_rna_UTR1_f_CFP_f_t16_f\\n k_forward=100\\n found_key=(mech=None, partid=None, name=kb).\\n search_key=(mech=translation_mm, partid=UTR1, name=kb).\\n k_reverse=10\\n found_key=(mech=None, partid=None, name=ku).\\n search_key=(mech=translation_mm, partid=UTR1, name=ku).\\n\",\"ordered_polymer[complex[protein[Ribo]:rna[UTR1]-forward]:rna[CFP-forward]:rna[t16-forward]] --> rna[rna[UTR1-forward]:rna[CFP-forward]:rna[t16-forward]]+protein[CFP]+protein[Ribo(machinery)]\\n Kf=k_forward * ordered_polymer_protein_Ribo_machinery_rna_UTR1_f_CFP_f_t16_f\\n k_forward=0.2\\n found_key=(mech=None, partid=None, name=ktl).\\n search_key=(mech=translation_mm, partid=UTR1, name=ktl).\\n\",\"dna[cellular_processes]+protein[RNAP(machinery)] <--> complex[dna[cellular_processes]:protein[RNAP]]\\n Kf=k_forward * dna_cellular_processes * protein_RNAP_machinery\\n Kr=k_reverse * complex_dna_cellular_processes_protein_RNAP_machinery\\n k_forward=500\\n found_key=(mech=transcription, partid=None, name=kb).\\n search_key=(mech=transcription_mm, partid=average_promoter, name=kb).\\n k_reverse=50\\n found_key=(mech=transcription, partid=None, name=ku).\\n search_key=(mech=transcription_mm, partid=average_promoter, name=ku).\\n\",\"complex[dna[cellular_processes]:protein[RNAP]] --> dna[cellular_processes]+rna[cellular_processes]+protein[RNAP(machinery)]\\n Kf=k_forward * complex_dna_cellular_processes_protein_RNAP_machinery\\n k_forward=0.1\\n found_key=(mech=transcription, partid=None, name=ktx).\\n search_key=(mech=transcription_mm, partid=average_promoter, name=ktx).\\n\",\"rna[cellular_processes]+protein[Ribo(machinery)] <--> complex[protein[Ribo]:rna[cellular_processes]]\\n Kf=k_forward * rna_cellular_processes * protein_Ribo_machinery\\n Kr=k_reverse * complex_protein_Ribo_machinery_rna_cellular_processes\\n k_forward=500\\n found_key=(mech=translation, partid=None, name=kb).\\n search_key=(mech=translation_mm, partid=average_rbs, name=kb).\\n k_reverse=5\\n found_key=(mech=translation, partid=None, name=ku).\\n search_key=(mech=translation_mm, partid=average_rbs, name=ku).\\n\",\"complex[protein[Ribo]:rna[cellular_processes]] --> rna[cellular_processes]+protein[cellular_processes]+protein[Ribo(machinery)]\\n Kf=k_forward * complex_protein_Ribo_machinery_rna_cellular_processes\\n k_forward=0.1\\n found_key=(mech=translation, partid=None, name=ktl).\\n search_key=(mech=translation_mm, partid=average_rbs, name=ktl).\\n\",\"rna[cellular_processes]+protein[RNAase(machinery)] <--> complex[protein[RNAase]:rna[cellular_processes]]\\n Kf=k_forward * rna_cellular_processes * protein_RNAase_machinery\\n Kr=k_reverse * complex_protein_RNAase_machinery_rna_cellular_processes\\n k_forward=500\\n found_key=(mech=rna_degredation, partid=None, name=kb).\\n search_key=(mech=rna_degredation_mm, partid=cellular_processes, name=kb).\\n k_reverse=50\\n found_key=(mech=rna_degredation, partid=None, name=ku).\\n search_key=(mech=rna_degredation_mm, partid=cellular_processes, name=ku).\\n\",\"complex[protein[RNAase]:rna[cellular_processes]] --> protein[RNAase(machinery)]\\n Kf=k_forward * complex_protein_RNAase_machinery_rna_cellular_processes\\n k_forward=0.1\\n found_key=(mech=rna_degredation, partid=None, name=kdeg).\\n search_key=(mech=rna_degredation_mm, partid=cellular_processes, name=kdeg).\\n\",\"rna[rna[UTR1-forward]:rna[GFP-forward]:rna[UTR1-forward]:rna[RFP-forward]:rna[t16-forward]] --> \\n Kf=k_forward * rna_UTR1_f_GFP_f_UTR1_f_RFP_f_t16_f\\n k_forward=0.5\\n found_key=(mech=None, partid=None, name=kdil).\\n search_key=(mech=global_degredation_via_dilution, partid=rna_UTR1_f_GFP_f_UTR1_f_RFP_f_t16_f, name=kdil).\\n\",\"protein[GFP] --> \\n Kf=k_forward * protein_GFP\\n k_forward=0.5\\n found_key=(mech=None, partid=None, name=kdil).\\n search_key=(mech=global_degredation_via_dilution, partid=protein_GFP, name=kdil).\\n\",\"protein[RFP] --> \\n Kf=k_forward * protein_RFP\\n k_forward=0.5\\n found_key=(mech=None, partid=None, name=kdil).\\n search_key=(mech=global_degredation_via_dilution, partid=protein_RFP, name=kdil).\\n\",\"protein[tetr] --> \\n Kf=k_forward * protein_tetr\\n k_forward=0.5\\n found_key=(mech=None, partid=None, name=kdil).\\n search_key=(mech=global_degredation_via_dilution, partid=protein_tetr, name=kdil).\\n\",\"protein[CFP] --> \\n Kf=k_forward * protein_CFP\\n k_forward=0.5\\n found_key=(mech=None, partid=None, name=kdil).\\n search_key=(mech=global_degredation_via_dilution, partid=protein_CFP, name=kdil).\\n\",\"rna[rna[UTR1-forward]:rna[CFP-forward]:rna[t16-forward]] --> \\n Kf=k_forward * rna_UTR1_f_CFP_f_t16_f\\n k_forward=0.5\\n found_key=(mech=None, partid=None, name=kdil).\\n search_key=(mech=global_degredation_via_dilution, partid=rna_UTR1_f_CFP_f_t16_f, name=kdil).\\n\",\"rna[cellular_processes] --> \\n Kf=k_forward * rna_cellular_processes\\n k_forward=0.5\\n found_key=(mech=None, partid=None, name=kdil).\\n search_key=(mech=global_degredation_via_dilution, partid=rna_cellular_processes, name=kdil).\\n\",\"protein[cellular_processes] --> \\n Kf=k_forward * protein_cellular_processes\\n k_forward=0.5\\n found_key=(mech=None, partid=None, name=kdil).\\n search_key=(mech=global_degredation_via_dilution, partid=protein_cellular_processes, name=kdil).\\n\"],\"type\":[\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\"]},\"selected\":{\"id\":\"2914\",\"type\":\"Selection\"},\"selection_policy\":{\"id\":\"2913\",\"type\":\"UnionRenderers\"}},\"id\":\"2619\",\"type\":\"ColumnDataSource\"},{\"attributes\":{},\"id\":\"2920\",\"type\":\"Selection\"},{\"attributes\":{\"callback\":null,\"end\":103.54073563741488,\"start\":-104.9536774198362},\"id\":\"2692\",\"type\":\"Range1d\"},{\"attributes\":{\"callback\":null,\"data\":{\"end\":[],\"start\":[]},\"selected\":{\"id\":\"2920\",\"type\":\"Selection\"},\"selection_policy\":{\"id\":\"2919\",\"type\":\"UnionRenderers\"}},\"id\":\"2639\",\"type\":\"ColumnDataSource\"},{\"attributes\":{},\"id\":\"2910\",\"type\":\"Selection\"},{\"attributes\":{\"active_drag\":\"auto\",\"active_inspect\":\"auto\",\"active_multi\":null,\"active_scroll\":\"auto\",\"active_tap\":\"auto\",\"tools\":[{\"id\":\"2723\",\"type\":\"HoverTool\"},{\"id\":\"2724\",\"type\":\"HoverTool\"},{\"id\":\"2725\",\"type\":\"HoverTool\"},{\"id\":\"2726\",\"type\":\"TapTool\"},{\"id\":\"2727\",\"type\":\"BoxSelectTool\"},{\"id\":\"2728\",\"type\":\"PanTool\"},{\"id\":\"2729\",\"type\":\"WheelZoomTool\"}]},\"id\":\"2730\",\"type\":\"Toolbar\"},{\"attributes\":{\"graph_layout\":{\"0\":[-40.488698255587884,-99.98952472799688],\"1\":[49.767898243079706,-10.735542748413387],\"10\":[47.30577950999651,-19.722072745306033],\"11\":[-18.972672268659107,0.7224877146550948],\"12\":[-38.97590329134622,13.706671906581116],\"13\":[-26.696823497511414,2.0198918985199303],\"14\":[-13.580372442442618,7.942510540105816],\"15\":[-1.522992093191837,2.410324244969439],\"16\":[51.9401620102646,7.188589525735296],\"17\":[-88.77554217777883,-42.33994511672994],\"18\":[-22.785000824122843,18.63983422158091],\"19\":[-17.75865238066117,98.57658294557555],\"2\":[39.822162176963296,-3.169631346880351],\"20\":[-0.999696774275828,38.24616633012679],\"21\":[-47.309180478026114,-6.9368259637582605],\"22\":[-11.0257956154718,18.558740697820543],\"23\":[61.0083309040473,-35.28880913795553],\"24\":[-0.33725646529628595,45.7600197635441],\"25\":[20.91244754068218,-46.940533105728846],\"26\":[-108.14760273559631,0.6386626690079918],\"27\":[-33.958674477233366,-18.19174915727836],\"28\":[-3.2204830526287833,8.920283443327545],\"29\":[2.6692336714589935,-9.810640833347529],\"3\":[33.595548668889585,-46.31505693503453],\"30\":[-26.506129037015288,18.56229030146137],\"31\":[-40.81082856915895,2.6617955850989308],\"32\":[-52.26719757077504,-13.527570500433503],\"33\":[-3.64165140314341,-1.9213288908724198],\"34\":[7.93913477198736,-3.244215121968057],\"35\":[-30.726842861111997,6.6118505212654135],\"36\":[-50.125463104851065,21.270517739865284],\"37\":[-37.065874978864876,-11.758585803016725],\"38\":[-54.929942818866245,-5.140186577053265],\"39\":[-11.598851698563433,12.139473742098522],\"4\":[68.11599882163907,-34.223578386314124],\"40\":[-7.502176425196686,27.17300349098635],\"41\":[-9.242723146867734,3.4099756555704372],\"42\":[4.3510147815826885,6.068020923643697],\"43\":[-21.82687972050324,10.327497982394673],\"44\":[-27.359455282844813,-8.151480263902494],\"45\":[-38.07706448880218,-28.27660824918838],\"46\":[55.003127335040276,-3.1763271004972435],\"47\":[50.567426344157354,16.618499455204944],\"48\":[45.40904618327813,-1.2811070115462924],\"49\":[57.540009004652376,13.1526144535564],\"5\":[9.284244879111066,-55.85437784744294],\"50\":[56.01129701377114,-13.030345413668693],\"51\":[68.00394889835104,-4.298487602280719],\"52\":[42.91385402950879,-10.15674328516365],\"53\":[34.45705055107074,0.7585426486960841],\"54\":[61.33222563727731,-31.275605461882986],\"55\":[72.92093486564866,-36.72102316186766],\"56\":[-3.1444933574144245,37.18549741272463],\"57\":[1.6536693582973179,52.12244558392136],\"58\":[31.3188000210444,-40.76642655885539],\"59\":[35.98453448478318,-50.37006150959009],\"6\":[-70.57673646194051,68.3354959677419],\"60\":[13.053514151447013,-52.585046793052776],\"61\":[6.7952691710658915,-57.81776133513421],\"62\":[52.27534534702393,-8.68356477340083],\"63\":[-71.59751122638255,67.30696163392028],\"64\":[-89.8284254911928,-41.34388446478372],\"65\":[-23.381653206516084,23.766736482913657],\"66\":[-19.194185826317618,98.38032450453473],\"67\":[60.69707820360041,-38.312536337529956],\"68\":[17.618330479043003,-46.43364417095276],\"69\":[-109.58408876455316,0.478196266169271],\"7\":[61.06261872553295,-6.546093065519916],\"8\":[10.738556388975034,-52.5968428985783],\"9\":[1.9206148002173835,-2.130222189331091]}},\"id\":\"2630\",\"type\":\"StaticLayoutProvider\"},{\"attributes\":{\"source\":{\"id\":\"2651\",\"type\":\"ColumnDataSource\"}},\"id\":\"2653\",\"type\":\"CDSView\"},{\"attributes\":{},\"id\":\"2919\",\"type\":\"UnionRenderers\"},{\"attributes\":{},\"id\":\"2876\",\"type\":\"LinearScale\"},{\"attributes\":{},\"id\":\"2892\",\"type\":\"NodesOnly\"},{\"attributes\":{\"callback\":null,\"overlay\":{\"id\":\"2908\",\"type\":\"BoxAnnotation\"}},\"id\":\"2727\",\"type\":\"BoxSelectTool\"},{\"attributes\":{\"source\":{\"id\":\"2639\",\"type\":\"ColumnDataSource\"}},\"id\":\"2641\",\"type\":\"CDSView\"},{\"attributes\":{},\"id\":\"2728\",\"type\":\"PanTool\"},{\"attributes\":{},\"id\":\"2911\",\"type\":\"UnionRenderers\"},{\"attributes\":{\"graph_layout\":{\"0\":[-40.488698255587884,-99.98952472799688],\"1\":[49.767898243079706,-10.735542748413387],\"10\":[47.30577950999651,-19.722072745306033],\"11\":[-18.972672268659107,0.7224877146550948],\"12\":[-38.97590329134622,13.706671906581116],\"13\":[-26.696823497511414,2.0198918985199303],\"14\":[-13.580372442442618,7.942510540105816],\"15\":[-1.522992093191837,2.410324244969439],\"16\":[51.9401620102646,7.188589525735296],\"17\":[-88.77554217777883,-42.33994511672994],\"18\":[-22.785000824122843,18.63983422158091],\"19\":[-17.75865238066117,98.57658294557555],\"2\":[39.822162176963296,-3.169631346880351],\"20\":[-0.999696774275828,38.24616633012679],\"21\":[-47.309180478026114,-6.9368259637582605],\"22\":[-11.0257956154718,18.558740697820543],\"23\":[61.0083309040473,-35.28880913795553],\"24\":[-0.33725646529628595,45.7600197635441],\"25\":[20.91244754068218,-46.940533105728846],\"26\":[-108.14760273559631,0.6386626690079918],\"27\":[-33.958674477233366,-18.19174915727836],\"28\":[-3.2204830526287833,8.920283443327545],\"29\":[2.6692336714589935,-9.810640833347529],\"3\":[33.595548668889585,-46.31505693503453],\"30\":[-26.506129037015288,18.56229030146137],\"31\":[-40.81082856915895,2.6617955850989308],\"32\":[-52.26719757077504,-13.527570500433503],\"33\":[-3.64165140314341,-1.9213288908724198],\"34\":[7.93913477198736,-3.244215121968057],\"35\":[-30.726842861111997,6.6118505212654135],\"36\":[-50.125463104851065,21.270517739865284],\"37\":[-37.065874978864876,-11.758585803016725],\"38\":[-54.929942818866245,-5.140186577053265],\"39\":[-11.598851698563433,12.139473742098522],\"4\":[68.11599882163907,-34.223578386314124],\"40\":[-7.502176425196686,27.17300349098635],\"41\":[-9.242723146867734,3.4099756555704372],\"42\":[4.3510147815826885,6.068020923643697],\"43\":[-21.82687972050324,10.327497982394673],\"44\":[-27.359455282844813,-8.151480263902494],\"45\":[-38.07706448880218,-28.27660824918838],\"46\":[55.003127335040276,-3.1763271004972435],\"47\":[50.567426344157354,16.618499455204944],\"48\":[45.40904618327813,-1.2811070115462924],\"49\":[57.540009004652376,13.1526144535564],\"5\":[9.284244879111066,-55.85437784744294],\"50\":[56.01129701377114,-13.030345413668693],\"51\":[68.00394889835104,-4.298487602280719],\"52\":[42.91385402950879,-10.15674328516365],\"53\":[34.45705055107074,0.7585426486960841],\"54\":[61.33222563727731,-31.275605461882986],\"55\":[72.92093486564866,-36.72102316186766],\"56\":[-3.1444933574144245,37.18549741272463],\"57\":[1.6536693582973179,52.12244558392136],\"58\":[31.3188000210444,-40.76642655885539],\"59\":[35.98453448478318,-50.37006150959009],\"6\":[-70.57673646194051,68.3354959677419],\"60\":[13.053514151447013,-52.585046793052776],\"61\":[6.7952691710658915,-57.81776133513421],\"62\":[52.27534534702393,-8.68356477340083],\"63\":[-71.59751122638255,67.30696163392028],\"64\":[-89.8284254911928,-41.34388446478372],\"65\":[-23.381653206516084,23.766736482913657],\"66\":[-19.194185826317618,98.38032450453473],\"67\":[60.69707820360041,-38.312536337529956],\"68\":[17.618330479043003,-46.43364417095276],\"69\":[-109.58408876455316,0.478196266169271],\"7\":[61.06261872553295,-6.546093065519916],\"8\":[10.738556388975034,-52.5968428985783],\"9\":[1.9206148002173835,-2.130222189331091]}},\"id\":\"2662\",\"type\":\"StaticLayoutProvider\"},{\"attributes\":{},\"id\":\"2729\",\"type\":\"WheelZoomTool\"},{\"attributes\":{\"source\":{\"id\":\"2623\",\"type\":\"ColumnDataSource\"}},\"id\":\"2625\",\"type\":\"CDSView\"},{\"attributes\":{\"fill_color\":{\"value\":\"#abdda4\"},\"size\":{\"units\":\"screen\",\"value\":15}},\"id\":\"2718\",\"type\":\"Circle\"},{\"attributes\":{},\"id\":\"2893\",\"type\":\"NodesOnly\"},{\"attributes\":{\"line_color\":{\"value\":\"#fdae61\"},\"line_join\":\"round\",\"line_width\":{\"value\":5}},\"id\":\"2673\",\"type\":\"MultiLine\"},{\"attributes\":{\"fill_color\":{\"value\":\"#abdda4\"},\"size\":{\"units\":\"screen\",\"value\":8}},\"id\":\"2703\",\"type\":\"Square\"},{\"attributes\":{\"callback\":null,\"data\":{\"color\":[\"purple\",\"orange\",\"grey\",\"cyan\",\"grey\",\"cyan\",\"lightgreen\",\"grey\",\"green\",\"grey\",\"pink\",\"skyblue\",\"grey\",\"grey\",\"white\",\"grey\",\"grey\",\"red\",\"green\",\"blue\",\"white\",\"grey\",\"grey\",\"orange\",\"cyan\",\"orange\",\"green\",\"grey\"],\"index\":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27],\"species\":[\"nothing\",\"rna[rna[UTR1-forward]:rna[GFP-forward]:rna[UTR1-forward]:rna[RFP-forward]:rna[t16-forward]]\",\"ordered_polymer[rna[UTR1-forward]:rna[GFP-forward]:complex[protein[Ribo]:rna[UTR1]-forward]:rna[RFP-forward]:rna[t16-forward]]\",\"complex[protein[Ribo]:rna[cellular_processes]]\",\"ordered_polymer[complex[protein[Ribo]:rna[UTR1]-forward]:rna[CFP-forward]:rna[t16-forward]]\",\"complex[protein[RNAase]:rna[cellular_processes]]\",\"protein[GFP]\",\"ordered_polymer[complex[protein[Ribo]:rna[UTR1]-forward]:rna[GFP-forward]:rna[UTR1-forward]:rna[RFP-forward]:rna[t16-forward]]\",\"protein[RNAase(machinery)]\",\"ordered_polymer[dna[t16-reverse]:dna[CFP-reverse]:dna[UTR1-reverse]:complex[dna[pconst]:protein[RNAP]-reverse]:complex[dna[ptet]:protein[RNAP]-forward]:dna[UTR1-forward]:dna[GFP-forward]:dna[UTR1-forward]:dna[RFP-forward]:dna[t16-forward](circular)]\",\"protein[Ribo(machinery)]\",\"protein[RNAP(machinery)]\",\"ordered_polymer[dna[t16-reverse]:dna[CFP-reverse]:dna[UTR1-reverse]:complex[dna[pconst]:protein[RNAP]-reverse]:[dna[ptet]:2x_protein[tetr]-forward]:dna[UTR1-forward]:dna[GFP-forward]:dna[UTR1-forward]:dna[RFP-forward]:dna[t16-forward](circular)]\",\"ordered_polymer[dna[t16-reverse]:dna[CFP-reverse]:dna[UTR1-reverse]:dna[pconst-reverse]:[dna[ptet]:2x_protein[tetr]-forward]:dna[UTR1-forward]:dna[GFP-forward]:dna[UTR1-forward]:dna[RFP-forward]:dna[t16-forward](circular)]\",\"dna[dna[t16-reverse]:dna[CFP-reverse]:dna[UTR1-reverse]:dna[pconst-reverse]:dna[ptet-forward]:dna[UTR1-forward]:dna[GFP-forward]:dna[UTR1-forward]:dna[RFP-forward]:dna[t16-forward](circular)]\",\"ordered_polymer[dna[t16-reverse]:dna[CFP-reverse]:dna[UTR1-reverse]:dna[pconst-reverse]:complex[dna[ptet]:protein[RNAP]-forward]:dna[UTR1-forward]:dna[GFP-forward]:dna[UTR1-forward]:dna[RFP-forward]:dna[t16-forward](circular)]\",\"ordered_polymer[complex[protein[Ribo]:rna[UTR1]-forward]:rna[GFP-forward]:complex[protein[Ribo]:rna[UTR1]-forward]:rna[RFP-forward]:rna[t16-forward]]\",\"protein[RFP]\",\"protein[tetr]\",\"protein[CFP]\",\"dna[cellular_processes]\",\"ordered_polymer[dna[t16-reverse]:dna[CFP-reverse]:dna[UTR1-reverse]:complex[dna[pconst]:protein[RNAP]-reverse]:complex[[dna[ptet]:2x_protein[tetr]]:protein[RNAP]-forward]:dna[UTR1-forward]:dna[GFP-forward]:dna[UTR1-forward]:dna[RFP-forward]:dna[t16-forward](circular)]\",\"ordered_polymer[dna[t16-reverse]:dna[CFP-reverse]:dna[UTR1-reverse]:complex[dna[pconst]:protein[RNAP]-reverse]:dna[ptet-forward]:dna[UTR1-forward]:dna[GFP-forward]:dna[UTR1-forward]:dna[RFP-forward]:dna[t16-forward](circular)]\",\"rna[rna[UTR1-forward]:rna[CFP-forward]:rna[t16-forward]]\",\"complex[dna[cellular_processes]:protein[RNAP]]\",\"rna[cellular_processes]\",\"protein[cellular_processes]\",\"ordered_polymer[dna[t16-reverse]:dna[CFP-reverse]:dna[UTR1-reverse]:dna[pconst-reverse]:complex[[dna[ptet]:2x_protein[tetr]]:protein[RNAP]-forward]:dna[UTR1-forward]:dna[GFP-forward]:dna[UTR1-forward]:dna[RFP-forward]:dna[t16-forward](circular)]\"],\"type\":[\"nothing\",\"rna\",\"ordered_polymer\",\"complex\",\"ordered_polymer\",\"complex\",\"protein\",\"ordered_polymer\",\"protein\",\"ordered_polymer\",\"protein\",\"protein\",\"ordered_polymer\",\"ordered_polymer\",\"dna\",\"ordered_polymer\",\"ordered_polymer\",\"protein\",\"protein\",\"protein\",\"dna\",\"ordered_polymer\",\"ordered_polymer\",\"rna\",\"complex\",\"rna\",\"protein\",\"ordered_polymer\"]},\"selected\":{\"id\":\"2918\",\"type\":\"Selection\"},\"selection_policy\":{\"id\":\"2917\",\"type\":\"UnionRenderers\"}},\"id\":\"2635\",\"type\":\"ColumnDataSource\"},{\"attributes\":{\"edge_renderer\":{\"id\":\"2624\",\"type\":\"GlyphRenderer\"},\"inspection_policy\":{\"id\":\"2892\",\"type\":\"NodesOnly\"},\"layout_provider\":{\"id\":\"2630\",\"type\":\"StaticLayoutProvider\"},\"node_renderer\":{\"id\":\"2620\",\"type\":\"GlyphRenderer\"},\"selection_policy\":{\"id\":\"2893\",\"type\":\"NodesOnly\"}},\"id\":\"2617\",\"type\":\"GraphRenderer\"},{\"attributes\":{},\"id\":\"2737\",\"type\":\"NodesAndLinkedEdges\"},{\"attributes\":{},\"id\":\"2902\",\"type\":\"NodesOnly\"},{\"attributes\":{\"data_source\":{\"id\":\"2635\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"2708\",\"type\":\"Circle\"},\"hover_glyph\":{\"id\":\"2718\",\"type\":\"Circle\"},\"muted_glyph\":null,\"selection_glyph\":{\"id\":\"2713\",\"type\":\"Circle\"},\"view\":{\"id\":\"2637\",\"type\":\"CDSView\"}},\"id\":\"2636\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"data_source\":{\"id\":\"2623\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"2622\",\"type\":\"MultiLine\"},\"hover_glyph\":null,\"muted_glyph\":null,\"view\":{\"id\":\"2625\",\"type\":\"CDSView\"}},\"id\":\"2624\",\"type\":\"GlyphRenderer\"}],\"root_ids\":[\"2612\"]},\"title\":\"Bokeh Application\",\"version\":\"1.4.0\"}};\n var render_items = [{\"docid\":\"0725f7ce-26e5-46dc-9741-eb447f03bef7\",\"roots\":{\"2612\":\"35052bf2-2381-436d-8bbf-6fb6c100f83a\"}}];\n root.Bokeh.embed.embed_items_notebook(docs_json, render_items);\n\n }\n if (root.Bokeh !== undefined) {\n embed_document(root);\n } else {\n var attempts = 0;\n var timer = setInterval(function(root) {\n if (root.Bokeh !== undefined) {\n clearInterval(timer);\n embed_document(root);\n } else {\n attempts++;\n if (attempts > 100) {\n clearInterval(timer);\n console.log(\"Bokeh: ERROR: Unable to run BokehJS code because BokehJS library is missing\");\n }\n }\n }, 10, root)\n }\n})(window);", + "application/vnd.bokehjs_exec.v0+json": "" + }, + "metadata": { + "application/vnd.bokehjs_exec.v0+json": { + "id": "2612" + } + } + } + ], + "source": [ + "colordict={\"complex\":\"cyan\",\"protein\":\"green\",\n", + " \"GFP\":\"lightgreen\",\n", + " \"Ribo\":\"pink\",\n", + " \"RNAP\":\"skyblue\",\n", + " \"RFP\":\"red\",\n", + " \"CFP\":\"blue\",\n", + " \"ribosome\":\"blue\",\n", + " \"dna\":\"white\",\"rna\":\"orange\",\n", + " \"ligand\":\"pink\",\"phosphate\":\"yellow\",\"nothing\":\"purple\"}\n", + "# plotNetwork(myCRN,colordict=colordict,iterations=2000,rseed=11,posscale=.2,export=False)" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.7.6-final" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} \ No newline at end of file diff --git a/examples/Old Examples and Tests/Advanced Examples.ipynb b/examples/Old Examples and Tests/Advanced Examples.ipynb.old similarity index 96% rename from examples/Old Examples and Tests/Advanced Examples.ipynb rename to examples/Old Examples and Tests/Advanced Examples.ipynb.old index 3b9884ba..b5efb40b 100644 --- a/examples/Old Examples and Tests/Advanced Examples.ipynb +++ b/examples/Old Examples and Tests/Advanced Examples.ipynb.old @@ -36,7 +36,10 @@ "cell_type": "code", "execution_count": 5, "metadata": { - "scrolled": false + "scrolled": false, + "pycharm": { + "name": "#%%\n" + } }, "outputs": [ { @@ -173,6 +176,7 @@ ], "source": [ "from biocrnpyler import *\n", + "\n", "%matplotlib inline\n", "\n", "#Because we are lazy, all parameters will use the default \"param_name\"-->value key mapping.\n", @@ -223,70 +227,72 @@ " \"\\n\", myCRN.pretty_print(show_material = True, show_rates = True, show_attributes = True))\n", "\n", "#Simulate with BioSCRAPE if installed\n", - "try:\n", - " print(\"Simulating\")\n", - " import numpy as np\n", - " import pylab as plt\n", - " timepoints = np.arange(0, 3, .01)\n", - " stochastic = False #Whether to use ODE models or Stochastic SSA models\n", - " plt.figure(figsize = (16, 8))\n", - " plt.subplot(221)\n", - " plt.title(\"Load on a RNAP Promoter\")\n", - " loads = [0, 1.0, 5., 10., 50, 100, 500, 1000]\n", - " for dna_Load in loads:\n", - " #print(\"Simulating for dna_Load=\", dna_Load)\n", - " x0_dict = {\"protein_T7\": 10., \"protein_RNAP\":10., \"protein_RNAase\":5.0, \"protein_Ribo\":50.,\n", - " 'dna_ref':5., 'dna_Load':dna_Load}\n", - "\n", - " results = myCRN.simulate_with_bioscrape(timepoints, x0_dict, stochastic = stochastic)\n", - " plt.plot(timepoints, results[\"protein_ref\"], label = \"Load = \"+str(dna_Load))\n", "\n", - " plt.xlim(0, 5)\n", - " #plt.xlabel(\"time\")\n", - " plt.ylabel(\"Reference Protein\")\n", - " plt.legend()\n", + "print(\"Simulating\")\n", + "import numpy as np\n", + "import pylab as plt\n", + "timepoints = np.arange(0, 3, .01)\n", + "stochastic = False #Whether to use ODE models or Stochastic SSA models\n", + "plt.figure(figsize = (16, 8))\n", + "plt.subplot(221)\n", + "plt.title(\"Load on a RNAP Promoter\")\n", + "loads = [0, 1.0, 5., 10., 50, 100, 500, 1000]\n", + "for dna_Load in loads:\n", + " #print(\"Simulating for dna_Load=\", dna_Load)\n", + " x0_dict = {\"protein_T7\": 10., \"protein_RNAP\":10., \"protein_RNAase\":5.0, \"protein_Ribo\":50.,\n", + " 'dna_ref':5., 'dna_Load':dna_Load}\n", + "\n", + " results = myCRN.simulate_with_bioscrape(timepoints, x0_dict, stochastic = stochastic)\n", + " if results is not None:\n", + " plt.plot(timepoints, results[\"protein_ref\"], label = \"Load = \"+str(dna_Load))\n", "\n", - " plt.subplot(222)\n", - " plt.title(\"Load on a T7 Promotoer\")\n", - " for dna_Load in loads:\n", - " #print(\"Simulating for dna_T7Load=\", dna_Load)\n", - " x0_dict = {\"protein_T7\": 10., \"protein_RNAP\":10., \"protein_RNAase\":5.0, \"protein_Ribo\":50.,\n", - " 'dna_ref':5., 'dna_T7Load':dna_Load}\n", - " results = myCRN.simulate_with_bioscrape(timepoints, x0_dict, stochastic = stochastic)\n", + "plt.xlim(0, 5)\n", + "#plt.xlabel(\"time\")\n", + "plt.ylabel(\"Reference Protein\")\n", + "plt.legend()\n", + "\n", + "plt.subplot(222)\n", + "plt.title(\"Load on a T7 Promotoer\")\n", + "for dna_Load in loads:\n", + " #print(\"Simulating for dna_T7Load=\", dna_Load)\n", + " x0_dict = {\"protein_T7\": 10., \"protein_RNAP\":10., \"protein_RNAase\":5.0, \"protein_Ribo\":50.,\n", + " 'dna_ref':5., 'dna_T7Load':dna_Load}\n", + " results = myCRN.simulate_with_bioscrape(timepoints, x0_dict, stochastic = stochastic)\n", + " if results is not None:\n", " plt.plot(timepoints, results[\"protein_ref\"], label=\"Load = \" + str(dna_Load))\n", - " plt.xlim(0, 5)\n", - " #plt.xlabel(\"time\")\n", - " plt.ylabel(\"Reference Protein\")\n", - " plt.legend()\n", - "\n", - " plt.subplot(223)\n", - " plt.title(\"Load on a RNAP Promotoer, No RBS\")\n", - " for dna_Load in loads:\n", - " #print(\"Simulating for dna_TxLoad=\", dna_Load)\n", - " x0_dict = {\"protein_T7\": 10., \"protein_RNAP\":10., \"protein_RNAase\":5.0, \"protein_Ribo\":50.,\n", - " 'dna_ref':5., 'dna_TxLoad':dna_Load}\n", - " results = myCRN.simulate_with_bioscrape(timepoints, x0_dict, stochastic = stochastic)\n", + "plt.xlim(0, 5)\n", + "#plt.xlabel(\"time\")\n", + "plt.ylabel(\"Reference Protein\")\n", + "plt.legend()\n", + "\n", + "plt.subplot(223)\n", + "plt.title(\"Load on a RNAP Promotoer, No RBS\")\n", + "for dna_Load in loads:\n", + " #print(\"Simulating for dna_TxLoad=\", dna_Load)\n", + " x0_dict = {\"protein_T7\": 10., \"protein_RNAP\":10., \"protein_RNAase\":5.0, \"protein_Ribo\":50.,\n", + " 'dna_ref':5., 'dna_TxLoad':dna_Load}\n", + " results = myCRN.simulate_with_bioscrape(timepoints, x0_dict, stochastic = stochastic)\n", + " if results is not None:\n", " plt.plot(timepoints, results[\"protein_ref\"], label=\"Load = \" + str(dna_Load))\n", - " plt.xlim(0, 5)\n", - " plt.xlabel(\"time\")\n", - " plt.ylabel(\"Reference Protein\")\n", - " plt.legend()\n", - "\n", - " plt.subplot(224)\n", - " plt.title(\"Load on a T7 Promotoer, No RBS\")\n", - " for dna_Load in loads:\n", - " #print(\"Simulating for dna_T7TxLoad=\", dna_Load)\n", - " x0_dict = {\"protein_T7\": 10., \"protein_RNAP\":10., \"protein_RNAase\":5.0, \"protein_Ribo\":50.,\n", - " 'dna_ref':5., 'dna_T7TxLoad':dna_Load}\n", - " results = myCRN.simulate_with_bioscrape(timepoints, x0_dict, stochastic = stochastic)\n", + "plt.xlim(0, 5)\n", + "plt.xlabel(\"time\")\n", + "plt.ylabel(\"Reference Protein\")\n", + "plt.legend()\n", + "\n", + "plt.subplot(224)\n", + "plt.title(\"Load on a T7 Promotoer, No RBS\")\n", + "for dna_Load in loads:\n", + " #print(\"Simulating for dna_T7TxLoad=\", dna_Load)\n", + " x0_dict = {\"protein_T7\": 10., \"protein_RNAP\":10., \"protein_RNAase\":5.0, \"protein_Ribo\":50.,\n", + " 'dna_ref':5., 'dna_T7TxLoad':dna_Load}\n", + " results = myCRN.simulate_with_bioscrape(timepoints, x0_dict, stochastic = stochastic)\n", + " if results is not None:\n", " plt.plot(timepoints, results[\"protein_ref\"], label=\"Load = \" + str(dna_Load))\n", - " plt.xlim(0, 5)\n", - " plt.xlabel(\"time\")\n", - " plt.ylabel(\"Reference Protein\")\n", - " plt.legend()\n", - " plt.show()\n", - "except ModuleNotFoundError:\n", - " pass" + "plt.xlim(0, 5)\n", + "plt.xlabel(\"time\")\n", + "plt.ylabel(\"Reference Protein\")\n", + "plt.legend()\n", + "plt.show()\n" ] }, { @@ -394,21 +400,22 @@ "print(myCRN.pretty_print(show_species = True, show_rates = True, show_attributes = True))\n", "\n", "#Simulate with BioSCRAPE, if installed\n", - "try:\n", - " import pylab as plt\n", - " time = np.arange(0, 20, .01)\n", - " #Simulate the CRN with no activator or repressor\n", - " x0 = {\"protein_activator\":0, \"protein_repressor\":0, \"dna_reporter\":10, \"protein_Ribo\":100, \"protein_RNAP\":20, \"protein_RNAase\":10}\n", - " R_const = myCRN.simulate_with_bioscrape(time, stochastic = False, initial_condition_dict = x0)\n", "\n", - " #Simulate teh CRN with just repressor\n", - " x0 = {\"protein_activator\":0, \"protein_repressor\":50, \"dna_reporter\":10, \"protein_Ribo\":100, \"protein_RNAP\":20, \"protein_RNAase\":10}\n", - " R_repressed = myCRN.simulate_with_bioscrape(time, stochastic = False, initial_condition_dict = x0)\n", + "import pylab as plt\n", + "time = np.arange(0, 20, .01)\n", + "#Simulate the CRN with no activator or repressor\n", + "x0 = {\"protein_activator\":0, \"protein_repressor\":0, \"dna_reporter\":10, \"protein_Ribo\":100, \"protein_RNAP\":20, \"protein_RNAase\":10}\n", + "R_const = myCRN.simulate_with_bioscrape(time, stochastic = False, initial_condition_dict = x0)\n", "\n", - " #Simulate the CRN with just activator\n", - " x0 = {\"protein_activator\":50, \"protein_repressor\":0, \"dna_reporter\":10, \"protein_Ribo\":100, \"protein_RNAP\":20, \"protein_RNAase\":10}\n", - " R_active = myCRN.simulate_with_bioscrape(time, stochastic = False, initial_condition_dict = x0)\n", + "#Simulate teh CRN with just repressor\n", + "x0 = {\"protein_activator\":0, \"protein_repressor\":50, \"dna_reporter\":10, \"protein_Ribo\":100, \"protein_RNAP\":20, \"protein_RNAase\":10}\n", + "R_repressed = myCRN.simulate_with_bioscrape(time, stochastic = False, initial_condition_dict = x0)\n", "\n", + "#Simulate the CRN with just activator\n", + "x0 = {\"protein_activator\":50, \"protein_repressor\":0, \"dna_reporter\":10, \"protein_Ribo\":100, \"protein_RNAP\":20, \"protein_RNAase\":10}\n", + "R_active = myCRN.simulate_with_bioscrape(time, stochastic = False, initial_condition_dict = x0)\n", + "\n", + "if (R_const is not None) and (R_repressed is not None) and (R_active is not None):\n", " plt.figure()\n", " plt.plot(time, R_const[\"protein_reporter\"], label = \"Unregulated Expression\")\n", " plt.plot(time, R_repressed[\"protein_reporter\"], label = \"Repressed Expression\")\n", @@ -417,9 +424,7 @@ " plt.xlabel(\"time\")\n", " plt.ylabel(\"[Reporter]\")\n", " plt.title(\"Regulated Promoter Example\")\n", - " plt.show()\n", - "except ModuleNotFoundError:\n", - " pass" + " plt.show()\n" ] }, { @@ -491,17 +496,16 @@ "\n", "\n", "#Simulate with BioSCRAPE if installed\n", - "try:\n", - " print(\"Simulating\")\n", - " import numpy as np\n", - " import pylab as plt\n", - " timepoints = np.arange(0, 20, .01)\n", - "\n", - " stochastic = False\n", - " sim_no_cas = CRN.simulate_with_bioscrape(timepoints, x0_no_dcas, stochastic = stochastic)\n", - " sim_with_cas = CRN.simulate_with_bioscrape(timepoints, x0_with_dcas, stochastic = stochastic)\n", + "print(\"Simulating\")\n", + "import numpy as np\n", + "import pylab as plt\n", + "timepoints = np.arange(0, 20, .01)\n", "\n", + "stochastic = False\n", + "sim_no_cas = CRN.simulate_with_bioscrape(timepoints, x0_no_dcas, stochastic = stochastic)\n", + "sim_with_cas = CRN.simulate_with_bioscrape(timepoints, x0_with_dcas, stochastic = stochastic)\n", "\n", + "if (sim_no_cas is not None) and (sim_with_cas is not None):\n", " plt.figure(figsize = (10, 10))\n", " plt.subplot(121)\n", " plt.title(\"RNAs\")\n", @@ -514,7 +518,7 @@ " plt.plot(timepoints, sim_with_cas[\"rna_reporter\"], \":\", color = \"green\", label = \"Reporter RNA: with dCas9\")\n", "\n", " plt.legend()\n", - " \n", + "\n", " plt.subplot(122)\n", " plt.title(\"proteins\")\n", " plt.plot(timepoints, sim_no_cas[\"protein_dCas9\"], color = \"blue\", label = \"dCas9 protein: No dCas9\")\n", @@ -526,9 +530,7 @@ "\n", " plt.plot()\n", " plt.legend()\n", - " plt.show()\n", - "except ModuleNotFoundError:\n", - " pass\n" + " plt.show()\n" ] }, { @@ -582,21 +584,21 @@ "print(myCRN.pretty_print(show_rates = True, show_materials = True, show_attributes = True))\n", "\n", "\n", - "try:\n", - " print(\"Simulating with BioSCRAPE\")\n", - " import numpy as np\n", - " import pylab as plt\n", - " timepoints = np.arange(0, 50, .1)\n", + "print(\"Simulating with BioSCRAPE\")\n", + "import numpy as np\n", + "import pylab as plt\n", + "timepoints = np.arange(0, 50, .1)\n", "\n", - " x0_dict = {repr(myMixture.ribosome.get_species()):100, \n", - " repr(myMixture.rnap.get_species()):20, \n", - " repr(myMixture.rnaase.get_species()):10, \n", - " repr(A_dna.dna):20, \n", - " repr(A_genome.dna):20}\n", + "x0_dict = {repr(myMixture.ribosome.get_species()):100,\n", + " repr(myMixture.rnap.get_species()):20,\n", + " repr(myMixture.rnaase.get_species()):10,\n", + " repr(A_dna.dna):20,\n", + " repr(A_genome.dna):20}\n", "\n", - " full_result_sto = myCRN.simulate_with_bioscrape(timepoints, x0_dict, stochastic = True)\n", - " full_result_det = myCRN.simulate_with_bioscrape(timepoints, x0_dict, stochastic = False)\n", + "full_result_sto = myCRN.simulate_with_bioscrape(timepoints, x0_dict, stochastic = True)\n", + "full_result_det = myCRN.simulate_with_bioscrape(timepoints, x0_dict, stochastic = False)\n", "\n", + "if (full_result_det is not None) and (full_result_sto is not None):\n", " #chemical_reaction_network.get_all_species_containing is a useful shortcut to get lists of species\n", " tot_A_dna_det = np.sum(full_result_det[myCRN.get_all_species_containing(A_dna.dna, return_as_strings=True)], 1)\n", " tot_A_genome_det = np.sum(full_result_det[myCRN.get_all_species_containing(A_genome.dna, return_as_strings=True)], 1)\n", @@ -640,9 +642,7 @@ " plt.xlabel(\"Time\")\n", " plt.ylabel(\"Concentration / Count\")\n", "\n", - " plt.show()\n", - "except ModuleNotFoundError:\n", - " pass" + " plt.show()\n" ] }, { @@ -710,4 +710,4 @@ }, "nbformat": 4, "nbformat_minor": 2 -} +} \ No newline at end of file diff --git a/examples/Old Examples and Tests/Beginner User Guide.ipynb b/examples/Old Examples and Tests/Beginner User Guide.ipynb.old similarity index 100% rename from examples/Old Examples and Tests/Beginner User Guide.ipynb rename to examples/Old Examples and Tests/Beginner User Guide.ipynb.old diff --git a/examples/Old Examples and Tests/CRN.xml b/examples/Old Examples and Tests/CRN.xml deleted file mode 100644 index fb4cf464..00000000 --- a/examples/Old Examples and Tests/CRN.xml +++ /dev/null @@ -1,80 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - type=proportionalhillnegative k=1.0 K=10.0 n=2 s1=protein_A d=dna_G - - - - - - - - - - - - - - - k - dna_G - - - - - - protein_A - n - - K - - - - - - - - - - - - - type=massaction k=0.1 - - - - - - - - - k - protein_X - - - - - - - - - - diff --git a/examples/Old Examples and Tests/GFP.xml b/examples/Old Examples and Tests/GFP.xml deleted file mode 100644 index 9b22232d..00000000 --- a/examples/Old Examples and Tests/GFP.xml +++ /dev/null @@ -1,1547 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - mwed97bcbd_4d1b_4df8_9cc5_6efe8dc18edf - mwc00961a6_47d1_4f5a_9c49_00fb0d02cd8a - mw28f62bd1_3a2b_45ba_be22_53e2eb1a9509 - - - - mw220339f8_94a8_4c76_a9f9_58d5c54662f3 - mw36dad171_05d7_4907_8d71_c2b3b5e51352 - - - - - - - - - - - - - - - - - - - - - - - mw95143b4c_189f_4371_9e49_c9203b9cbcbc - - - mweb04477f_13a4_4d28_8518_06b1c5bae4de - 2 - - - - - mw957daec6_ebbb_49d5_8167_3766b2a188d2 - mw609aa47a_fc0e_418c_a186_aa3a658fb203 - - - - - - - - - - - - - - - - - - - - - - - mwa09a7a9d_81cc_4ec4_bba4_36d8e79b88d8 - - - mw609aa47a_fc0e_418c_a186_aa3a658fb203 - 2 - - - - - mw88e6b301_c19d_4176_a4ab_c796e1855157 - mwc00961a6_47d1_4f5a_9c49_00fb0d02cd8a - - - - - - - - - - - - - - - - - - - - - - - - mwea067fb0_944c_4ea9_ad77_d6c4637982d5 - mwcbd6bcc3_2c61_4e12_a6f7_e1ac7bc57188 - mwe54945ce_9d19_4055_b186_48aad8d539a7 - - - - mwaa2e8186_64eb_4461_8a31_8d0de39dc096 - mw6fb7f787_57b9_494d_a431_121e3ccbcda9 - - - - - - - - - - - - - - - - - - - - - - - - mwd1e6aca1_12f3_4a1c_8a72_af7a96b9813b - mwdb801a58_028d_43ff_90eb_830d15b4bc7f - mw88609092_a820_4312_9f44_7089240fc041 - - - - mw820bf2c5_8b99_479b_81a8_f87bd2e4993c - mwde89bce9_6b96_41b5_ab10_47fdb6f84323 - - - - - - - - - - - - - - - - - - - - - mw78a7da0a_3e7e_491f_ad91_2ed5d734d5fc - mwb8e6b1d7_6c72_4a9b_a640_24ba06276629 - - - - - - - - - - - - - - - - - - - - mwce5fddb7_71c3_4e98_ac81_ec0a3b001d99 - mw117ae676_633e_4f3a_be8d_eacdbdddfeea - - - - - - - - - - - - - - - - - - - - - - mw5d32e76c_c3b5_41f5_ab4d_a989739e976b - mwde89bce9_6b96_41b5_ab10_47fdb6f84323 - mw4fb63e25_555b_4449_82e9_57273897e481 - - - - mw2ae82278_adf1_4e1e_bc67_81fd0721e604 - mw4740c413_fa03_405b_a56e_3a2fd6375f6c - - - - - - - - - - - - - - - - - - - - - - - - mwe97cb484_3f1f_4130_b862_68561e44f9e7 - mwde89bce9_6b96_41b5_ab10_47fdb6f84323 - mwfc2523f4_818e_4cfc_8a78_dc586dd37d07 - - - - mw8ab9985a_3984_4d46_8b30_0e80a32b67f1 - mwb71129fd_b0dc_41ce_a833_e547a1c07b4f - - - - - - - - - - - - - - - - - - - - - - - - mwdb1afb7b_616f_4514_aa03_8864294581f7 - mw4740c413_fa03_405b_a56e_3a2fd6375f6c - mwfc2523f4_818e_4cfc_8a78_dc586dd37d07 - - - - mw7afd6ea0_151a_485a_951e_95ad1b693ddb - mwb8e6b1d7_6c72_4a9b_a640_24ba06276629 - - - - - - - - - - - - - - - - - - - - - - - - mw324437a8_304c_4428_82a3_e4d0282c46a1 - mwb71129fd_b0dc_41ce_a833_e547a1c07b4f - mw4fb63e25_555b_4449_82e9_57273897e481 - - - - mw04494ba4_76c3_4733_9985_94acd310297b - mwb8e6b1d7_6c72_4a9b_a640_24ba06276629 - - - - - - - - - - - - - - - - - - - - - - mw8dbd1384_dfe7_407c_bb2f_4c6a60ece113 - mwb8e6b1d7_6c72_4a9b_a640_24ba06276629 - - - - - - - - - - - - - - - - - - - - - - mwa454e0eb_5b9b_4abe_97fb_c8fecd1a5067 - mw6fb7f787_57b9_494d_a431_121e3ccbcda9 - mw23834843_3708_4b86_abd8_09c25561cb03 - - - - mw4749d6e8_391a_4fed_9840_574e826d220b - mwf36a5d62_cdc5_4e90_af35_a9fa5ddb33e2 - - - - - - - - - - - - - - - - - - - - - - - - mweb0418ba_a652_4601_b6c9_0815d8c7fdd7 - mwf36a5d62_cdc5_4e90_af35_a9fa5ddb33e2 - - - mw4fb63e25_555b_4449_82e9_57273897e481 - 2 - - - - - mwfc57ef0b_083f_47a2_a7fb_bd77e7ea271a - mw969018c5_d898_4ea0_bb80_35de71266464 - - - - - - - - - - - - - - - - - - - - - mw91ca7fce_56fc_4796_be5f_31f2113d05ff - mw969018c5_d898_4ea0_bb80_35de71266464 - - - - - - - - - - - - - - - - - - - - mw45c534f2_a178_4fda_9794_bb6a741ee891 - mw969018c5_d898_4ea0_bb80_35de71266464 - - - - - - - - - - - - - - - - - - - - mw9e438038_4cdf_47fe_9fd8_8c153f1d0d36 - mw7416e86a_aa61_4745_b4bc_072c5e137891 - - - - - - - - - - - - - - - - - - - - - - mw5503e10b_b399_401c_85c1_34fcb4a75ef2 - mwcbd6bcc3_2c61_4e12_a6f7_e1ac7bc57188 - mw5a769204_a049_475d_8d40_b3980a459584 - - - - mwae4a630a_9af9_48e4_934e_06c84da51e82 - mwcb7850c8_3801_4d30_9282_42269ca72cc2 - - - - - - - - - - - - - - - - - - - - - mwb96a1d2a_b5f8_44f4_b227_80f66fda9cc3 - mwcb7850c8_3801_4d30_9282_42269ca72cc2 - - - - - - - - - - - - - - - - - - - - - - mwb6485fb2_9c6d_49a4_8420_c7c4c53a90cc - mw6fb7f787_57b9_494d_a431_121e3ccbcda9 - mw5a769204_a049_475d_8d40_b3980a459584 - - - - mwa7c866b1_be00_4def_b475_9f5439669d26 - mwf0fa4e98_5b94_43bf_9fd1_16e075a088f9 - - - - - - - - - - - - - - - - - - - - - - mw415d655e_9891_4a00_843a_4d3ea56c6961 - mwf0fa4e98_5b94_43bf_9fd1_16e075a088f9 - - - - - - - - - - - - - - - - - - - - - - mw33c60e2e_0342_44e5_9018_5b0afb2d9e37 - mw969018c5_d898_4ea0_bb80_35de71266464 - mw5a769204_a049_475d_8d40_b3980a459584 - - - - mw743021d4_03be_46d4_8cfe_01c2a98abd72 - mw87bea200_227d_4010_9616_9bee4d30458b - - - - - - - - - - - - - - - - - - - - - - - - mw9cee779f_46f7_454d_bdfc_0fdc67ae9dbb - mw87bea200_227d_4010_9616_9bee4d30458b - - - - - - - - - - - - - - - - - - - - - - mw5ba0589c_de85_47f9_b4de_6521446eb626 - mw7416e86a_aa61_4745_b4bc_072c5e137891 - mw5a769204_a049_475d_8d40_b3980a459584 - - - - mwb009fcc9_b90f_4dc5_ab36_f7cb4afaa2a6 - mwd91c4e55_95af_42a7_ac6d_2c307d96e1fe - - - - - - - - - - - - - - - - - - - - - - mw510ac102_ffdc_417a_aaf0_4e2404610fdf - mwd91c4e55_95af_42a7_ac6d_2c307d96e1fe - - - - - - - - - - - - - - - - - - - - - - mw98935be7_cc3a_45c9_82a1_60b4de40e60b - mwf36a5d62_cdc5_4e90_af35_a9fa5ddb33e2 - mw5a769204_a049_475d_8d40_b3980a459584 - - - - mw36bc145a_0803_475e_952d_f47300281d76 - mwf056a433_e0f6_461e_bfe3_c2b3c62486ca - - - - - - - - - - - - - - - - - - - - - - - mw6a9add31_478e_43ac_93dc_7ac72e1b235b - mwf056a433_e0f6_461e_bfe3_c2b3c62486ca - - - - - - - - - - - - - - - - - - - mwb58426aa_c779_4bf6_abcb_d9b102a11b01 - mw5c94996f_4533_4f46_813f_fb42fa7356f3 - - - - - - - - - - - - - - - - - - - - - - mw047616e8_0b14_42e1_aa37_4c17eb01c742 - mw6a8ec7cf_9ce3_4f43_a91b_8cf54a67e9cb - mwe54945ce_9d19_4055_b186_48aad8d539a7 - - - - mw76a20dcd_87ed_43cb_9023_0c10a44bc081 - mw11bfe9cd_0d22_4115_b9f7_163fa42fa97b - - - - - - - - - - - - - - - - - - - - - - - - mwa4a57dad_68c2_457b_b8fe_5e44e0f79081 - mw0f006cd4_e78e_48c5_b532_eb6e2f3c6121 - mw88609092_a820_4312_9f44_7089240fc041 - - - - mwdb5eda20_e9dc_4fa3_b7a8_4bb243cfa316 - mw55a8259b_29cf_445a_a79e_f0229fbc33d2 - - - - - - - - - - - - - - - - - - - - - mw3ea9c4de_2ae2_4c10_bcc0_779417a5a6f4 - mw68ff84bd_5ee7_416e_8ada_d4f9bad9d42b - - - - - - - - - - - - - - - - - - - - mw3d1a9380_01d0_445c_a000_7aef19654d03 - mwc200e475_c73f_465a_8de3_97b93a64c967 - - - - - - - - - - - - - - - - - - - - - - mw2954d485_8830_42f7_9567_c5fb232a305e - mw55a8259b_29cf_445a_a79e_f0229fbc33d2 - mw4fb63e25_555b_4449_82e9_57273897e481 - - - - mwe2129027_42be_48a5_b1ac_08a8475a4489 - mwd6c5bf43_5a9f_455e_8341_73d1b30d0264 - - - - - - - - - - - - - - - - - - - - - - - - mw861809d2_2f89_480e_8ac0_a22bd363ee4d - mw55a8259b_29cf_445a_a79e_f0229fbc33d2 - mwfc2523f4_818e_4cfc_8a78_dc586dd37d07 - - - - mw5b6e5883_a3b1_41fd_b446_96fd580cb6fc - mw49de218b_1e29_45e1_862c_0dc03a516700 - - - - - - - - - - - - - - - - - - - - - - - - mw420d2b27_f423_4274_84cb_6cac151f0d41 - mwd6c5bf43_5a9f_455e_8341_73d1b30d0264 - mwfc2523f4_818e_4cfc_8a78_dc586dd37d07 - - - - mwae8d8860_b8ab_4267_b767_361c82045673 - mw68ff84bd_5ee7_416e_8ada_d4f9bad9d42b - - - - - - - - - - - - - - - - - - - - - - - - mw7f4252d3_360b_4d1c_be74_de2dd056dd30 - mw49de218b_1e29_45e1_862c_0dc03a516700 - mw4fb63e25_555b_4449_82e9_57273897e481 - - - - mw495d6006_2243_4a1b_8f99_da34ba8620c4 - mw68ff84bd_5ee7_416e_8ada_d4f9bad9d42b - - - - - - - - - - - - - - - - - - - - - - mw5c4b8017_d12f_4da7_844b_66866761e8a8 - mw68ff84bd_5ee7_416e_8ada_d4f9bad9d42b - - - - - - - - - - - - - - - - - - - - - - mw1f7cd54c_006a_4336_a29b_b8e165e47ffd - mw0f006cd4_e78e_48c5_b532_eb6e2f3c6121 - mwc00961a6_47d1_4f5a_9c49_00fb0d02cd8a - - - - mw2f5f58cf_40d2_46e1_b838_f65fc5977fe4 - mw7da17532_fa9d_4ff2_8436_cb08e7696382 - - - - - - - - - - - - - - - - - - - - - - - - mw886360ca_3240_4b70_b2ed_71f6a14f6991 - mw11bfe9cd_0d22_4115_b9f7_163fa42fa97b - mw23834843_3708_4b86_abd8_09c25561cb03 - - - - mw5f037ee6_02ab_416b_b171_6a8d50c40d98 - mw6729d170_4447_449b_9e97_0908b0caab6b - - - - - - - - - - - - - - - - - - - - - - - - mwd0db75ff_7917_4f48_8568_a6e4deaaef49 - mw6729d170_4447_449b_9e97_0908b0caab6b - - - mw4fb63e25_555b_4449_82e9_57273897e481 - 2 - - - - - mwc11b606e_316e_4d71_9489_566accdec78f - mw50cebc13_eef8_41ce_9a71_72ef3e078558 - - - - - - - - - - - - - - - - - - - - - mwda5b89c3_b635_462b_99e8_64dcdb001557 - mw50cebc13_eef8_41ce_9a71_72ef3e078558 - - - - - - - - - - - - - - - - - - - - mw1f06627c_eca4_4a8e_95a3_0507a39254a8 - mw50cebc13_eef8_41ce_9a71_72ef3e078558 - - - - - - - - - - - - - - - - - - - - mw1ce3701e_a468_4bc4_8e8f_9490b0481417 - mwe03e3eea_a713_4196_a6d8_44a14c926596 - - - - - - - - - - - - - - - - - - - - - - mwb8b2f665_972a_4fa5_b77b_65267d72d771 - mw6a8ec7cf_9ce3_4f43_a91b_8cf54a67e9cb - mw5a769204_a049_475d_8d40_b3980a459584 - - - - mw901997be_8666_4eaa_89ce_67dae645b596 - mw611fccdf_157e_40db_8702_848bfb75c079 - - - - - - - - - - - - - - - - - - - - - mw9a0d61ce_d19f_491d_8a8b_e7185dd6407b - mw611fccdf_157e_40db_8702_848bfb75c079 - - - - - - - - - - - - - - - - - - - - - - mw9095c419_1af6_423f_a17b_f35649e9b8e3 - mw11bfe9cd_0d22_4115_b9f7_163fa42fa97b - mw5a769204_a049_475d_8d40_b3980a459584 - - - - mw8495daea_5d03_48d8_9a63_049bb19938e1 - mw7e686ddd_072e_4ab7_8512_92481d978201 - - - - - - - - - - - - - - - - - - - - - - mw97572d63_c62e_4bbf_bdc1_2e74c31eaafc - mw7e686ddd_072e_4ab7_8512_92481d978201 - - - - - - - - - - - - - - - - - - - - - - mw93951f7c_0025_4fcb_b7aa_13011fab660e - mw50cebc13_eef8_41ce_9a71_72ef3e078558 - mw5a769204_a049_475d_8d40_b3980a459584 - - - - mw16c052b6_5d10_4f5b_b210_7e2b014b2b09 - mw88722339_572e_456f_85da_875cfc4e92bc - - - - - - - - - - - - - - - - - - - - - - - - mwdb1c589a_02fe_4cbe_8254_348163ce6ad0 - mw88722339_572e_456f_85da_875cfc4e92bc - - - - - - - - - - - - - - - - - - - - - - mw67ee2769_d071_4e0c_8ae9_890a69369c1c - mwe03e3eea_a713_4196_a6d8_44a14c926596 - mw5a769204_a049_475d_8d40_b3980a459584 - - - - mw32cd40a9_406f_4471_8a5c_ccf548642a0b - mw6b40acd5_0395_4c2b_a5d8_eae734923797 - - - - - - - - - - - - - - - - - - - - - - mwc71a57e2_1da1_46e5_a212_4a2eddb53988 - mw6b40acd5_0395_4c2b_a5d8_eae734923797 - - - - - - - - - - - - - - - - - - - - - - mw6e36b10f_0200_499f_802b_7186ac265e97 - mw6729d170_4447_449b_9e97_0908b0caab6b - mw5a769204_a049_475d_8d40_b3980a459584 - - - - mw0e13e734_1441_4dd8_8bb2_6c45e689ce89 - mwa029c0f1_d85f_44ba_a505_84310ebae4b0 - - - - - - - - - - - - - - - - - - - - - - - mw47f65815_3810_49b1_98a8_e8576ae26c72 - mwa029c0f1_d85f_44ba_a505_84310ebae4b0 - - - - - - - - - - - - - - - - - - - mwc2ce705a_11c4_429d_a1e9_4163d818c21e - mw4fb63e25_555b_4449_82e9_57273897e481 - - - - - - - - - - - - time - 5400 - - - - - - - 0 - - - - - - - - - - time - 5400 - - - - - - - 0.0002 - - - - - - - diff --git a/examples/Old Examples and Tests/Non-Massaction Propensities.ipynb b/examples/Old Examples and Tests/Non-Massaction Propensities.ipynb.old similarity index 100% rename from examples/Old Examples and Tests/Non-Massaction Propensities.ipynb rename to examples/Old Examples and Tests/Non-Massaction Propensities.ipynb.old diff --git a/examples/Old Examples and Tests/Testing Propensities.py b/examples/Old Examples and Tests/Testing Propensities.py index 5f87fa56..fe9b16b5 100644 --- a/examples/Old Examples and Tests/Testing Propensities.py +++ b/examples/Old Examples and Tests/Testing Propensities.py @@ -1,9 +1,11 @@ from biocrnpyler.chemical_reaction_network import Species, Reaction, ComplexSpecies, ChemicalReactionNetwork +from biocrnpyler.propensities import MassAction, ProportionalHillPositive, ProportionalHillNegative, HillNegative, HillPositive, Propensity print("Start") -#Names of different supported propensities -propensity_types = ['hillpositive', 'proportionalhillpositive', 'hillnegative', 'proportionalhillnegative', 'massaction', 'general'] +# Names of different supported propensities +for prop in Propensity.get_available_propensities(): + print(prop) kb = 100 ku = 10 @@ -15,36 +17,42 @@ GA = ComplexSpecies([G, A, A]) #Activated Gene X = Species(name = "X", material_type = "protein") -rxnd = Reaction([X], [], kd) +rxnd = Reaction.from_massaction(inputs=[X], outputs=[], k_forward=kd) -#Massaction Unregulated +# Massaction Unregulated species1 = [G, A, GA, X] -rxn0_1 = Reaction([G, A, A], [GA], k=kb, k_rev = ku) -rxn0_2 = Reaction([GA], [GA, X], k=kex) +rxn0_1 = Reaction.from_massaction(inputs=[G, A, A], outputs=[GA], k_forward=kb, k_reverse=ku) +rxn0_2 = Reaction.from_massaction(inputs=[GA], outputs=[GA, X], k_forward=kex) CRN0 = ChemicalReactionNetwork(species1, [rxn0_1, rxn0_2, rxnd]) -rxn1_1 = Reaction([G, A, A], [GA], k=kb, k_rev = ku) -rxn1_2 = Reaction([G], [G, X], k=kex) +mak1 = MassAction(k_forward=kb, k_reverse=ku) +mak2 = MassAction(k_forward=kex) +rxn1_1 = Reaction([G, A, A], [GA], propensity_type=mak1) +rxn1_2 = Reaction([G], [G, X], propensity_type=mak2) CRN1 = ChemicalReactionNetwork(species1, [rxn1_1, rxn1_2, rxnd]) -#hill positive +# Hill positive species2 = [G, A, X] -rxn2_1 = Reaction([G], [G, X], propensity_type = "hillpositive", propensity_params = {"k":kex, "n":2, "K":float(kb/ku), "s1":A}) +hill_pos = HillPositive(k=kex, s1=A, K=float(kb/ku), n=2) +rxn2_1 = Reaction([G], [G, X], propensity_type=hill_pos) CRN2 = ChemicalReactionNetwork(species2, [rxn2_1, rxnd]) -#proportional hill positive -rxn3_1 = Reaction([G], [G, X], propensity_type = "proportionalhillpositive", propensity_params = {"k":kex, "n":2, "K":float(kb/ku), "s1":A, "d":G}) +# proportional Hill positive +prop_hill_pos = ProportionalHillPositive(k=kex, s1=A, K=float(kb/ku), n=2, d=G) +rxn3_1 = Reaction([G], [G, X], propensity_type=prop_hill_pos) CRN3 = ChemicalReactionNetwork(species2, [rxn3_1, rxnd]) -#hill Negative -rxn4_1 = Reaction([G], [G, X], propensity_type = "hillnegative", propensity_params = {"k":kex, "n":2, "K":float(kb/ku), "s1":A}) +# Hill Negative +hill_negative = HillNegative(k=kex, s1=A, K=float(kb/ku), n=2) +rxn4_1 = Reaction([G], [G, X], propensity_type=hill_negative) CRN4 = ChemicalReactionNetwork(species2, [rxn4_1, rxnd]) -#proportional hill negative -rxn5_1 = Reaction([G], [G, X], propensity_type = "proportionalhillnegative", propensity_params = {"k":kex, "n":2, "K":float(kb/ku), "s1":A, "d":G}) +# proportional hill negative +prop_hill_neg = ProportionalHillNegative(k=kex, s1=A, K=float(kb / ku), n=2, d=G) +rxn5_1 = Reaction([G], [G, X], propensity_type=prop_hill_neg) CRN5 = ChemicalReactionNetwork(species2, [rxn5_1, rxnd]) diff --git a/examples/Old Examples and Tests/bioscrape_test.xml b/examples/Old Examples and Tests/bioscrape_test.xml deleted file mode 100644 index 0dd35016..00000000 --- a/examples/Old Examples and Tests/bioscrape_test.xml +++ /dev/null @@ -1,249 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - type=massaction k=100 - - - - - - - - - - - - - k - dna_G1 - protein_RNAP - - - - - - - - - - type=massaction k=10 - - - - - - - - - - - - - k - complex_dna_G1_protein_RNAP - - - - - - - - - - type=massaction k=3 - - - - - - - - - - - - - - k - complex_dna_G1_protein_RNAP - - - - - - - - - - type=massaction k=100 - - - - - - - - - - - - - k - rna_T1 - protein_Ribo - - - - - - - - - - type=massaction k=10 - - - - - - - - - - - - - k - complex_protein_Ribo_rna_T1 - - - - - - - - - - type=massaction k=2 - - - - - - - - - - - - - - k - complex_protein_Ribo_rna_T1 - - - - - - - - - - type=massaction k=100 - - - - - - - - - - - - - k - rna_T1 - protein_RNAase - - - - - - - - - - type=massaction k=10 - - - - - - - - - - - - - k - complex_protein_RNAase_rna_T1 - - - - - - - - - - type=massaction k=1 - - - - - - - - - - - - k - complex_protein_RNAase_rna_T1 - - - - - - - - - - diff --git a/examples/Old Examples and Tests/geneexpr.xml b/examples/Old Examples and Tests/geneexpr.xml deleted file mode 100644 index 8820038c..00000000 --- a/examples/Old Examples and Tests/geneexpr.xml +++ /dev/null @@ -1,248 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - type=massaction k=100.0 - - - - - - - - - - - - - k - dna_G1 - protein_RNAP - - - - - - - - - - type=massaction k=10.0 - - - - - - - - - - - - - k - complex_dna_G1_protein_RNAP - - - - - - - - - - type=massaction k=3.0 - - - - - - - - - - - - - - k - complex_dna_G1_protein_RNAP - - - - - - - - - - type=massaction k=10.0 - - - - - - - - - - - - - k - rna_G1 - protein_Ribo - - - - - - - - - - type=massaction k=0.25 - - - - - - - - - - - - - k - complex_protein_Ribo_rna_G1 - - - - - - - - - - type=massaction k=2.0 - - - - - - - - - - - - - - k - complex_protein_Ribo_rna_G1 - - - - - - - - - - type=massaction k=10.0 - - - - - - - - - - - - - k - rna_G1 - protein_RNAase - - - - - - - - - - type=massaction k=0.5 - - - - - - - - - - - - - k - complex_protein_RNAase_rna_G1 - - - - - - - - - - type=massaction k=1.0 - - - - - - - - - - - - k - complex_protein_RNAase_rna_G1 - - - - - - - - - - diff --git a/examples/Old Examples and Tests/repr_for_crn_and_component_and_write_to_sbml.py b/examples/Old Examples and Tests/repr_for_crn_and_component_and_write_to_sbml.py index 2af2fb7e..cc7ef246 100644 --- a/examples/Old Examples and Tests/repr_for_crn_and_component_and_write_to_sbml.py +++ b/examples/Old Examples and Tests/repr_for_crn_and_component_and_write_to_sbml.py @@ -10,16 +10,17 @@ #Create Reactions #DNA_G --> DNA_G + protein_R @ k=1 -r1 = Reaction([s1], [s1, s2], k=1.0) +r1 = Reaction.from_massaction([s1], [s1, s2], k_forward=1.0) #2 protein_R <--> dimer_R @ kf = 100, krev = 10 -r2 = Reaction([s2, s2], [s3], k=100., k_rev=10.) #Note duplicates in inputs +r2 = Reaction.from_massaction([s2, s2], [s3], k_forward=100., k_reverse=10.) #Note duplicates in inputs # dimer_R <--> 2 protein_R_deg -r3 = Reaction([s3], [s4], k=100., k_rev = 10., output_coefs=[2]) #Note use of output_coefs instead of duplicates in outputs +outputs = [ChemicalComplex(species=s4, stoichiometry=2)] # Note the use of Chemical complex of duplicates in outputs +r3 = Reaction.from_massaction(inputs=[s3], outputs=outputs, k_forward=100., k_reverse=10.) #protein_R_deg --> NULL -r4 = Reaction([s4], [], k = .1) #Empty set denoted as empty brackets +r4 = Reaction.from_massaction(inputs=[s4], outputs=[], k_forward=.1) #Empty set denoted as empty brackets species = [s1, s1double, s2, s3, s4] rxns = [r1, r2, r3, r4] CRN = ChemicalReactionNetwork(species, rxns) diff --git a/examples/Old Examples and Tests/temp_sbml_file.xml b/examples/Old Examples and Tests/temp_sbml_file.xml deleted file mode 100644 index d6355df1..00000000 --- a/examples/Old Examples and Tests/temp_sbml_file.xml +++ /dev/null @@ -1,65 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - type=proportionalhillpositive k=1.0 K=10.0 n=2 s1=protein_A d=dna_G - - - - - - - - - - - - - - - k - dna_G - - - protein_A - n - - - - - - - protein_A - n - - K - - - - - - - - - - - - - diff --git a/examples/Specialized Component Tutorials/CombinatorialPromoter Details.ipynb b/examples/Specialized Component Tutorials/CombinatorialPromoter Details.ipynb index 862c49a3..27d85b48 100644 --- a/examples/Specialized Component Tutorials/CombinatorialPromoter Details.ipynb +++ b/examples/Specialized Component Tutorials/CombinatorialPromoter Details.ipynb @@ -70,7 +70,7 @@ }, { "cell_type": "code", - "execution_count": 13, + "execution_count": 1, "metadata": { "slideshow": { "slide_type": "skip" @@ -83,7 +83,7 @@ "\n", "
\n", " \n", - " Loading BokehJS ...\n", + " Loading BokehJS ...\n", "
" ] }, @@ -253,7 +253,7 @@ " \"\"}};\n", "\n", " function display_loaded() {\n", - " var el = document.getElementById(\"2017\");\n", + " var el = document.getElementById(\"1001\");\n", " if (el != null) {\n", " el.textContent = \"BokehJS is loading...\";\n", " }\n", @@ -373,7 +373,7 @@ " console.log(\"Bokeh: BokehJS failed to load within specified timeout.\");\n", " root._bokeh_failed_load = true;\n", " } else if (force !== true) {\n", - " var cell = $(document.getElementById(\"2017\")).parents('.cell').data().cell;\n", + " var cell = $(document.getElementById(\"1001\")).parents('.cell').data().cell;\n", " cell.output_area.append_execute_result(NB_LOAD_WARNING)\n", " }\n", "\n", @@ -390,7 +390,7 @@ " }\n", "}(window));" ], - "application/vnd.bokehjs_load.v0+json": "\n(function(root) {\n function now() {\n return new Date();\n }\n\n var force = true;\n\n if (typeof root._bokeh_onload_callbacks === \"undefined\" || force === true) {\n root._bokeh_onload_callbacks = [];\n root._bokeh_is_loading = undefined;\n }\n\n \n\n \n if (typeof (root._bokeh_timeout) === \"undefined\" || force === true) {\n root._bokeh_timeout = Date.now() + 5000;\n root._bokeh_failed_load = false;\n }\n\n var NB_LOAD_WARNING = {'data': {'text/html':\n \"
\\n\"+\n \"

\\n\"+\n \"BokehJS does not appear to have successfully loaded. If loading BokehJS from CDN, this \\n\"+\n \"may be due to a slow or bad network connection. Possible fixes:\\n\"+\n \"

\\n\"+\n \"
    \\n\"+\n \"
  • re-rerun `output_notebook()` to attempt to load from CDN again, or
  • \\n\"+\n \"
  • use INLINE resources instead, as so:
  • \\n\"+\n \"
\\n\"+\n \"\\n\"+\n \"from bokeh.resources import INLINE\\n\"+\n \"output_notebook(resources=INLINE)\\n\"+\n \"\\n\"+\n \"
\"}};\n\n function display_loaded() {\n var el = document.getElementById(\"2017\");\n if (el != null) {\n el.textContent = \"BokehJS is loading...\";\n }\n if (root.Bokeh !== undefined) {\n if (el != null) {\n el.textContent = \"BokehJS \" + root.Bokeh.version + \" successfully loaded.\";\n }\n } else if (Date.now() < root._bokeh_timeout) {\n setTimeout(display_loaded, 100)\n }\n }\n\n\n function run_callbacks() {\n try {\n root._bokeh_onload_callbacks.forEach(function(callback) {\n if (callback != null)\n callback();\n });\n } finally {\n delete root._bokeh_onload_callbacks\n }\n console.debug(\"Bokeh: all callbacks have finished\");\n }\n\n function load_libs(css_urls, js_urls, callback) {\n if (css_urls == null) css_urls = [];\n if (js_urls == null) js_urls = [];\n\n root._bokeh_onload_callbacks.push(callback);\n if (root._bokeh_is_loading > 0) {\n console.debug(\"Bokeh: BokehJS is being loaded, scheduling callback at\", now());\n return null;\n }\n if (js_urls == null || js_urls.length === 0) {\n run_callbacks();\n return null;\n }\n console.debug(\"Bokeh: BokehJS not loaded, scheduling load and callback at\", now());\n root._bokeh_is_loading = css_urls.length + js_urls.length;\n\n function on_load() {\n root._bokeh_is_loading--;\n if (root._bokeh_is_loading === 0) {\n console.debug(\"Bokeh: all BokehJS libraries/stylesheets loaded\");\n run_callbacks()\n }\n }\n\n function on_error() {\n console.error(\"failed to load \" + url);\n }\n\n for (var i = 0; i < css_urls.length; i++) {\n var url = css_urls[i];\n const element = document.createElement(\"link\");\n element.onload = on_load;\n element.onerror = on_error;\n element.rel = \"stylesheet\";\n element.type = \"text/css\";\n element.href = url;\n console.debug(\"Bokeh: injecting link tag for BokehJS stylesheet: \", url);\n document.body.appendChild(element);\n }\n\n const hashes = {\"https://cdn.bokeh.org/bokeh/release/bokeh-2.0.2.min.js\": \"ufR9RFnRs6lniiaFvtJziE0YeidtAgBRH6ux2oUItHw5WTvE1zuk9uzhUU/FJXDp\", \"https://cdn.bokeh.org/bokeh/release/bokeh-widgets-2.0.2.min.js\": \"8QM/PGWBT+IssZuRcDcjzwIh1mkOmJSoNMmyYDZbCfXJg3Ap1lEvdVgFuSAwhb/J\", \"https://cdn.bokeh.org/bokeh/release/bokeh-tables-2.0.2.min.js\": \"Jm8cH3Rg0P6UeZhVY5cLy1WzKajUT9KImCY+76hEqrcJt59/d8GPvFHjCkYgnSIn\", \"https://cdn.bokeh.org/bokeh/release/bokeh-gl-2.0.2.min.js\": \"Ozhzj+SI7ywm74aOI/UajcWz+C0NjsPunEVyVIrxzYkB+jA+2tUw8x5xJCbVtK5I\"};\n\n for (var i = 0; i < js_urls.length; i++) {\n var url = js_urls[i];\n var element = document.createElement('script');\n element.onload = on_load;\n element.onerror = on_error;\n element.async = false;\n element.src = url;\n if (url in hashes) {\n element.crossOrigin = \"anonymous\";\n element.integrity = \"sha384-\" + hashes[url];\n }\n console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n document.head.appendChild(element);\n }\n };\n\n function inject_raw_css(css) {\n const element = document.createElement(\"style\");\n element.appendChild(document.createTextNode(css));\n document.body.appendChild(element);\n }\n\n \n var js_urls = [\"https://cdn.bokeh.org/bokeh/release/bokeh-2.0.2.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-widgets-2.0.2.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-tables-2.0.2.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-gl-2.0.2.min.js\"];\n var css_urls = [];\n \n\n var inline_js = [\n function(Bokeh) {\n Bokeh.set_log_level(\"info\");\n },\n function(Bokeh) {\n \n \n }\n ];\n\n function run_inline_js() {\n \n if (root.Bokeh !== undefined || force === true) {\n \n for (var i = 0; i < inline_js.length; i++) {\n inline_js[i].call(root, root.Bokeh);\n }\n if (force === true) {\n display_loaded();\n }} else if (Date.now() < root._bokeh_timeout) {\n setTimeout(run_inline_js, 100);\n } else if (!root._bokeh_failed_load) {\n console.log(\"Bokeh: BokehJS failed to load within specified timeout.\");\n root._bokeh_failed_load = true;\n } else if (force !== true) {\n var cell = $(document.getElementById(\"2017\")).parents('.cell').data().cell;\n cell.output_area.append_execute_result(NB_LOAD_WARNING)\n }\n\n }\n\n if (root._bokeh_is_loading === 0) {\n console.debug(\"Bokeh: BokehJS loaded, going straight to plotting\");\n run_inline_js();\n } else {\n load_libs(css_urls, js_urls, function() {\n console.debug(\"Bokeh: BokehJS plotting callback run at\", now());\n run_inline_js();\n });\n }\n}(window));" + "application/vnd.bokehjs_load.v0+json": "\n(function(root) {\n function now() {\n return new Date();\n }\n\n var force = true;\n\n if (typeof root._bokeh_onload_callbacks === \"undefined\" || force === true) {\n root._bokeh_onload_callbacks = [];\n root._bokeh_is_loading = undefined;\n }\n\n \n\n \n if (typeof (root._bokeh_timeout) === \"undefined\" || force === true) {\n root._bokeh_timeout = Date.now() + 5000;\n root._bokeh_failed_load = false;\n }\n\n var NB_LOAD_WARNING = {'data': {'text/html':\n \"
\\n\"+\n \"

\\n\"+\n \"BokehJS does not appear to have successfully loaded. If loading BokehJS from CDN, this \\n\"+\n \"may be due to a slow or bad network connection. Possible fixes:\\n\"+\n \"

\\n\"+\n \"
    \\n\"+\n \"
  • re-rerun `output_notebook()` to attempt to load from CDN again, or
  • \\n\"+\n \"
  • use INLINE resources instead, as so:
  • \\n\"+\n \"
\\n\"+\n \"\\n\"+\n \"from bokeh.resources import INLINE\\n\"+\n \"output_notebook(resources=INLINE)\\n\"+\n \"\\n\"+\n \"
\"}};\n\n function display_loaded() {\n var el = document.getElementById(\"1001\");\n if (el != null) {\n el.textContent = \"BokehJS is loading...\";\n }\n if (root.Bokeh !== undefined) {\n if (el != null) {\n el.textContent = \"BokehJS \" + root.Bokeh.version + \" successfully loaded.\";\n }\n } else if (Date.now() < root._bokeh_timeout) {\n setTimeout(display_loaded, 100)\n }\n }\n\n\n function run_callbacks() {\n try {\n root._bokeh_onload_callbacks.forEach(function(callback) {\n if (callback != null)\n callback();\n });\n } finally {\n delete root._bokeh_onload_callbacks\n }\n console.debug(\"Bokeh: all callbacks have finished\");\n }\n\n function load_libs(css_urls, js_urls, callback) {\n if (css_urls == null) css_urls = [];\n if (js_urls == null) js_urls = [];\n\n root._bokeh_onload_callbacks.push(callback);\n if (root._bokeh_is_loading > 0) {\n console.debug(\"Bokeh: BokehJS is being loaded, scheduling callback at\", now());\n return null;\n }\n if (js_urls == null || js_urls.length === 0) {\n run_callbacks();\n return null;\n }\n console.debug(\"Bokeh: BokehJS not loaded, scheduling load and callback at\", now());\n root._bokeh_is_loading = css_urls.length + js_urls.length;\n\n function on_load() {\n root._bokeh_is_loading--;\n if (root._bokeh_is_loading === 0) {\n console.debug(\"Bokeh: all BokehJS libraries/stylesheets loaded\");\n run_callbacks()\n }\n }\n\n function on_error() {\n console.error(\"failed to load \" + url);\n }\n\n for (var i = 0; i < css_urls.length; i++) {\n var url = css_urls[i];\n const element = document.createElement(\"link\");\n element.onload = on_load;\n element.onerror = on_error;\n element.rel = \"stylesheet\";\n element.type = \"text/css\";\n element.href = url;\n console.debug(\"Bokeh: injecting link tag for BokehJS stylesheet: \", url);\n document.body.appendChild(element);\n }\n\n const hashes = {\"https://cdn.bokeh.org/bokeh/release/bokeh-2.0.2.min.js\": \"ufR9RFnRs6lniiaFvtJziE0YeidtAgBRH6ux2oUItHw5WTvE1zuk9uzhUU/FJXDp\", \"https://cdn.bokeh.org/bokeh/release/bokeh-widgets-2.0.2.min.js\": \"8QM/PGWBT+IssZuRcDcjzwIh1mkOmJSoNMmyYDZbCfXJg3Ap1lEvdVgFuSAwhb/J\", \"https://cdn.bokeh.org/bokeh/release/bokeh-tables-2.0.2.min.js\": \"Jm8cH3Rg0P6UeZhVY5cLy1WzKajUT9KImCY+76hEqrcJt59/d8GPvFHjCkYgnSIn\", \"https://cdn.bokeh.org/bokeh/release/bokeh-gl-2.0.2.min.js\": \"Ozhzj+SI7ywm74aOI/UajcWz+C0NjsPunEVyVIrxzYkB+jA+2tUw8x5xJCbVtK5I\"};\n\n for (var i = 0; i < js_urls.length; i++) {\n var url = js_urls[i];\n var element = document.createElement('script');\n element.onload = on_load;\n element.onerror = on_error;\n element.async = false;\n element.src = url;\n if (url in hashes) {\n element.crossOrigin = \"anonymous\";\n element.integrity = \"sha384-\" + hashes[url];\n }\n console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n document.head.appendChild(element);\n }\n };\n\n function inject_raw_css(css) {\n const element = document.createElement(\"style\");\n element.appendChild(document.createTextNode(css));\n document.body.appendChild(element);\n }\n\n \n var js_urls = [\"https://cdn.bokeh.org/bokeh/release/bokeh-2.0.2.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-widgets-2.0.2.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-tables-2.0.2.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-gl-2.0.2.min.js\"];\n var css_urls = [];\n \n\n var inline_js = [\n function(Bokeh) {\n Bokeh.set_log_level(\"info\");\n },\n function(Bokeh) {\n \n \n }\n ];\n\n function run_inline_js() {\n \n if (root.Bokeh !== undefined || force === true) {\n \n for (var i = 0; i < inline_js.length; i++) {\n inline_js[i].call(root, root.Bokeh);\n }\n if (force === true) {\n display_loaded();\n }} else if (Date.now() < root._bokeh_timeout) {\n setTimeout(run_inline_js, 100);\n } else if (!root._bokeh_failed_load) {\n console.log(\"Bokeh: BokehJS failed to load within specified timeout.\");\n root._bokeh_failed_load = true;\n } else if (force !== true) {\n var cell = $(document.getElementById(\"1001\")).parents('.cell').data().cell;\n cell.output_area.append_execute_result(NB_LOAD_WARNING)\n }\n\n }\n\n if (root._bokeh_is_loading === 0) {\n console.debug(\"Bokeh: BokehJS loaded, going straight to plotting\");\n run_inline_js();\n } else {\n load_libs(css_urls, js_urls, function() {\n console.debug(\"Bokeh: BokehJS plotting callback run at\", now());\n run_inline_js();\n });\n }\n}(window));" }, "metadata": {}, "output_type": "display_data" @@ -401,14 +401,20 @@ "#from bioscrape.types import Model\n", "#from bioscrape.simulator import py_simulate_model\n", "#For arrays and plotting\n", - "import numpy as np\n", - "import pylab as plt\n", + "\n", "try:\n", + " import numpy as np\n", + " import pylab as plt\n", " make_heatmap = True\n", + " import numpy as np\n", + " import pylab as plt\n", + " import bioscrape\n", " import seaborn as sns\n", " import pandas as pd\n", "except ModuleNotFoundError:\n", " make_heatmap = False\n", + " print('please install the plotting libraries: pip install biocrnpyler[all]')\n", + "\n", "#this is for the network representation\n", "try:\n", " import bokeh.plotting\n", @@ -418,6 +424,8 @@ " from biocrnpyler import plotting\n", "except (ModuleNotFoundError,ImportError) as e:\n", " plotCRN = False\n", + " print('please install the plotting libraries: pip install biocrnpyler[all]')\n", + "\n", "#biocrnpyler\n", "from biocrnpyler import *" ] @@ -432,56 +440,58 @@ }, { "cell_type": "code", - "execution_count": 14, + "execution_count": 2, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ + "mixture.add_component: DNAassembly: mydna rna_mydna\n", + "mixture.update_species: DNAassembly: mydna rna_mydna\n", "The species and reactions in the CRN:\n", - " Species (17) = {0. dna[mydna], 1. protein[GFP], 2. complex[complex[dna[mydna]:protein[hrpR]:protein[hrpS]]:protein[RNAP]], 3. complex[dna[mydna]:protein[hrpS]], 4. complex[dna[mydna]:protein[RNAP]], 5. complex[dna[mydna]:protein[hrpR]], 6. complex[complex[dna[mydna]:protein[hrpR]]:protein[RNAP]], 7. complex[protein[Ribo]:rna[mydna]], 8. complex[protein[RNAase]:rna[mydna]], 9. protein[RNAP], 10. rna[mydna], 11. protein[RNAase], 12. protein[Ribo], 13. complex[dna[mydna]:protein[hrpR]:protein[hrpS]], 14. complex[complex[dna[mydna]:protein[hrpS]]:protein[RNAP]], 15. protein[hrpR], 16. protein[hrpS]}\n", + " Species (17) = {0. protein[Ribo], 1. complex[dna[mydna]:protein[hrpR]], 2. protein[GFP], 3. complex[protein[Ribo]:rna[mydna]], 4. complex[dna[mydna]:protein[RNAP]], 5. complex[complex[dna[mydna]:protein[hrpR]:protein[hrpS]]:protein[RNAP]], 6. protein[RNAase], 7. complex[dna[mydna]:protein[hrpR]:protein[hrpS]], 8. complex[protein[RNAase]:rna[mydna]], 9. complex[complex[dna[mydna]:protein[hrpR]]:protein[RNAP]], 10. rna[mydna], 11. complex[dna[mydna]:protein[hrpS]], 12. dna[mydna], 13. protein[RNAP], 14. complex[complex[dna[mydna]:protein[hrpS]]:protein[RNAP]], 15. protein[hrpR], 16. protein[hrpS]}\n", "Reactions (16) = [\n", "0. dna[mydna] + protein[RNAP] <--> complex[dna[mydna]:protein[RNAP]] \n", - " massaction: k_f(dna[mydna],protein[RNAP])=100.0*dna[mydna]*protein[RNAP]\n", + " massaction: k_f(dna[mydna],protein[RNAP])=100*dna[mydna]*protein[RNAP]\n", " k_r(complex[dna[mydna]:protein[RNAP]])=100*complex[dna[mydna]:protein[RNAP]]\n", "1. complex[dna[mydna]:protein[RNAP]] --> dna[mydna] + rna[mydna] + protein[RNAP] \n", " massaction: k_f(complex[dna[mydna]:protein[RNAP]])=0.01*complex[dna[mydna]:protein[RNAP]]\n", "2. protein[hrpR] + dna[mydna] <--> complex[dna[mydna]:protein[hrpR]] \n", - " massaction: k_f(protein[hrpR],dna[mydna])=100.0*protein[hrpR]*dna[mydna]\n", + " massaction: k_f(protein[hrpR],dna[mydna])=100*protein[hrpR]*dna[mydna]\n", " k_r(complex[dna[mydna]:protein[hrpR]])=50*complex[dna[mydna]:protein[hrpR]]\n", "3. protein[hrpS] + dna[mydna] <--> complex[dna[mydna]:protein[hrpS]] \n", - " massaction: k_f(protein[hrpS],dna[mydna])=100.0*protein[hrpS]*dna[mydna]\n", + " massaction: k_f(protein[hrpS],dna[mydna])=100*protein[hrpS]*dna[mydna]\n", " k_r(complex[dna[mydna]:protein[hrpS]])=50*complex[dna[mydna]:protein[hrpS]]\n", "4. protein[hrpR] + complex[dna[mydna]:protein[hrpS]] <--> complex[dna[mydna]:protein[hrpR]:protein[hrpS]] \n", - " massaction: k_f(protein[hrpR],complex[dna[mydna]:protein[hrpS]])=100.0*protein[hrpR]*complex[dna[mydna]:protein[hrpS]]\n", + " massaction: k_f(protein[hrpR],complex[dna[mydna]:protein[hrpS]])=100*protein[hrpR]*complex[dna[mydna]:protein[hrpS]]\n", " k_r(complex[dna[mydna]:protein[hrpR]:protein[hrpS]])=50*complex[dna[mydna]:protein[hrpR]:protein[hrpS]]\n", "5. protein[hrpS] + complex[dna[mydna]:protein[hrpR]] <--> complex[dna[mydna]:protein[hrpR]:protein[hrpS]] \n", - " massaction: k_f(protein[hrpS],complex[dna[mydna]:protein[hrpR]])=100.0*protein[hrpS]*complex[dna[mydna]:protein[hrpR]]\n", + " massaction: k_f(protein[hrpS],complex[dna[mydna]:protein[hrpR]])=100*protein[hrpS]*complex[dna[mydna]:protein[hrpR]]\n", " k_r(complex[dna[mydna]:protein[hrpR]:protein[hrpS]])=50*complex[dna[mydna]:protein[hrpR]:protein[hrpS]]\n", "6. complex[dna[mydna]:protein[hrpR]] + protein[RNAP] <--> complex[complex[dna[mydna]:protein[hrpR]]:protein[RNAP]] \n", - " massaction: k_f(complex[dna[mydna]:protein[hrpR]],protein[RNAP])=100.0*complex[dna[mydna]:protein[hrpR]]*protein[RNAP]\n", - " k_r(complex[complex[dna[mydna]:protein[hrpR]]:protein[RNAP]])=10.0*complex[complex[dna[mydna]:protein[hrpR]]:protein[RNAP]]\n", + " massaction: k_f(complex[dna[mydna]:protein[hrpR]],protein[RNAP])=100*complex[dna[mydna]:protein[hrpR]]*protein[RNAP]\n", + " k_r(complex[complex[dna[mydna]:protein[hrpR]]:protein[RNAP]])=10*complex[complex[dna[mydna]:protein[hrpR]]:protein[RNAP]]\n", "7. complex[complex[dna[mydna]:protein[hrpR]]:protein[RNAP]] --> complex[dna[mydna]:protein[hrpR]] + rna[mydna] + protein[RNAP] \n", " massaction: k_f(complex[complex[dna[mydna]:protein[hrpR]]:protein[RNAP]])=0.05*complex[complex[dna[mydna]:protein[hrpR]]:protein[RNAP]]\n", "8. complex[dna[mydna]:protein[hrpS]] + protein[RNAP] <--> complex[complex[dna[mydna]:protein[hrpS]]:protein[RNAP]] \n", - " massaction: k_f(complex[dna[mydna]:protein[hrpS]],protein[RNAP])=100.0*complex[dna[mydna]:protein[hrpS]]*protein[RNAP]\n", - " k_r(complex[complex[dna[mydna]:protein[hrpS]]:protein[RNAP]])=10.0*complex[complex[dna[mydna]:protein[hrpS]]:protein[RNAP]]\n", + " massaction: k_f(complex[dna[mydna]:protein[hrpS]],protein[RNAP])=100*complex[dna[mydna]:protein[hrpS]]*protein[RNAP]\n", + " k_r(complex[complex[dna[mydna]:protein[hrpS]]:protein[RNAP]])=10*complex[complex[dna[mydna]:protein[hrpS]]:protein[RNAP]]\n", "9. complex[complex[dna[mydna]:protein[hrpS]]:protein[RNAP]] --> complex[dna[mydna]:protein[hrpS]] + rna[mydna] + protein[RNAP] \n", " massaction: k_f(complex[complex[dna[mydna]:protein[hrpS]]:protein[RNAP]])=0.05*complex[complex[dna[mydna]:protein[hrpS]]:protein[RNAP]]\n", "10. complex[dna[mydna]:protein[hrpR]:protein[hrpS]] + protein[RNAP] <--> complex[complex[dna[mydna]:protein[hrpR]:protein[hrpS]]:protein[RNAP]] \n", - " massaction: k_f(complex[dna[mydna]:protein[hrpR]:protein[hrpS]],protein[RNAP])=100.0*complex[dna[mydna]:protein[hrpR]:protein[hrpS]]*protein[RNAP]\n", - " k_r(complex[complex[dna[mydna]:protein[hrpR]:protein[hrpS]]:protein[RNAP]])=10.0*complex[complex[dna[mydna]:protein[hrpR]:protein[hrpS]]:protein[RNAP]]\n", + " massaction: k_f(complex[dna[mydna]:protein[hrpR]:protein[hrpS]],protein[RNAP])=100*complex[dna[mydna]:protein[hrpR]:protein[hrpS]]*protein[RNAP]\n", + " k_r(complex[complex[dna[mydna]:protein[hrpR]:protein[hrpS]]:protein[RNAP]])=10*complex[complex[dna[mydna]:protein[hrpR]:protein[hrpS]]:protein[RNAP]]\n", "11. complex[complex[dna[mydna]:protein[hrpR]:protein[hrpS]]:protein[RNAP]] --> complex[dna[mydna]:protein[hrpR]:protein[hrpS]] + rna[mydna] + protein[RNAP] \n", " massaction: k_f(complex[complex[dna[mydna]:protein[hrpR]:protein[hrpS]]:protein[RNAP]])=0.05*complex[complex[dna[mydna]:protein[hrpR]:protein[hrpS]]:protein[RNAP]]\n", "12. rna[mydna] + protein[Ribo] <--> complex[protein[Ribo]:rna[mydna]] \n", - " massaction: k_f(rna[mydna],protein[Ribo])=100.0*rna[mydna]*protein[Ribo]\n", + " massaction: k_f(rna[mydna],protein[Ribo])=100*rna[mydna]*protein[Ribo]\n", " k_r(complex[protein[Ribo]:rna[mydna]])=10.0*complex[protein[Ribo]:rna[mydna]]\n", "13. complex[protein[Ribo]:rna[mydna]] --> rna[mydna] + protein[GFP] + protein[Ribo] \n", " massaction: k_f(complex[protein[Ribo]:rna[mydna]])=1.5*complex[protein[Ribo]:rna[mydna]]\n", "14. rna[mydna] + protein[RNAase] <--> complex[protein[RNAase]:rna[mydna]] \n", - " massaction: k_f(rna[mydna],protein[RNAase])=100.0*rna[mydna]*protein[RNAase]\n", - " k_r(complex[protein[RNAase]:rna[mydna]])=10.0*complex[protein[RNAase]:rna[mydna]]\n", + " massaction: k_f(rna[mydna],protein[RNAase])=100*rna[mydna]*protein[RNAase]\n", + " k_r(complex[protein[RNAase]:rna[mydna]])=10*complex[protein[RNAase]:rna[mydna]]\n", "15. complex[protein[RNAase]:rna[mydna]] --> protein[RNAase] \n", " massaction: k_f(complex[protein[RNAase]:rna[mydna]])=0.000555556*complex[protein[RNAase]:rna[mydna]]\n", "]\n" @@ -505,7 +515,7 @@ "\n", "\n", "\n", - "
\n" + "
\n" ] }, "metadata": {}, @@ -517,8 +527,8 @@ "(function(root) {\n", " function embed_document(root) {\n", " \n", - " var docs_json = {\"8eb7364d-9ee0-4936-8dcc-c86c47ac2f1a\":{\"roots\":{\"references\":[{\"attributes\":{\"plot_height\":500,\"plot_width\":500,\"renderers\":[{\"id\":\"2051\"},{\"id\":\"2023\"},{\"id\":\"2037\"}],\"title\":{\"id\":\"2235\"},\"toolbar\":{\"id\":\"2132\"},\"x_range\":{\"id\":\"2093\"},\"x_scale\":{\"id\":\"2234\"},\"y_range\":{\"id\":\"2094\"},\"y_scale\":{\"id\":\"2233\"}},\"id\":\"2020\",\"type\":\"Plot\"},{\"attributes\":{},\"id\":\"2268\",\"type\":\"UnionRenderers\"},{\"attributes\":{},\"id\":\"2276\",\"type\":\"UnionRenderers\"},{\"attributes\":{\"edge_renderer\":{\"id\":\"2030\"},\"inspection_policy\":{\"id\":\"2245\"},\"layout_provider\":{\"id\":\"2036\"},\"node_renderer\":{\"id\":\"2026\"},\"selection_policy\":{\"id\":\"2254\"}},\"id\":\"2023\",\"type\":\"GraphRenderer\"},{\"attributes\":{\"data_source\":{\"id\":\"2039\"},\"glyph\":{\"id\":\"2110\"},\"hover_glyph\":{\"id\":\"2120\"},\"muted_glyph\":null,\"selection_glyph\":{\"id\":\"2115\"},\"view\":{\"id\":\"2041\"}},\"id\":\"2040\",\"type\":\"GlyphRenderer\"},{\"attributes\":{},\"id\":\"2233\",\"type\":\"LinearScale\"},{\"attributes\":{\"text\":\"\"},\"id\":\"2235\",\"type\":\"Title\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"size\":{\"units\":\"screen\",\"value\":12}},\"id\":\"2110\",\"type\":\"Circle\"},{\"attributes\":{\"bottom_units\":\"screen\",\"fill_alpha\":0.5,\"fill_color\":\"lightgrey\",\"left_units\":\"screen\",\"level\":\"overlay\",\"line_alpha\":1.0,\"line_color\":\"black\",\"line_dash\":[4,4],\"line_width\":2,\"render_mode\":\"css\",\"right_units\":\"screen\",\"top_units\":\"screen\"},\"id\":\"2265\",\"type\":\"BoxAnnotation\"},{\"attributes\":{},\"id\":\"2269\",\"type\":\"Selection\"},{\"attributes\":{\"fill_color\":{\"value\":\"#fdae61\"},\"size\":{\"units\":\"screen\",\"value\":15}},\"id\":\"2115\",\"type\":\"Circle\"},{\"attributes\":{\"graph_layout\":{\"0\":[-159.2644697481072,-95.01659919572936],\"1\":[-24.95206255401747,-28.796731204667896],\"10\":[8.093230436938587,-31.298583132130158],\"11\":[91.93978395828509,93.07420257277103],\"12\":[74.97593135649333,93.93152904933689],\"13\":[100.5052233520395,82.49902452920922],\"14\":[7.105871768422399,-38.65437247711602],\"15\":[-4.616722186471445,15.310777071238443],\"16\":[-3.0749012846013666,-10.73140389528782],\"17\":[-15.454910601544976,-24.974880478238877],\"18\":[-28.12071253233513,-43.849029027436394],\"19\":[-60.07431169868613,-66.99105346309918],\"2\":[-152.75159829378953,-60.43195461667418],\"20\":[-6.893860059548873,-19.0375487723802],\"21\":[-22.327592199191397,-15.546768357604067],\"22\":[2.8955675636407228,-9.945815949602656],\"23\":[-1.366956029866812,-31.193953367079974],\"24\":[30.589836410130008,-18.684548236367995],\"25\":[53.13256746342284,-10.106898045878879],\"26\":[-0.7102861981929732,0.9986445668881058],\"27\":[-8.348856929658716,26.317821856724468],\"28\":[19.099547652106743,-54.68350493022234],\"29\":[35.55439918754469,-82.50034156646389],\"3\":[28.635540355974683,-70.65735329055241],\"30\":[103.22854699287531,87.36788085485956],\"31\":[127.29180027011469,81.70561078106734],\"32\":[78.86621144452673,98.23932782479385],\"33\":[65.65740858378635,108.2243734030081],\"4\":[-12.247827442728601,-2.185630887961543],\"5\":[-46.463449980535486,-57.17942645291274],\"6\":[11.381275991223156,-19.45739699351974],\"7\":[42.97117228654644,-14.036576974353984],\"8\":[116.64065698258389,84.28368958146413],\"9\":[71.35879514696282,104.20426285969073]}},\"id\":\"2050\",\"type\":\"StaticLayoutProvider\"},{\"attributes\":{\"data_source\":{\"id\":\"2029\"},\"glyph\":{\"id\":\"2028\"},\"hover_glyph\":null,\"muted_glyph\":null,\"view\":{\"id\":\"2031\"}},\"id\":\"2030\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"callback\":null},\"id\":\"2128\",\"type\":\"TapTool\"},{\"attributes\":{\"line_alpha\":{\"value\":0.2},\"line_width\":{\"value\":4}},\"id\":\"2070\",\"type\":\"MultiLine\"},{\"attributes\":{\"source\":{\"id\":\"2053\"}},\"id\":\"2055\",\"type\":\"CDSView\"},{\"attributes\":{},\"id\":\"2245\",\"type\":\"NodesOnly\"},{\"attributes\":{\"edge_renderer\":{\"id\":\"2058\"},\"inspection_policy\":{\"id\":\"2141\"},\"layout_provider\":{\"id\":\"2064\"},\"node_renderer\":{\"id\":\"2054\"},\"selection_policy\":{\"id\":\"2139\"}},\"id\":\"2051\",\"type\":\"GraphRenderer\"},{\"attributes\":{},\"id\":\"2270\",\"type\":\"UnionRenderers\"},{\"attributes\":{},\"id\":\"2271\",\"type\":\"Selection\"},{\"attributes\":{},\"id\":\"2141\",\"type\":\"EdgesAndLinkedNodes\"},{\"attributes\":{\"graph_layout\":{\"0\":[-159.2644697481072,-95.01659919572936],\"1\":[-24.95206255401747,-28.796731204667896],\"10\":[8.093230436938587,-31.298583132130158],\"11\":[91.93978395828509,93.07420257277103],\"12\":[74.97593135649333,93.93152904933689],\"13\":[100.5052233520395,82.49902452920922],\"14\":[7.105871768422399,-38.65437247711602],\"15\":[-4.616722186471445,15.310777071238443],\"16\":[-3.0749012846013666,-10.73140389528782],\"17\":[-15.454910601544976,-24.974880478238877],\"18\":[-28.12071253233513,-43.849029027436394],\"19\":[-60.07431169868613,-66.99105346309918],\"2\":[-152.75159829378953,-60.43195461667418],\"20\":[-6.893860059548873,-19.0375487723802],\"21\":[-22.327592199191397,-15.546768357604067],\"22\":[2.8955675636407228,-9.945815949602656],\"23\":[-1.366956029866812,-31.193953367079974],\"24\":[30.589836410130008,-18.684548236367995],\"25\":[53.13256746342284,-10.106898045878879],\"26\":[-0.7102861981929732,0.9986445668881058],\"27\":[-8.348856929658716,26.317821856724468],\"28\":[19.099547652106743,-54.68350493022234],\"29\":[35.55439918754469,-82.50034156646389],\"3\":[28.635540355974683,-70.65735329055241],\"30\":[103.22854699287531,87.36788085485956],\"31\":[127.29180027011469,81.70561078106734],\"32\":[78.86621144452673,98.23932782479385],\"33\":[65.65740858378635,108.2243734030081],\"4\":[-12.247827442728601,-2.185630887961543],\"5\":[-46.463449980535486,-57.17942645291274],\"6\":[11.381275991223156,-19.45739699351974],\"7\":[42.97117228654644,-14.036576974353984],\"8\":[116.64065698258389,84.28368958146413],\"9\":[71.35879514696282,104.20426285969073]}},\"id\":\"2064\",\"type\":\"StaticLayoutProvider\"},{\"attributes\":{},\"id\":\"2130\",\"type\":\"PanTool\"},{\"attributes\":{},\"id\":\"2131\",\"type\":\"WheelZoomTool\"},{\"attributes\":{\"data_source\":{\"id\":\"2025\"},\"glyph\":{\"id\":\"2095\"},\"hover_glyph\":{\"id\":\"2105\"},\"muted_glyph\":null,\"selection_glyph\":{\"id\":\"2100\"},\"view\":{\"id\":\"2027\"}},\"id\":\"2026\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"source\":{\"id\":\"2057\"}},\"id\":\"2059\",\"type\":\"CDSView\"},{\"attributes\":{},\"id\":\"2272\",\"type\":\"UnionRenderers\"},{\"attributes\":{\"graph_layout\":{\"0\":[-159.2644697481072,-95.01659919572936],\"1\":[-24.95206255401747,-28.796731204667896],\"10\":[8.093230436938587,-31.298583132130158],\"11\":[91.93978395828509,93.07420257277103],\"12\":[74.97593135649333,93.93152904933689],\"13\":[100.5052233520395,82.49902452920922],\"14\":[7.105871768422399,-38.65437247711602],\"15\":[-4.616722186471445,15.310777071238443],\"16\":[-3.0749012846013666,-10.73140389528782],\"17\":[-15.454910601544976,-24.974880478238877],\"18\":[-28.12071253233513,-43.849029027436394],\"19\":[-60.07431169868613,-66.99105346309918],\"2\":[-152.75159829378953,-60.43195461667418],\"20\":[-6.893860059548873,-19.0375487723802],\"21\":[-22.327592199191397,-15.546768357604067],\"22\":[2.8955675636407228,-9.945815949602656],\"23\":[-1.366956029866812,-31.193953367079974],\"24\":[30.589836410130008,-18.684548236367995],\"25\":[53.13256746342284,-10.106898045878879],\"26\":[-0.7102861981929732,0.9986445668881058],\"27\":[-8.348856929658716,26.317821856724468],\"28\":[19.099547652106743,-54.68350493022234],\"29\":[35.55439918754469,-82.50034156646389],\"3\":[28.635540355974683,-70.65735329055241],\"30\":[103.22854699287531,87.36788085485956],\"31\":[127.29180027011469,81.70561078106734],\"32\":[78.86621144452673,98.23932782479385],\"33\":[65.65740858378635,108.2243734030081],\"4\":[-12.247827442728601,-2.185630887961543],\"5\":[-46.463449980535486,-57.17942645291274],\"6\":[11.381275991223156,-19.45739699351974],\"7\":[42.97117228654644,-14.036576974353984],\"8\":[116.64065698258389,84.28368958146413],\"9\":[71.35879514696282,104.20426285969073]}},\"id\":\"2036\",\"type\":\"StaticLayoutProvider\"},{\"attributes\":{\"source\":{\"id\":\"2025\"}},\"id\":\"2027\",\"type\":\"CDSView\"},{\"attributes\":{},\"id\":\"2273\",\"type\":\"Selection\"},{\"attributes\":{\"fill_color\":{\"value\":\"#2b83ba\"},\"size\":{\"units\":\"screen\",\"value\":8}},\"id\":\"2095\",\"type\":\"Square\"},{\"attributes\":{},\"id\":\"2139\",\"type\":\"NodesAndLinkedEdges\"},{\"attributes\":{\"attachment\":\"right\",\"callback\":null,\"renderers\":[{\"id\":\"2023\"}],\"tooltips\":[[\"reaction\",\"@species\"],[\"type\",\"@type\"],[\"k_f\",\"@k\"],[\"k_r\",\"@k_r\"]]},\"id\":\"2127\",\"type\":\"HoverTool\"},{\"attributes\":{},\"id\":\"2274\",\"type\":\"UnionRenderers\"},{\"attributes\":{\"data_source\":{\"id\":\"2053\"},\"glyph\":{\"id\":\"2065\"},\"hover_glyph\":null,\"muted_glyph\":null,\"view\":{\"id\":\"2055\"}},\"id\":\"2054\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"data_source\":{\"id\":\"2057\"},\"glyph\":{\"id\":\"2070\"},\"hover_glyph\":{\"id\":\"2080\"},\"muted_glyph\":null,\"selection_glyph\":{\"id\":\"2075\"},\"view\":{\"id\":\"2059\"}},\"id\":\"2058\",\"type\":\"GlyphRenderer\"},{\"attributes\":{},\"id\":\"2264\",\"type\":\"NodesOnly\"},{\"attributes\":{\"data\":{\"end\":[],\"start\":[]},\"selected\":{\"id\":\"2271\"},\"selection_policy\":{\"id\":\"2270\"}},\"id\":\"2029\",\"type\":\"ColumnDataSource\"},{\"attributes\":{},\"id\":\"2275\",\"type\":\"Selection\"},{\"attributes\":{},\"id\":\"2254\",\"type\":\"NodesOnly\"},{\"attributes\":{\"line_color\":{\"value\":\"#abdda4\"},\"line_width\":{\"value\":5}},\"id\":\"2080\",\"type\":\"MultiLine\"},{\"attributes\":{\"fill_alpha\":{\"value\":0},\"fill_color\":{\"field\":\"color\"},\"line_alpha\":{\"value\":0},\"size\":{\"units\":\"screen\",\"value\":12}},\"id\":\"2065\",\"type\":\"Circle\"},{\"attributes\":{\"source\":{\"id\":\"2029\"}},\"id\":\"2031\",\"type\":\"CDSView\"},{\"attributes\":{\"line_color\":{\"value\":\"#fdae61\"},\"line_width\":{\"value\":5}},\"id\":\"2075\",\"type\":\"MultiLine\"},{\"attributes\":{\"fill_color\":{\"value\":\"#fdae61\"},\"size\":{\"units\":\"screen\",\"value\":8}},\"id\":\"2100\",\"type\":\"Square\"},{\"attributes\":{\"fill_color\":{\"value\":\"#abdda4\"},\"size\":{\"units\":\"screen\",\"value\":15}},\"id\":\"2120\",\"type\":\"Circle\"},{\"attributes\":{\"source\":{\"id\":\"2039\"}},\"id\":\"2041\",\"type\":\"CDSView\"},{\"attributes\":{\"end\":159.88480016432183,\"start\":-134.16076832777762},\"id\":\"2094\",\"type\":\"Range1d\"},{\"attributes\":{},\"id\":\"2266\",\"type\":\"UnionRenderers\"},{\"attributes\":{},\"id\":\"2267\",\"type\":\"Selection\"},{\"attributes\":{\"attachment\":\"right\",\"callback\":null,\"renderers\":[{\"id\":\"2037\"}],\"tooltips\":[[\"name\",\"@species\"],[\"type\",\"@type\"]]},\"id\":\"2126\",\"type\":\"HoverTool\"},{\"attributes\":{\"data\":{\"color\":[\"blue\",\"blue\",\"blue\",\"blue\",\"blue\",\"blue\",\"blue\",\"blue\",\"blue\",\"blue\",\"blue\",\"blue\",\"blue\",\"blue\",\"blue\",\"blue\"],\"index\":[18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33],\"k\":[100.0,0.01,100.0,100.0,100.0,100.0,100.0,0.05,100.0,0.05,100.0,0.05,100.0,1.5,100.0,0.000555556],\"k_r\":[100,0,50,50,50,50,10.0,0,10.0,0,10.0,0,10.0,0,10.0,0],\"species\":[\"dna_mydna + protein_RNAP <--> complex_dna_mydna_protein_RNAP massaction: k_f(dna_mydna,protein_RNAP)=100.0*dna_mydna*protein_RNAP k_r(complex_dna_mydna_protein_RNAP)=100*complex_dna_mydna_protein_RNAP\",\"complex_dna_mydna_protein_RNAP --> dna_mydna + rna_mydna + protein_RNAP massaction: k_f(complex_dna_mydna_protein_RNAP)=0.01*complex_dna_mydna_protein_RNAP\",\"protein_hrpR + dna_mydna <--> complex_dna_mydna_protein_hrpR massaction: k_f(protein_hrpR,dna_mydna)=100.0*protein_hrpR*dna_mydna k_r(complex_dna_mydna_protein_hrpR)=50*complex_dna_mydna_protein_hrpR\",\"protein_hrpS + dna_mydna <--> complex_dna_mydna_protein_hrpS massaction: k_f(protein_hrpS,dna_mydna)=100.0*protein_hrpS*dna_mydna k_r(complex_dna_mydna_protein_hrpS)=50*complex_dna_mydna_protein_hrpS\",\"protein_hrpR + complex_dna_mydna_protein_hrpS <--> complex_dna_mydna_protein_hrpR_protein_hrpS massaction: k_f(protein_hrpR,complex_dna_mydna_protein_hrpS)=100.0*protein_hrpR*complex_dna_mydna_protein_hrpS k_r(complex_dna_mydna_protein_hrpR_protein_hrpS)=50*complex_dna_mydna_protein_hrpR_protein_hrpS\",\"protein_hrpS + complex_dna_mydna_protein_hrpR <--> complex_dna_mydna_protein_hrpR_protein_hrpS massaction: k_f(protein_hrpS,complex_dna_mydna_protein_hrpR)=100.0*protein_hrpS*complex_dna_mydna_protein_hrpR k_r(complex_dna_mydna_protein_hrpR_protein_hrpS)=50*complex_dna_mydna_protein_hrpR_protein_hrpS\",\"complex_dna_mydna_protein_hrpR + protein_RNAP <--> complex_dna_mydna_protein_hrpR_protein_RNAP massaction: k_f(complex_dna_mydna_protein_hrpR,protein_RNAP)=100.0*complex_dna_mydna_protein_hrpR*protein_RNAP k_r(complex_dna_mydna_protein_hrpR_protein_RNAP)=10.0*complex_dna_mydna_protein_hrpR_protein_RNAP\",\"complex_dna_mydna_protein_hrpR_protein_RNAP --> complex_dna_mydna_protein_hrpR + rna_mydna + protein_RNAP massaction: k_f(complex_dna_mydna_protein_hrpR_protein_RNAP)=0.05*complex_dna_mydna_protein_hrpR_protein_RNAP\",\"complex_dna_mydna_protein_hrpS + protein_RNAP <--> complex_dna_mydna_protein_hrpS_protein_RNAP massaction: k_f(complex_dna_mydna_protein_hrpS,protein_RNAP)=100.0*complex_dna_mydna_protein_hrpS*protein_RNAP k_r(complex_dna_mydna_protein_hrpS_protein_RNAP)=10.0*complex_dna_mydna_protein_hrpS_protein_RNAP\",\"complex_dna_mydna_protein_hrpS_protein_RNAP --> complex_dna_mydna_protein_hrpS + rna_mydna + protein_RNAP massaction: k_f(complex_dna_mydna_protein_hrpS_protein_RNAP)=0.05*complex_dna_mydna_protein_hrpS_protein_RNAP\",\"complex_dna_mydna_protein_hrpR_protein_hrpS + protein_RNAP <--> complex_dna_mydna_protein_hrpR_protein_hrpS_protein_RNAP massaction: k_f(complex_dna_mydna_protein_hrpR_protein_hrpS,protein_RNAP)=100.0*complex_dna_mydna_protein_hrpR_protein_hrpS*protein_RNAP k_r(complex_dna_mydna_protein_hrpR_protein_hrpS_protein_RNAP)=10.0*complex_dna_mydna_protein_hrpR_protein_hrpS_protein_RNAP\",\"complex_dna_mydna_protein_hrpR_protein_hrpS_protein_RNAP --> complex_dna_mydna_protein_hrpR_protein_hrpS + rna_mydna + protein_RNAP massaction: k_f(complex_dna_mydna_protein_hrpR_protein_hrpS_protein_RNAP)=0.05*complex_dna_mydna_protein_hrpR_protein_hrpS_protein_RNAP\",\"rna_mydna + protein_Ribo <--> complex_protein_Ribo_rna_mydna massaction: k_f(rna_mydna,protein_Ribo)=100.0*rna_mydna*protein_Ribo k_r(complex_protein_Ribo_rna_mydna)=10.0*complex_protein_Ribo_rna_mydna\",\"complex_protein_Ribo_rna_mydna --> rna_mydna + protein_GFP + protein_Ribo massaction: k_f(complex_protein_Ribo_rna_mydna)=1.5*complex_protein_Ribo_rna_mydna\",\"rna_mydna + protein_RNAase <--> complex_protein_RNAase_rna_mydna massaction: k_f(rna_mydna,protein_RNAase)=100.0*rna_mydna*protein_RNAase k_r(complex_protein_RNAase_rna_mydna)=10.0*complex_protein_RNAase_rna_mydna\",\"complex_protein_RNAase_rna_mydna --> protein_RNAase massaction: k_f(complex_protein_RNAase_rna_mydna)=0.000555556*complex_protein_RNAase_rna_mydna\"],\"type\":[\"massaction\",\"massaction\",\"massaction\",\"massaction\",\"massaction\",\"massaction\",\"massaction\",\"massaction\",\"massaction\",\"massaction\",\"massaction\",\"massaction\",\"massaction\",\"massaction\",\"massaction\",\"massaction\"]},\"selected\":{\"id\":\"2273\"},\"selection_policy\":{\"id\":\"2272\"}},\"id\":\"2025\",\"type\":\"ColumnDataSource\"},{\"attributes\":{\"source\":{\"id\":\"2043\"}},\"id\":\"2045\",\"type\":\"CDSView\"},{\"attributes\":{\"data\":{\"color\":[\"purple\",\"grey\",\"green\",\"cyan\",\"cyan\",\"cyan\",\"cyan\",\"cyan\",\"cyan\",\"cyan\",\"green\",\"orange\",\"green\",\"green\",\"cyan\",\"cyan\",\"green\",\"green\"],\"index\":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17],\"species\":[\"nothing\",\"dna_mydna\",\"protein_GFP\",\"complex_dna_mydna_protein_hrpR_protein_hrpS_protein_RNAP\",\"complex_dna_mydna_protein_hrpS\",\"complex_dna_mydna_protein_RNAP\",\"complex_dna_mydna_protein_hrpR\",\"complex_dna_mydna_protein_hrpR_protein_RNAP\",\"complex_protein_Ribo_rna_mydna\",\"complex_protein_RNAase_rna_mydna\",\"protein_RNAP\",\"rna_mydna\",\"protein_RNAase\",\"protein_Ribo\",\"complex_dna_mydna_protein_hrpR_protein_hrpS\",\"complex_dna_mydna_protein_hrpS_protein_RNAP\",\"protein_hrpR\",\"protein_hrpS\"],\"type\":[\"nothing\",\"dna\",\"protein\",\"complex\",\"complex\",\"complex\",\"complex\",\"complex\",\"complex\",\"complex\",\"protein\",\"rna\",\"protein\",\"protein\",\"complex\",\"complex\",\"protein\",\"protein\"]},\"selected\":{\"id\":\"2277\"},\"selection_policy\":{\"id\":\"2276\"}},\"id\":\"2039\",\"type\":\"ColumnDataSource\"},{\"attributes\":{\"callback\":null,\"renderers\":[{\"id\":\"2051\"}],\"tooltips\":null},\"id\":\"2125\",\"type\":\"HoverTool\"},{\"attributes\":{},\"id\":\"2028\",\"type\":\"MultiLine\"},{\"attributes\":{},\"id\":\"2234\",\"type\":\"LinearScale\"},{\"attributes\":{\"end\":134.2928852342123,\"start\":-159.75268325788716},\"id\":\"2093\",\"type\":\"Range1d\"},{\"attributes\":{},\"id\":\"2255\",\"type\":\"NodesOnly\"},{\"attributes\":{\"data_source\":{\"id\":\"2043\"},\"glyph\":{\"id\":\"2042\"},\"hover_glyph\":null,\"muted_glyph\":null,\"view\":{\"id\":\"2045\"}},\"id\":\"2044\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"overlay\":{\"id\":\"2265\"}},\"id\":\"2129\",\"type\":\"BoxSelectTool\"},{\"attributes\":{\"data\":{\"end\":[18,20,21,28,29,21,22,26,18,19,20,23,24,24,25,30,31,32,33,18,24,26,28,30,32,32,30,22,23,28,26,27,20,22,21,23,1,10,5,1,11,10,16,1,6,17,1,4,16,4,14,17,6,14,6,10,7,6,11,10,4,10,15,4,11,10,14,10,3,14,11,10,11,13,8,11,2,13,11,12,9,12],\"start\":[1,1,1,3,3,4,4,4,5,5,6,6,6,7,7,8,8,9,9,10,10,10,10,11,11,12,13,14,14,14,15,15,16,16,17,17,18,18,18,19,19,19,20,20,20,21,21,21,22,22,22,23,23,23,24,24,24,25,25,25,26,26,26,27,27,27,28,28,28,29,29,29,30,30,30,31,31,31,32,32,32,33],\"weight\":[1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1],\"xs\":[[-24.95206255401747,-27.3997313701095,-29.67511248336003,-28.12071253233513,-24.78234686091758,-27.3997313701095],[-24.95206255401747,-9.972976078269703,-9.514674883141895,-6.893860059548873,-11.891881502846825,-9.972976078269703],[-24.95206255401747,-23.007638595554198,-20.71657552512999,-22.327592199191397,-25.621287316116362,-23.007638595554198],[28.635540355974683,20.893594541311575,23.46569653379591,19.099547652106743,19.172513575079954,20.893594541311575],[28.635540355974683,33.78886157789435,31.21149500425952,35.55439918754469,35.52873073856115,33.78886157789435],[-12.247827442728601,-20.219715993415324,-21.715539924752072,-22.327592199191397,-17.72400349581691,-20.219715993415324],[-12.247827442728601,-0.21926600772062033,-2.0981729028293015,2.8955675636407228,0.18209374051208327,-0.21926600772062033],[-12.247827442728601,-4.084147481923398,-4.219242322802155,-0.7102861981929732,-5.549471732313293,-4.084147481923398],[-46.463449980535486,-30.95200638394014,-30.153806005328267,-28.12071253233513,-33.09325449096664,-30.95200638394014],[-46.463449980535486,-57.23510979992378,-58.02363045294727,-60.07431169868613,-55.09979017070724,-57.23510979992378],[11.381275991223156,-3.394783331356612,-2.5074560943784965,-6.893860059548873,-2.6222944921322906,-3.394783331356612],[11.381275991223156,1.207978812684657,0.12541904384760505,-1.366956029866812,3.511980287102359,1.207978812684657],[11.381275991223156,27.09266591564532,26.36371518084855,30.589836410130008,26.162704812013956,27.09266591564532],[42.97117228654644,33.86655587117767,33.765093123785356,30.589836410130008,35.52235768030931,33.86655587117767],[42.97117228654644,49.868172169427986,49.995659651173504,53.13256746342284,48.19219169683242,49.868172169427986],[116.64065698258389,106.63952314396043,108.00880230660484,103.22854699287531,106.88826881783888,106.63952314396043],[116.64065698258389,123.89003139464185,122.4950681524501,127.29180027011469,123.67133734788584,123.89003139464185],[71.35879514696282,76.12588588406588,73.92072670918682,78.86621144452673,77.03114889415542,76.12588588406588],[71.35879514696282,68.51783519177974,70.63692470079863,65.65740858378635,67.755612775869,68.51783519177974],[8.093230436938587,-24.813680692260675,-24.847963058142717,-28.12071253233513,-23.210680336160475,-24.813680692260675],[8.093230436938587,27.536987690462993,28.035599759391776,30.589836410130008,25.590231503318435,27.536987690462993],[8.093230436938587,0.2101558281793653,2.840466355099198,-0.7102861981929732,-1.9835353870586552,0.2101558281793653],[8.093230436938587,17.60907530263989,14.993581008644435,19.099547652106743,19.517551671921705,17.60907530263989],[91.93978395828509,100.1049374117234,98.23626542844195,103.22854699287531,100.49189927507429,100.1049374117234],[91.93978395828509,82.12137153345533,83.81203704888736,78.86621144452673,81.97481821273003,82.12137153345533],[74.97593135649333,76.52042039550406,77.81944030302442,78.86621144452673,74.1086550419611,76.52042039550406],[100.5052233520395,101.51998090522227,103.296627610176,103.22854699287531,98.9328617014257,101.51998090522227],[7.105871768422399,3.403433673489972,5.997429724805155,2.8955675636407228,1.0503481249066577,3.403433673489972],[7.105871768422399,1.25987530295238,3.5350150666803755,-1.366956029866812,0.23079477552416017,1.25987530295238],[7.105871768422399,17.002701332732812,14.50368561739139,19.099547652106743,18.507060599937173,17.002701332732812],[-4.616722186471445,-1.6318837687599386,-4.262243232058207,-0.7102861981929732,0.561308240880792,-1.6318837687599386],[-4.616722186471445,-7.2249674116551565,-4.590800587293701,-8.348856929658716,-9.326007918771928,-7.2249674116551565],[-3.0749012846013666,-5.431780674709306,-7.356425953114683,-6.893860059548873,-2.8135859099242344,-5.431780674709306],[-3.0749012846013666,-0.5745224753183842,-1.0714192184832299,2.8955675636407228,-1.7236917318293803,-0.5745224753183842],[-15.454910601544976,-20.265878142603626,-17.75666142147193,-22.327592199191397,-21.797103695926644,-20.265878142603626],[-15.454910601544976,-4.568849406071483,-6.337888470290057,-1.366956029866812,-4.318655029450338,-4.568849406071483],[-28.12071253233513,-25.6730437162431,-23.39766260299257,-24.95206255401747,-28.290428225435015,-25.6730437162431],[-28.12071253233513,4.786198596864132,4.8204809627461715,8.093230436938587,3.1831982407639323,4.786198596864132],[-28.12071253233513,-43.632156128930475,-44.43035650754235,-46.463449980535486,-41.49090802190397,-43.632156128930475],[-60.07431169868613,-27.321156569231302,-26.04283202294988,-24.95206255401747,-29.723280516881793,-27.321156569231302],[-60.07431169868613,89.5295600455621,90.7706746205518,91.93978395828509,87.14513576108459,89.5295600455621],[-60.07431169868613,4.9925520489095785,5.416787728697108,8.093230436938587,3.097483850898625,4.9925520489095785],[-6.893860059548873,-4.536980669440933,-2.612335391035556,-3.0749012846013666,-7.155175434226004,-4.536980669440933],[-6.893860059548873,-21.872946535296638,-22.331247730424447,-24.95206255401747,-19.95404111071952,-21.872946535296638],[-6.893860059548873,7.882199263030895,6.99487202605278,11.381275991223156,7.109710423806573,7.882199263030895],[-22.327592199191397,-17.516624658132745,-20.025841379264442,-15.454910601544976,-15.985399104809726,-17.516624658132745],[-22.327592199191397,-24.27201615765467,-26.563079228078877,-24.95206255401747,-21.658367437092505,-24.27201615765467],[-22.327592199191397,-14.355703648504674,-12.859879717167926,-12.247827442728601,-16.851416146103087,-14.355703648504674],[2.8955675636407228,0.39518875435774037,0.892085497522586,-3.0749012846013666,1.5443580108687365,0.39518875435774037],[2.8955675636407228,-9.132993871367258,-7.254086976258577,-12.247827442728601,-9.534353619599962,-9.132993871367258],[2.8955675636407228,6.5980056585731495,4.004009607257968,7.105871768422399,8.951091207156463,6.5980056585731495],[-1.366956029866812,-12.253017225340304,-10.48397816112173,-15.454910601544976,-12.50321160196145,-12.253017225340304],[-1.366956029866812,8.806341148671686,9.888900917508739,11.381275991223156,6.502339674253985,8.806341148671686],[-1.366956029866812,4.479040435603206,2.2039006718752114,7.105871768422399,5.508120963031425,4.479040435603206],[30.589836410130008,14.878446485707844,15.607397220504613,11.381275991223156,15.808407589339208,14.878446485707844],[30.589836410130008,11.1460791566056,10.64746708767682,8.093230436938587,13.09283534375016,11.1460791566056],[30.589836410130008,39.69445282549878,39.79591557289109,42.97117228654644,38.03865101636713,39.69445282549878],[53.13256746342284,14.796671254361648,15.060373163163442,11.381275991223156,16.153090424548502,14.796671254361648],[53.13256746342284,90.70767081748116,92.75540887867498,91.93978395828509,88.07546966568708,90.70767081748116],[53.13256746342284,11.260185206915157,10.94696382483906,8.093230436938587,13.075677858855293,11.260185206915157],[-0.7102861981929732,-8.873966158998176,-8.738871318119418,-12.247827442728601,-7.408641908608282,-8.873966158998176],[-0.7102861981929732,7.172788410566248,4.5424778836464155,8.093230436938587,9.366479625804267,7.172788410566248],[-0.7102861981929732,-3.6951246159044793,-1.0647651526062112,-4.616722186471445,-5.888316625545209,-3.6951246159044793],[-8.348856929658716,-11.773481759105678,-14.137910871733027,-12.247827442728601,-9.184042836030038,-11.773481759105678],[-8.348856929658716,89.02623143455028,89.72047207060157,91.93978395828509,86.9499229864983,89.02623143455028],[-8.348856929658716,7.132772756767587,4.500944878026188,8.093230436938587,9.30899956645683,7.132772756767587],[19.099547652106743,9.202718087796331,11.701733803137753,7.105871768422399,7.698358820591968,9.202718087796331],[19.099547652106743,9.583702786405437,12.199197080400895,8.093230436938587,7.675226417123624,9.583702786405437],[19.099547652106743,26.84149346676985,24.269391474285516,28.635540355974683,28.562574433001473,26.84149346676985],[35.55439918754469,9.01091291892656,11.55997966385445,7.105871768422399,7.3655182489656,9.01091291892656],[35.55439918754469,90.86959977571594,92.99604040314107,91.93978395828509,88.23550840247722,90.86959977571594],[35.55439918754469,9.747486872790354,12.342974705785014,8.093230436938587,7.936709304725114,9.747486872790354],[103.22854699287531,95.063393539437,96.93206552271845,91.93978395828509,94.67643167608611,95.063393539437],[103.22854699287531,102.21378943969253,100.4371427347388,100.5052233520395,104.80090864348911,102.21378943969253],[103.22854699287531,113.22968083149877,111.86040166885437,116.64065698258389,112.98093515762032,113.22968083149877],[127.29180027011469,95.27173441749517,96.82735869491358,91.93978395828509,95.29664848401988,95.27173441749517],[127.29180027011469,-149.63059226199977,-150.02184310758858,-152.75159829378953,-147.75886631172074,-149.63059226199977],[127.29180027011469,104.00368902688838,104.907469239197,100.5052233520395,104.75943503255915,104.00368902688838],[78.86621144452673,88.68462386935649,86.99395835392446,91.93978395828509,88.83117719008179,88.68462386935649],[78.86621144452673,77.321722405516,76.02270249799562,74.97593135649333,79.73348775905896,77.321722405516],[78.86621144452673,74.09912070742367,76.30427988230272,71.35879514696282,73.19385769733412,74.09912070742367],[65.65740858378635,73.06441114126778,70.51681768039654,74.97593135649333,74.70525912906777,73.06441114126778]],\"ys\":[[-28.796731204667896,-40.42409309172668,-39.09678315919117,-43.849029027436394,-40.12675624808493,-40.42409309172668],[-28.796731204667896,-20.701593406173654,-23.295638679889798,-19.0375487723802,-18.89690151028861,-20.701593406173654],[-28.796731204667896,-18.98006661129453,-20.280120792812767,-15.546768357604067,-19.30862594086591,-18.98006661129453],[-70.65735329055241,-57.68873300132351,-57.12004837184706,-54.68350493022234,-59.682972499282535,-57.68873300132351],[-70.65735329055241,-79.47827655245274,-80.02260403904009,-82.50034156646389,-77.50040745382532,-79.47827655245274],[-2.185630887961543,-12.752692857349455,-10.584370548746573,-15.546768357604067,-13.59562227128382,-12.752692857349455],[-2.185630887961543,-8.349629299263686,-10.195928231467704,-9.945815949602656,-5.746165986665787,-8.349629299263686],[-2.185630887961543,0.06748398023030877,-2.5632688115600155,0.9986445668881058,2.256533022340589,0.06748398023030877],[-57.17942645291274,-45.90664296738326,-48.41701884026136,-43.849029027436394,-44.37231333796849,-45.90664296738326],[-57.17942645291274,-64.94436526553116,-62.43093214581222,-66.99105346309918,-66.48693485832987,-64.94436526553116],[-19.45739699351974,-19.11793565080786,-16.63766122202756,-19.0375487723802,-21.636342262302218,-19.11793565080786],[-19.45739699351974,-28.823360496801648,-26.421866125698497,-31.193953367079974,-30.100344472200593,-28.823360496801648],[-19.45739699351974,-18.825255494552213,-21.356607246834752,-18.684548236367995,-16.360649397570914,-18.825255494552213],[-14.036576974353984,-17.454463046801223,-14.822198588499921,-18.684548236367995,-19.50322638999658,-17.454463046801223],[-14.036576974353984,-11.36932561391764,-14.000458033531451,-10.106898045878879,-9.33703618496738,-11.36932561391764],[84.28368958146413,86.58350741272339,88.8338819242864,87.36788085485956,83.96105885130767,86.58350741272339],[84.28368958146413,82.52899921787235,80.29445487495173,81.70561078106734,85.15412469705579,82.52899921787235],[104.20426285969073,100.41662335427186,98.97565705314219,98.23932782479385,102.89040785380053,100.41662335427186],[104.20426285969073,106.20745505555736,107.77224594264442,108.2243734030081,103.68592221693957,106.20745505555736],[-31.298583132130158,-42.702931122048824,-40.06893499696926,-43.849029027436394,-44.793266197075624,-42.702931122048824],[-31.298583132130158,-20.396306015619334,-22.98290549606914,-18.684548236367995,-18.62169303940198,-20.396306015619334],[-31.298583132130158,-2.3781566526223914,-2.521604899455029,0.9986445668881058,-3.836522079986941,-2.3781566526223914],[-31.298583132130158,-51.51672546592825,-51.83025451661072,-54.68350493022234,-49.70100830308665,-51.51672546592825],[93.07420257277103,88.94682454750219,87.09016736685638,87.36788085485956,91.55246676850197,88.94682454750219],[93.07420257277103,96.95327463948371,98.97336398960503,98.23932782479385,94.3231352911356,96.95327463948371],[93.93152904933689,95.64177814204952,93.35012848570796,98.23932782479385,96.70125855574032,95.64177814204952],[82.49902452920922,84.31324471873435,82.3683443733897,87.36788085485956,84.80915307003691,84.31324471873435],[-38.65437247711602,-13.408773069531604,-13.86735278267414,-9.945815949602656,-14.592875796744496,-13.408773069531604],[-38.65437247711602,-33.506907570889325,-32.17918398405042,-31.193953367079974,-35.93180017379212,-33.506907570889325],[-38.65437247711602,-51.88114244244029,-52.71422786544399,-54.68350493022234,-49.71873312348123,-51.88114244244029],[15.310777071238443,4.375130597945404,4.517678699938721,0.9986445668881058,5.834246657891529,4.375130597945404],[15.310777071238443,23.00317672468971,23.0197902426234,26.317821856724468,21.414233788332602,23.00317672468971],[-10.73140389528782,-15.857560742146887,-14.058991471905529,-19.0375487723802,-16.147676307390626,-15.857560742146887],[-10.73140389528782,-10.40240670894496,-12.989336258464395,-9.945815949602656,-8.0320647742371,-10.40240670894496],[-24.974880478238877,-18.37507794972237,-17.57324111224374,-15.546768357604067,-20.518546907369124,-18.37507794972237],[-24.974880478238877,-29.78048995849217,-31.732312608430764,-31.193953367079974,-27.158179213852662,-29.78048995849217],[-43.849029027436394,-32.22166714037761,-33.54897707291312,-28.796731204667896,-32.51900398401936,-32.22166714037761],[-43.849029027436394,-32.444681037517725,-35.078677162597295,-31.298583132130158,-30.35434596249093,-32.444681037517725],[-43.849029027436394,-55.121812512965874,-52.611436640087774,-57.17942645291274,-56.656142142380645,-55.121812512965874],[-66.99105346309918,-31.373045150420236,-33.67630310860014,-28.796731204667896,-30.29188308686609,-31.373045150420236],[-66.99105346309918,90.53632537114399,88.21280530897693,93.07420257277103,91.6559823271526,90.53632537114399],[-66.99105346309918,-32.922095846589094,-35.52192948656298,-31.298583132130158,-31.092388932235828,-32.922095846589094],[-19.0375487723802,-13.911391925521134,-15.709961195762492,-10.73140389528782,-13.621276360277397,-13.911391925521134],[-19.0375487723802,-27.132686570874448,-24.5386412971583,-28.796731204667896,-28.937378466759487,-27.132686570874448],[-19.0375487723802,-19.377010115092084,-21.85728454387238,-19.45739699351974,-16.858603503597724,-19.377010115092084],[-15.546768357604067,-22.146570886120575,-22.948407723599203,-24.974880478238877,-20.00310192847382,-22.146570886120575],[-15.546768357604067,-25.363432950977433,-24.0633787694592,-28.796731204667896,-25.034873621406053,-25.363432950977433],[-15.546768357604067,-4.979706388216156,-7.148028696819036,-2.185630887961543,-4.136776974281791,-4.979706388216156],[-9.945815949602656,-10.274813135945514,-7.68788358642608,-10.73140389528782,-12.645155070653376,-10.274813135945514],[-9.945815949602656,-3.781817538300513,-1.9355186060964937,-2.185630887961543,-6.385280850898412,-3.781817538300513],[-9.945815949602656,-35.191415357187076,-34.732835644044535,-38.65437247711602,-34.00731262997418,-35.191415357187076],[-31.193953367079974,-26.388343886826682,-24.436521236888087,-24.974880478238877,-29.01065463146619,-26.388343886826682],[-31.193953367079974,-21.827989863798066,-24.229484234901218,-19.45739699351974,-20.55100588839912,-21.827989863798066],[-31.193953367079974,-36.34141827330667,-37.66914186014557,-38.65437247711602,-33.91652567040387,-36.34141827330667],[-18.684548236367995,-19.316689735335522,-16.785337983052983,-19.45739699351974,-21.78129583231682,-19.316689735335522],[-18.684548236367995,-29.58682535287882,-27.000225872429013,-31.298583132130158,-31.361438329096174,-29.58682535287882],[-18.684548236367995,-15.266662163920756,-17.898926622222056,-14.036576974353984,-13.217898820725399,-15.266662163920756],[-10.106898045878879,-18.6924949105502,-16.071508040907595,-19.45739699351974,-20.950644131105438,-18.6924949105502],[-10.106898045878879,89.79824512367951,88.14117551129661,93.07420257277103,89.90133714101651,89.79824512367951],[-10.106898045878879,-29.808483308318795,-27.192952151296385,-31.298583132130158,-31.71717325126291,-29.808483308318795],[0.9986445668881058,-1.2544703013037468,1.3762824904865778,-2.185630887961543,-3.443519343414028,-1.2544703013037468],[0.9986445668881058,-27.92178191261966,-27.778333665787024,-31.298583132130158,-26.46341648525511,-27.92178191261966],[0.9986445668881058,11.934291040181144,11.791742938187827,15.310777071238443,10.47517498023502,11.934291040181144],[26.317821856724468,1.2820767370305495,2.4433630233979082,-2.185630887961543,1.765726332508017,1.2820767370305495],[26.317821856724468,91.13481821389873,88.59372773798101,93.07420257277103,92.75594562903073,91.13481821389873],[26.317821856724468,-27.932944850228708,-27.82072682928649,-31.298583132130158,-26.448644429042204,-27.932944850228708],[-54.68350493022234,-41.45673496489807,-40.62364954189437,-38.65437247711602,-43.61914428385713,-41.45673496489807],[-54.68350493022234,-34.46536259642425,-34.15183354574177,-31.298583132130158,-36.28107975926585,-34.46536259642425],[-54.68350493022234,-67.65212521945124,-68.22080984892769,-70.65735329055241,-65.6578857214922,-67.65212521945124],[-82.50034156646389,-41.59049546753822,-40.92613893867184,-38.65437247711602,-43.64762629653493,-41.59049546753822],[-82.50034156646389,89.74183017230634,88.18704365140371,93.07420257277103,89.71587819793106,89.74183017230634],[-82.50034156646389,-34.38296891287209,-33.93290916537034,-31.298583132130158,-36.29613264515858,-34.38296891287209],[87.36788085485956,91.4952588801284,93.35191606077422,93.07420257277103,88.88961665912862,91.4952588801284],[87.36788085485956,85.55366066533443,87.49856101067908,82.49902452920922,85.05775231403187,85.55366066533443],[87.36788085485956,85.0680630236003,82.8176885120373,84.28368958146413,87.69051158501603,85.0680630236003],[81.70561078106734,92.00270542514544,94.12853325802632,93.07420257277103,89.36860403058336,92.00270542514544],[81.70561078106734,-58.847870859566676,-56.242869200570915,-60.43195461667418,-60.701449245984875,-58.847870859566676],[81.70561078106734,82.39540058456274,84.86972719909527,82.49902452920922,79.87191909216828,82.39540058456274],[98.23932782479385,94.36025575808117,92.34016640795984,93.07420257277103,96.99039510642928,94.36025575808117],[98.23932782479385,96.52907873208122,98.82072838842278,93.93152904933689,95.46959831839041,96.52907873208122],[98.23932782479385,102.02696733021271,103.46793363134239,104.20426285969073,99.55318283068405,102.02696733021271],[108.2243734030081,96.86343806340675,96.1934541638459,93.93152904933689,98.92419732845383,96.86343806340675]]},\"selected\":{\"id\":\"2267\"},\"selection_policy\":{\"id\":\"2266\"}},\"id\":\"2057\",\"type\":\"ColumnDataSource\"},{\"attributes\":{\"data\":{\"end\":[],\"start\":[]},\"selected\":{\"id\":\"2275\"},\"selection_policy\":{\"id\":\"2274\"}},\"id\":\"2043\",\"type\":\"ColumnDataSource\"},{\"attributes\":{\"edge_renderer\":{\"id\":\"2044\"},\"inspection_policy\":{\"id\":\"2255\"},\"layout_provider\":{\"id\":\"2050\"},\"node_renderer\":{\"id\":\"2040\"},\"selection_policy\":{\"id\":\"2264\"}},\"id\":\"2037\",\"type\":\"GraphRenderer\"},{\"attributes\":{\"data\":{\"color\":[\"purple\",\"grey\",\"green\",\"cyan\",\"cyan\",\"cyan\",\"cyan\",\"cyan\",\"cyan\",\"cyan\",\"green\",\"orange\",\"green\",\"green\",\"cyan\",\"cyan\",\"green\",\"green\",\"blue\",\"blue\",\"blue\",\"blue\",\"blue\",\"blue\",\"blue\",\"blue\",\"blue\",\"blue\",\"blue\",\"blue\",\"blue\",\"blue\",\"blue\",\"blue\"],\"index\":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33],\"k\":[null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,100.0,0.01,100.0,100.0,100.0,100.0,100.0,0.05,100.0,0.05,100.0,0.05,100.0,1.5,100.0,0.000555556],\"k_r\":[null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,100,0,50,50,50,50,10.0,0,10.0,0,10.0,0,10.0,0,10.0,0],\"species\":[\"nothing\",\"dna_mydna\",\"protein_GFP\",\"complex_dna_mydna_protein_hrpR_protein_hrpS_protein_RNAP\",\"complex_dna_mydna_protein_hrpS\",\"complex_dna_mydna_protein_RNAP\",\"complex_dna_mydna_protein_hrpR\",\"complex_dna_mydna_protein_hrpR_protein_RNAP\",\"complex_protein_Ribo_rna_mydna\",\"complex_protein_RNAase_rna_mydna\",\"protein_RNAP\",\"rna_mydna\",\"protein_RNAase\",\"protein_Ribo\",\"complex_dna_mydna_protein_hrpR_protein_hrpS\",\"complex_dna_mydna_protein_hrpS_protein_RNAP\",\"protein_hrpR\",\"protein_hrpS\",\"dna_mydna + protein_RNAP <--> complex_dna_mydna_protein_RNAP massaction: k_f(dna_mydna,protein_RNAP)=100.0*dna_mydna*protein_RNAP k_r(complex_dna_mydna_protein_RNAP)=100*complex_dna_mydna_protein_RNAP\",\"complex_dna_mydna_protein_RNAP --> dna_mydna + rna_mydna + protein_RNAP massaction: k_f(complex_dna_mydna_protein_RNAP)=0.01*complex_dna_mydna_protein_RNAP\",\"protein_hrpR + dna_mydna <--> complex_dna_mydna_protein_hrpR massaction: k_f(protein_hrpR,dna_mydna)=100.0*protein_hrpR*dna_mydna k_r(complex_dna_mydna_protein_hrpR)=50*complex_dna_mydna_protein_hrpR\",\"protein_hrpS + dna_mydna <--> complex_dna_mydna_protein_hrpS massaction: k_f(protein_hrpS,dna_mydna)=100.0*protein_hrpS*dna_mydna k_r(complex_dna_mydna_protein_hrpS)=50*complex_dna_mydna_protein_hrpS\",\"protein_hrpR + complex_dna_mydna_protein_hrpS <--> complex_dna_mydna_protein_hrpR_protein_hrpS massaction: k_f(protein_hrpR,complex_dna_mydna_protein_hrpS)=100.0*protein_hrpR*complex_dna_mydna_protein_hrpS k_r(complex_dna_mydna_protein_hrpR_protein_hrpS)=50*complex_dna_mydna_protein_hrpR_protein_hrpS\",\"protein_hrpS + complex_dna_mydna_protein_hrpR <--> complex_dna_mydna_protein_hrpR_protein_hrpS massaction: k_f(protein_hrpS,complex_dna_mydna_protein_hrpR)=100.0*protein_hrpS*complex_dna_mydna_protein_hrpR k_r(complex_dna_mydna_protein_hrpR_protein_hrpS)=50*complex_dna_mydna_protein_hrpR_protein_hrpS\",\"complex_dna_mydna_protein_hrpR + protein_RNAP <--> complex_dna_mydna_protein_hrpR_protein_RNAP massaction: k_f(complex_dna_mydna_protein_hrpR,protein_RNAP)=100.0*complex_dna_mydna_protein_hrpR*protein_RNAP k_r(complex_dna_mydna_protein_hrpR_protein_RNAP)=10.0*complex_dna_mydna_protein_hrpR_protein_RNAP\",\"complex_dna_mydna_protein_hrpR_protein_RNAP --> complex_dna_mydna_protein_hrpR + rna_mydna + protein_RNAP massaction: k_f(complex_dna_mydna_protein_hrpR_protein_RNAP)=0.05*complex_dna_mydna_protein_hrpR_protein_RNAP\",\"complex_dna_mydna_protein_hrpS + protein_RNAP <--> complex_dna_mydna_protein_hrpS_protein_RNAP massaction: k_f(complex_dna_mydna_protein_hrpS,protein_RNAP)=100.0*complex_dna_mydna_protein_hrpS*protein_RNAP k_r(complex_dna_mydna_protein_hrpS_protein_RNAP)=10.0*complex_dna_mydna_protein_hrpS_protein_RNAP\",\"complex_dna_mydna_protein_hrpS_protein_RNAP --> complex_dna_mydna_protein_hrpS + rna_mydna + protein_RNAP massaction: k_f(complex_dna_mydna_protein_hrpS_protein_RNAP)=0.05*complex_dna_mydna_protein_hrpS_protein_RNAP\",\"complex_dna_mydna_protein_hrpR_protein_hrpS + protein_RNAP <--> complex_dna_mydna_protein_hrpR_protein_hrpS_protein_RNAP massaction: k_f(complex_dna_mydna_protein_hrpR_protein_hrpS,protein_RNAP)=100.0*complex_dna_mydna_protein_hrpR_protein_hrpS*protein_RNAP k_r(complex_dna_mydna_protein_hrpR_protein_hrpS_protein_RNAP)=10.0*complex_dna_mydna_protein_hrpR_protein_hrpS_protein_RNAP\",\"complex_dna_mydna_protein_hrpR_protein_hrpS_protein_RNAP --> complex_dna_mydna_protein_hrpR_protein_hrpS + rna_mydna + protein_RNAP massaction: k_f(complex_dna_mydna_protein_hrpR_protein_hrpS_protein_RNAP)=0.05*complex_dna_mydna_protein_hrpR_protein_hrpS_protein_RNAP\",\"rna_mydna + protein_Ribo <--> complex_protein_Ribo_rna_mydna massaction: k_f(rna_mydna,protein_Ribo)=100.0*rna_mydna*protein_Ribo k_r(complex_protein_Ribo_rna_mydna)=10.0*complex_protein_Ribo_rna_mydna\",\"complex_protein_Ribo_rna_mydna --> rna_mydna + protein_GFP + protein_Ribo massaction: k_f(complex_protein_Ribo_rna_mydna)=1.5*complex_protein_Ribo_rna_mydna\",\"rna_mydna + protein_RNAase <--> complex_protein_RNAase_rna_mydna massaction: k_f(rna_mydna,protein_RNAase)=100.0*rna_mydna*protein_RNAase k_r(complex_protein_RNAase_rna_mydna)=10.0*complex_protein_RNAase_rna_mydna\",\"complex_protein_RNAase_rna_mydna --> protein_RNAase massaction: k_f(complex_protein_RNAase_rna_mydna)=0.000555556*complex_protein_RNAase_rna_mydna\"],\"type\":[\"nothing\",\"dna\",\"protein\",\"complex\",\"complex\",\"complex\",\"complex\",\"complex\",\"complex\",\"complex\",\"protein\",\"rna\",\"protein\",\"protein\",\"complex\",\"complex\",\"protein\",\"protein\",\"massaction\",\"massaction\",\"massaction\",\"massaction\",\"massaction\",\"massaction\",\"massaction\",\"massaction\",\"massaction\",\"massaction\",\"massaction\",\"massaction\",\"massaction\",\"massaction\",\"massaction\",\"massaction\"]},\"selected\":{\"id\":\"2269\"},\"selection_policy\":{\"id\":\"2268\"}},\"id\":\"2053\",\"type\":\"ColumnDataSource\"},{\"attributes\":{},\"id\":\"2042\",\"type\":\"MultiLine\"},{\"attributes\":{},\"id\":\"2277\",\"type\":\"Selection\"},{\"attributes\":{\"fill_color\":{\"value\":\"#abdda4\"},\"size\":{\"units\":\"screen\",\"value\":8}},\"id\":\"2105\",\"type\":\"Square\"},{\"attributes\":{\"active_drag\":\"auto\",\"active_inspect\":\"auto\",\"active_multi\":null,\"active_scroll\":\"auto\",\"active_tap\":\"auto\",\"tools\":[{\"id\":\"2125\"},{\"id\":\"2126\"},{\"id\":\"2127\"},{\"id\":\"2128\"},{\"id\":\"2129\"},{\"id\":\"2130\"},{\"id\":\"2131\"}]},\"id\":\"2132\",\"type\":\"Toolbar\"}],\"root_ids\":[\"2020\"]},\"title\":\"Bokeh Application\",\"version\":\"2.0.2\"}};\n", - " var render_items = [{\"docid\":\"8eb7364d-9ee0-4936-8dcc-c86c47ac2f1a\",\"root_ids\":[\"2020\"],\"roots\":{\"2020\":\"07ca8f9d-8094-459c-8209-dc5106f81337\"}}];\n", + " var docs_json = {\"9928c12b-e691-4cdb-9e7f-98f5884c7443\":{\"roots\":{\"references\":[{\"attributes\":{\"plot_height\":500,\"plot_width\":500,\"renderers\":[{\"id\":\"1035\"},{\"id\":\"1007\"},{\"id\":\"1021\"}],\"title\":{\"id\":\"1130\"},\"toolbar\":{\"id\":\"1116\"},\"x_range\":{\"id\":\"1077\"},\"x_scale\":{\"id\":\"1128\"},\"y_range\":{\"id\":\"1078\"},\"y_scale\":{\"id\":\"1127\"}},\"id\":\"1004\",\"type\":\"Plot\"},{\"attributes\":{\"edge_renderer\":{\"id\":\"1028\"},\"inspection_policy\":{\"id\":\"1154\"},\"layout_provider\":{\"id\":\"1034\"},\"node_renderer\":{\"id\":\"1024\"},\"selection_policy\":{\"id\":\"1153\"}},\"id\":\"1021\",\"type\":\"GraphRenderer\"},{\"attributes\":{\"source\":{\"id\":\"1027\"}},\"id\":\"1029\",\"type\":\"CDSView\"},{\"attributes\":{},\"id\":\"1127\",\"type\":\"LinearScale\"},{\"attributes\":{\"end\":179.48830883389695,\"start\":-100.85017549486308},\"id\":\"1077\",\"type\":\"Range1d\"},{\"attributes\":{\"data_source\":{\"id\":\"1023\"},\"glyph\":{\"id\":\"1094\"},\"hover_glyph\":{\"id\":\"1104\"},\"muted_glyph\":null,\"selection_glyph\":{\"id\":\"1099\"},\"view\":{\"id\":\"1025\"}},\"id\":\"1024\",\"type\":\"GlyphRenderer\"},{\"attributes\":{},\"id\":\"1128\",\"type\":\"LinearScale\"},{\"attributes\":{\"graph_layout\":{\"0\":[-128.06534390538394,188.8110737063345],\"1\":[-4.942642958329285,-141.43195492316931],\"10\":[-63.05482954977653,53.96466500077084],\"11\":[-18.111741884048353,-144.97809028556364],\"12\":[-0.03034153180732158,0.01367303858752807],\"13\":[-1.289279313130396,15.122781689567564],\"14\":[-2.279250371726325,34.84819716524268],\"15\":[26.43926448068255,-13.496628475304133],\"16\":[-17.653612018224468,15.029871711418627],\"17\":[-26.542599340112336,0.6402053798270149],\"18\":[15.827931173971795,29.42291883724415],\"19\":[42.58663923851341,34.851882467682195],\"2\":[-42.912667181668425,26.8250862178223],\"20\":[-22.425925393415437,19.18005005376656],\"21\":[-10.831238753170846,-2.6236818957972776],\"22\":[-10.842673172635013,17.64794512343082],\"23\":[-34.61463764843533,17.361354830535326],\"24\":[-43.31085414311069,42.33438781184292],\"25\":[-77.741780780435,62.808082530055444],\"26\":[14.022429470966996,-0.553959854560857],\"27\":[36.38357800981411,-22.635106090529064],\"28\":[-8.968942098927226,57.00149749918813],\"29\":[-2.4043658578715292,89.4222184982506],\"3\":[156.37991411946888,-177.56681419580656],\"30\":[-6.805066829718983,-146.37918054221225],\"31\":[12.5197498143886,-152.90399699369698],\"32\":[-31.65772711420718,-144.4222919267058],\"33\":[-46.06217951791717,-137.07274852058956],\"4\":[3.0894514477121673,-149.86496953886694],\"5\":[30.79277003241157,32.55511799827421],\"6\":[-5.172597935166938,76.14428069155251],\"7\":[-34.21960043849704,-149.60570618132508],\"8\":[-20.756455984906772,37.19976305162342],\"9\":[-40.00747948102076,-140.3922770855331]}},\"id\":\"1020\",\"type\":\"StaticLayoutProvider\"},{\"attributes\":{\"data_source\":{\"id\":\"1009\"},\"glyph\":{\"id\":\"1079\"},\"hover_glyph\":{\"id\":\"1089\"},\"muted_glyph\":null,\"selection_glyph\":{\"id\":\"1084\"},\"view\":{\"id\":\"1011\"}},\"id\":\"1010\",\"type\":\"GlyphRenderer\"},{\"attributes\":{},\"id\":\"1154\",\"type\":\"NodesOnly\"},{\"attributes\":{\"edge_renderer\":{\"id\":\"1042\"},\"inspection_policy\":{\"id\":\"1125\"},\"layout_provider\":{\"id\":\"1048\"},\"node_renderer\":{\"id\":\"1038\"},\"selection_policy\":{\"id\":\"1123\"}},\"id\":\"1035\",\"type\":\"GraphRenderer\"},{\"attributes\":{},\"id\":\"1123\",\"type\":\"NodesAndLinkedEdges\"},{\"attributes\":{\"source\":{\"id\":\"1037\"}},\"id\":\"1039\",\"type\":\"CDSView\"},{\"attributes\":{},\"id\":\"1166\",\"type\":\"Selection\"},{\"attributes\":{\"text\":\"\"},\"id\":\"1130\",\"type\":\"Title\"},{\"attributes\":{\"source\":{\"id\":\"1009\"}},\"id\":\"1011\",\"type\":\"CDSView\"},{\"attributes\":{\"data\":{\"color\":[\"purple\",\"green\",\"cyan\",\"green\",\"cyan\",\"cyan\",\"cyan\",\"green\",\"cyan\",\"cyan\",\"cyan\",\"orange\",\"cyan\",\"grey\",\"green\",\"cyan\",\"green\",\"green\"],\"index\":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17],\"species\":[\"nothing\",\"protein_Ribo\",\"complex_dna_mydna_protein_hrpR\",\"protein_GFP\",\"complex_protein_Ribo_rna_mydna\",\"complex_dna_mydna_protein_RNAP\",\"complex_dna_mydna_protein_hrpR_protein_hrpS_protein_RNAP\",\"protein_RNAase\",\"complex_dna_mydna_protein_hrpR_protein_hrpS\",\"complex_protein_RNAase_rna_mydna\",\"complex_dna_mydna_protein_hrpR_protein_RNAP\",\"rna_mydna\",\"complex_dna_mydna_protein_hrpS\",\"dna_mydna\",\"protein_RNAP\",\"complex_dna_mydna_protein_hrpS_protein_RNAP\",\"protein_hrpR\",\"protein_hrpS\"],\"type\":[\"nothing\",\"protein\",\"complex\",\"protein\",\"complex\",\"complex\",\"complex\",\"protein\",\"complex\",\"complex\",\"complex\",\"rna\",\"complex\",\"dna\",\"protein\",\"complex\",\"protein\",\"protein\"]},\"selected\":{\"id\":\"1170\"},\"selection_policy\":{\"id\":\"1171\"}},\"id\":\"1023\",\"type\":\"ColumnDataSource\"},{\"attributes\":{},\"id\":\"1160\",\"type\":\"Selection\"},{\"attributes\":{},\"id\":\"1163\",\"type\":\"UnionRenderers\"},{\"attributes\":{\"graph_layout\":{\"0\":[-128.06534390538394,188.8110737063345],\"1\":[-4.942642958329285,-141.43195492316931],\"10\":[-63.05482954977653,53.96466500077084],\"11\":[-18.111741884048353,-144.97809028556364],\"12\":[-0.03034153180732158,0.01367303858752807],\"13\":[-1.289279313130396,15.122781689567564],\"14\":[-2.279250371726325,34.84819716524268],\"15\":[26.43926448068255,-13.496628475304133],\"16\":[-17.653612018224468,15.029871711418627],\"17\":[-26.542599340112336,0.6402053798270149],\"18\":[15.827931173971795,29.42291883724415],\"19\":[42.58663923851341,34.851882467682195],\"2\":[-42.912667181668425,26.8250862178223],\"20\":[-22.425925393415437,19.18005005376656],\"21\":[-10.831238753170846,-2.6236818957972776],\"22\":[-10.842673172635013,17.64794512343082],\"23\":[-34.61463764843533,17.361354830535326],\"24\":[-43.31085414311069,42.33438781184292],\"25\":[-77.741780780435,62.808082530055444],\"26\":[14.022429470966996,-0.553959854560857],\"27\":[36.38357800981411,-22.635106090529064],\"28\":[-8.968942098927226,57.00149749918813],\"29\":[-2.4043658578715292,89.4222184982506],\"3\":[156.37991411946888,-177.56681419580656],\"30\":[-6.805066829718983,-146.37918054221225],\"31\":[12.5197498143886,-152.90399699369698],\"32\":[-31.65772711420718,-144.4222919267058],\"33\":[-46.06217951791717,-137.07274852058956],\"4\":[3.0894514477121673,-149.86496953886694],\"5\":[30.79277003241157,32.55511799827421],\"6\":[-5.172597935166938,76.14428069155251],\"7\":[-34.21960043849704,-149.60570618132508],\"8\":[-20.756455984906772,37.19976305162342],\"9\":[-40.00747948102076,-140.3922770855331]}},\"id\":\"1048\",\"type\":\"StaticLayoutProvider\"},{\"attributes\":{\"data\":{\"color\":[\"blue\",\"blue\",\"blue\",\"blue\",\"blue\",\"blue\",\"blue\",\"blue\",\"blue\",\"blue\",\"blue\",\"blue\",\"blue\",\"blue\",\"blue\",\"blue\"],\"index\":[18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33],\"k\":[100,0.01,100,100,100,100,100,0.05,100,0.05,100,0.05,100,1.5,100,0.000555556],\"k_r\":[100,0,50,50,50,50,10,0,10,0,10,0,10.0,0,10,0],\"species\":[\"dna_mydna + protein_RNAP <--> complex_dna_mydna_protein_RNAP massaction: k_f(dna_mydna,protein_RNAP)=100*dna_mydna*protein_RNAP k_r(complex_dna_mydna_protein_RNAP)=100*complex_dna_mydna_protein_RNAP\",\"complex_dna_mydna_protein_RNAP --> dna_mydna + rna_mydna + protein_RNAP massaction: k_f(complex_dna_mydna_protein_RNAP)=0.01*complex_dna_mydna_protein_RNAP\",\"protein_hrpR + dna_mydna <--> complex_dna_mydna_protein_hrpR massaction: k_f(protein_hrpR,dna_mydna)=100*protein_hrpR*dna_mydna k_r(complex_dna_mydna_protein_hrpR)=50*complex_dna_mydna_protein_hrpR\",\"protein_hrpS + dna_mydna <--> complex_dna_mydna_protein_hrpS massaction: k_f(protein_hrpS,dna_mydna)=100*protein_hrpS*dna_mydna k_r(complex_dna_mydna_protein_hrpS)=50*complex_dna_mydna_protein_hrpS\",\"protein_hrpR + complex_dna_mydna_protein_hrpS <--> complex_dna_mydna_protein_hrpR_protein_hrpS massaction: k_f(protein_hrpR,complex_dna_mydna_protein_hrpS)=100*protein_hrpR*complex_dna_mydna_protein_hrpS k_r(complex_dna_mydna_protein_hrpR_protein_hrpS)=50*complex_dna_mydna_protein_hrpR_protein_hrpS\",\"protein_hrpS + complex_dna_mydna_protein_hrpR <--> complex_dna_mydna_protein_hrpR_protein_hrpS massaction: k_f(protein_hrpS,complex_dna_mydna_protein_hrpR)=100*protein_hrpS*complex_dna_mydna_protein_hrpR k_r(complex_dna_mydna_protein_hrpR_protein_hrpS)=50*complex_dna_mydna_protein_hrpR_protein_hrpS\",\"complex_dna_mydna_protein_hrpR + protein_RNAP <--> complex_dna_mydna_protein_hrpR_protein_RNAP massaction: k_f(complex_dna_mydna_protein_hrpR,protein_RNAP)=100*complex_dna_mydna_protein_hrpR*protein_RNAP k_r(complex_dna_mydna_protein_hrpR_protein_RNAP)=10*complex_dna_mydna_protein_hrpR_protein_RNAP\",\"complex_dna_mydna_protein_hrpR_protein_RNAP --> complex_dna_mydna_protein_hrpR + rna_mydna + protein_RNAP massaction: k_f(complex_dna_mydna_protein_hrpR_protein_RNAP)=0.05*complex_dna_mydna_protein_hrpR_protein_RNAP\",\"complex_dna_mydna_protein_hrpS + protein_RNAP <--> complex_dna_mydna_protein_hrpS_protein_RNAP massaction: k_f(complex_dna_mydna_protein_hrpS,protein_RNAP)=100*complex_dna_mydna_protein_hrpS*protein_RNAP k_r(complex_dna_mydna_protein_hrpS_protein_RNAP)=10*complex_dna_mydna_protein_hrpS_protein_RNAP\",\"complex_dna_mydna_protein_hrpS_protein_RNAP --> complex_dna_mydna_protein_hrpS + rna_mydna + protein_RNAP massaction: k_f(complex_dna_mydna_protein_hrpS_protein_RNAP)=0.05*complex_dna_mydna_protein_hrpS_protein_RNAP\",\"complex_dna_mydna_protein_hrpR_protein_hrpS + protein_RNAP <--> complex_dna_mydna_protein_hrpR_protein_hrpS_protein_RNAP massaction: k_f(complex_dna_mydna_protein_hrpR_protein_hrpS,protein_RNAP)=100*complex_dna_mydna_protein_hrpR_protein_hrpS*protein_RNAP k_r(complex_dna_mydna_protein_hrpR_protein_hrpS_protein_RNAP)=10*complex_dna_mydna_protein_hrpR_protein_hrpS_protein_RNAP\",\"complex_dna_mydna_protein_hrpR_protein_hrpS_protein_RNAP --> complex_dna_mydna_protein_hrpR_protein_hrpS + rna_mydna + protein_RNAP massaction: k_f(complex_dna_mydna_protein_hrpR_protein_hrpS_protein_RNAP)=0.05*complex_dna_mydna_protein_hrpR_protein_hrpS_protein_RNAP\",\"rna_mydna + protein_Ribo <--> complex_protein_Ribo_rna_mydna massaction: k_f(rna_mydna,protein_Ribo)=100*rna_mydna*protein_Ribo k_r(complex_protein_Ribo_rna_mydna)=10.0*complex_protein_Ribo_rna_mydna\",\"complex_protein_Ribo_rna_mydna --> rna_mydna + protein_GFP + protein_Ribo massaction: k_f(complex_protein_Ribo_rna_mydna)=1.5*complex_protein_Ribo_rna_mydna\",\"rna_mydna + protein_RNAase <--> complex_protein_RNAase_rna_mydna massaction: k_f(rna_mydna,protein_RNAase)=100*rna_mydna*protein_RNAase k_r(complex_protein_RNAase_rna_mydna)=10*complex_protein_RNAase_rna_mydna\",\"complex_protein_RNAase_rna_mydna --> protein_RNAase massaction: k_f(complex_protein_RNAase_rna_mydna)=0.000555556*complex_protein_RNAase_rna_mydna\"],\"type\":[\"massaction\",\"massaction\",\"massaction\",\"massaction\",\"massaction\",\"massaction\",\"massaction\",\"massaction\",\"massaction\",\"massaction\",\"massaction\",\"massaction\",\"massaction\",\"massaction\",\"massaction\",\"massaction\"]},\"selected\":{\"id\":\"1166\"},\"selection_policy\":{\"id\":\"1167\"}},\"id\":\"1009\",\"type\":\"ColumnDataSource\"},{\"attributes\":{},\"id\":\"1164\",\"type\":\"Selection\"},{\"attributes\":{},\"id\":\"1114\",\"type\":\"PanTool\"},{\"attributes\":{},\"id\":\"1162\",\"type\":\"Selection\"},{\"attributes\":{\"line_color\":{\"value\":\"#fdae61\"},\"line_width\":{\"value\":5}},\"id\":\"1059\",\"type\":\"MultiLine\"},{\"attributes\":{\"data_source\":{\"id\":\"1027\"},\"glyph\":{\"id\":\"1026\"},\"hover_glyph\":null,\"muted_glyph\":null,\"view\":{\"id\":\"1029\"}},\"id\":\"1028\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"callback\":null,\"renderers\":[{\"id\":\"1035\"}],\"tooltips\":null},\"id\":\"1109\",\"type\":\"HoverTool\"},{\"attributes\":{\"fill_alpha\":{\"value\":0},\"fill_color\":{\"field\":\"color\"},\"line_alpha\":{\"value\":0},\"size\":{\"units\":\"screen\",\"value\":12}},\"id\":\"1049\",\"type\":\"Circle\"},{\"attributes\":{},\"id\":\"1165\",\"type\":\"UnionRenderers\"},{\"attributes\":{\"end\":96.09694431560204,\"start\":-184.241540013158},\"id\":\"1078\",\"type\":\"Range1d\"},{\"attributes\":{},\"id\":\"1143\",\"type\":\"NodesOnly\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"size\":{\"units\":\"screen\",\"value\":12}},\"id\":\"1094\",\"type\":\"Circle\"},{\"attributes\":{\"overlay\":{\"id\":\"1159\"}},\"id\":\"1113\",\"type\":\"BoxSelectTool\"},{\"attributes\":{\"data\":{\"end\":[30,20,23,24,30,31,18,19,28,29,32,22,23,28,32,33,24,25,30,32,21,22,26,18,20,21,18,24,26,28,26,27,20,22,21,23,13,14,5,13,11,14,16,13,2,17,13,12,16,12,8,17,2,8,2,14,10,2,11,14,12,14,15,12,11,14,8,14,6,8,11,14,11,1,4,11,3,1,11,7,9,7],\"start\":[1,2,2,2,4,4,5,5,6,6,7,8,8,8,9,9,10,10,11,11,12,12,12,13,13,13,14,14,14,14,15,15,16,16,17,17,18,18,18,19,19,19,20,20,20,21,21,21,22,22,22,23,23,23,24,24,24,25,25,25,26,26,26,27,27,27,28,28,28,29,29,29,30,30,30,31,31,31,32,32,32,33],\"weight\":[1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1],\"xs\":[[-4.942642958329285,-5.571948087837751,-7.619177362423808,-6.805066829718983,-2.9397787074374366,-5.571948087837751],[-42.912667181668425,-25.70504622139233,-27.35683481803103,-22.425925393415437,-25.608735794818845,-25.70504622139233],[-42.912667181668425,-36.92212162178128,-39.34915001838829,-34.61463764843533,-35.589667392033924,-36.92212162178128],[-42.912667181668425,-43.22102448416216,-40.700542302667614,-43.31085414311069,-45.69889522166027,-43.22102448416216],[3.0894514477121673,-3.503931703604464,-1.8902760771415483,-6.805066829718983,-3.55166649503836,-3.503931703604464],[3.0894514477121673,9.188459711312802,7.631526849050843,12.5197498143886,9.165167475042576,9.188459711312802],[30.79277003241157,19.25369727968878,19.55405598668026,15.827931173971795,20.578379146905025,19.25369727968878],[30.79277003241157,39.1511771961488,38.81423549396341,42.58663923851341,37.85847897613506,39.1511771961488],[-5.172597935166938,-8.288091435191152,-10.578849891458505,-8.968942098927226,-5.674365817884702,-8.288091435191152],[-5.172597935166938,-3.118699137141978,-0.8407464941400313,-2.4043658578715292,-5.735501697651178,-3.118699137141978],[-34.21960043849704,-33.20851054914762,-31.335120064619787,-31.65772711420718,-35.81752802215604,-33.20851054914762],[-20.756455984906772,-12.425506325508966,-15.030664535831551,-10.842673172635013,-10.571178153270077,-12.425506325508966],[-20.756455984906772,-32.61030664492941,-34.18439308608949,-34.61463764843533,-30.08544916327007,-32.61030664492941],[-20.756455984906772,-10.7592216442438,-9.03564299210884,-8.968942098927226,-13.332034251802206,-10.7592216442438],[-40.00747948102076,-34.809790861644174,-36.64407048358997,-31.65772711420718,-34.47071882947701,-34.809790861644174],[-40.00747948102076,-42.99316710610184,-41.063399956364414,-46.06217951791717,-43.46712275615044,-42.99316710610184],[-63.05482954977653,-46.32654372258937,-48.3106634517175,-43.31085414311069,-45.77294136523687,-46.32654372258937],[-63.05482954977653,-74.74337354691369,-72.7426256494153,-77.741780780435,-75.32180209682477,-74.74337354691369],[-18.111741884048353,-10.278500367509423,-11.409767641348935,-6.805066829718983,-10.794885109755823,-10.278500367509423],[-18.111741884048353,-28.160669525947092,-27.22875040515838,-31.65772711420718,-27.433730366312044,-28.160669525947092],[-0.03034153180732158,-7.431134348314944,-7.217725430311383,-10.831238753170846,-6.031675532817221,-7.431134348314944],[-0.03034153180732158,-9.013185785788632,-6.447994169508954,-10.842673172635013,-10.710544881726285,-9.013185785788632],[-0.03034153180732158,10.525281265105615,9.594930534594756,14.022429470966996,9.796730729981729,10.525281265105615],[-1.289279313130396,13.141921156411144,14.107683157586383,15.827931173971795,10.902028018851462,13.141921156411144],[-1.289279313130396,-18.988677711497775,-17.70215266964749,-22.425925393415437,-18.64471579821233,-18.988677711497775],[-1.289279313130396,-9.17375185850481,-10.982524100717992,-10.831238753170846,-6.578736956422074,-9.17375185850481],[-2.279250371726325,12.47518895949925,10.962453079012546,15.827931173971795,12.397523754434706,12.47518895949925],[-2.279250371726325,-39.8676926039124,-38.60233027826227,-43.31085414311069,-39.49976268716127,-39.8676926039124],[-2.279250371726325,12.558523106010098,9.94049547388013,14.022429470966996,14.482134608584126,12.558523106010098],[-2.279250371726325,-7.957162258766869,-5.323926786452475,-8.968942098927226,-10.110451569642466,-7.957162258766869],[26.43926448068255,16.445465445416417,18.824193176667038,14.022429470966996,15.216124931429185,16.445465445416417],[26.43926448068255,33.80649105173634,31.503650395096624,36.38357800981411,34.886869128940404,33.80649105173634],[-17.653612018224468,-19.78489940679811,-17.517979655657776,-22.425925393415437,-20.7990265698432,-19.78489940679811],[-17.653612018224468,-14.109626765743851,-13.987485559201106,-10.842673172635013,-15.78147451354636,-14.109626765743851],[-26.542599340112336,-14.258075242015225,-15.579344419374706,-10.831238753170846,-14.56235438398042,-14.258075242015225],[-26.542599340112336,-33.09305272024596,-30.480772721824636,-34.61463764843533,-34.983556284110264,-33.09305272024596],[15.827931173971795,1.3967307044302553,0.4309687032550147,-1.289279313130396,3.6366238419899366,1.3967307044302553],[15.827931173971795,1.0734918427462188,2.586227723232924,-2.279250371726325,1.151157047810762,1.0734918427462188],[15.827931173971795,27.367003926694586,27.0666452197031,30.79277003241157,26.04232205947834,27.367003926694586],[42.58663923851341,1.9028559171387007,1.6347031207839384,-1.289279313130396,3.6852245436076307,1.9028559171387007],[42.58663923851341,-16.99242118520085,-19.09564934269741,-18.111741884048353,-14.358233967731614,-16.99242118520085],[42.58663923851341,1.2207496164663438,2.050671281570914,-2.279250371726325,2.0510819836052545,1.2207496164663438],[-22.425925393415437,-20.294638004841794,-22.56155775598213,-17.653612018224468,-19.280510841796705,-20.294638004841794],[-22.425925393415437,-4.726526995048056,-6.013052036898341,-1.289279313130396,-5.070488908333502,-4.726526995048056],[-22.425925393415437,-39.633546353691536,-37.98175775705283,-42.912667181668425,-39.72985678026502,-39.633546353691536],[-10.831238753170846,-23.115762851267956,-21.794493673908477,-26.542599340112336,-22.81148370930276,-23.115762851267956],[-10.831238753170846,-2.946766207796431,-1.137993965583249,-1.289279313130396,-5.5417811098791665,-2.946766207796431],[-10.831238753170846,-3.430445936663223,-3.6438548546667846,-0.03034153180732158,-4.829904752160947,-3.430445936663223],[-10.842673172635013,-14.38665842511563,-14.508799631658375,-17.653612018224468,-12.714810677313121,-14.38665842511563],[-10.842673172635013,-1.859828918653703,-4.42502053493338,-0.03034153180732158,-0.16246982271604904,-1.859828918653703],[-10.842673172635013,-19.17362283203282,-16.568464621710234,-20.756455984906772,-21.02795100427171,-19.17362283203282],[-34.61463764843533,-28.0641842683017,-30.676464266723027,-26.542599340112336,-26.173680704437395,-28.0641842683017],[-34.61463764843533,-40.60518320832247,-38.17815481171546,-42.912667181668425,-41.93763743806983,-40.60518320832247],[-34.61463764843533,-22.76078698841269,-21.186700547252606,-20.756455984906772,-25.28564447007203,-22.76078698841269],[-43.31085414311069,-43.002496840616956,-45.5229790221115,-42.912667181668425,-40.52462610311884,-43.002496840616956],[-43.31085414311069,-5.722411910924609,-6.987774236574744,-2.279250371726325,-6.090341827675745,-5.722411910924609],[-43.31085414311069,-60.039139970297846,-58.055020241169714,-63.05482954977653,-60.59274232765035,-60.039139970297846],[-77.741780780435,-45.34688971576819,-47.72057077158106,-42.912667181668425,-44.12790231459846,-45.34688971576819],[-77.741780780435,-19.077195393775,-21.709186979481398,-18.111741884048353,-16.90317469031851,-19.077195393775],[-77.741780780435,-5.56121802742271,-7.208213237800813,-2.279250371726325,-5.47105140345735,-5.56121802742271],[14.022429470966996,3.466806674054059,4.397157404564918,-0.03034153180732158,4.195357209177944,3.466806674054059],[14.022429470966996,-0.8153440067694278,1.8026836253605398,-2.279250371726325,-2.7389555093434566,-0.8153440067694278],[14.022429470966996,24.016228506233126,21.637500774982506,26.43926448068255,25.24556902022036,24.016228506233126],[36.38357800981411,2.941677638275481,4.9669646990981065,-0.03034153180732158,2.3261925282188245,2.941677638275481],[36.38357800981411,-16.68762465462958,-18.633545942097026,-18.111741884048353,-14.066161544160337,-16.68762465462958],[36.38357800981411,-0.3259017745853676,2.2118267010742163,-2.279250371726325,-1.9370431371818257,-0.3259017745853676],[-8.968942098927226,-18.9661764395902,-20.68975509172516,-20.756455984906772,-16.393363832031792,-18.9661764395902],[-8.968942098927226,-3.2910302118866825,-5.924265684201076,-2.279250371726325,-1.137740901011084,-3.2910302118866825],[-8.968942098927226,-5.853448598903011,-3.5626901426356605,-5.172597935166938,-8.467174216209461,-5.853448598903011],[-2.4043658578715292,-19.59604902065719,-21.679423334959353,-20.756455984906772,-16.962226035515567,-19.59604902065719],[-2.4043658578715292,-17.87772855380111,-20.316631228796364,-18.111741884048353,-15.327819714105166,-17.87772855380111],[-2.4043658578715292,-2.287274391947266,-4.789170952332478,-2.279250371726325,0.21081590787464322,-2.287274391947266],[-6.805066829718983,-14.638308346257913,-13.507041072418403,-18.111741884048353,-14.121923604011513,-14.638308346257913],[-6.805066829718983,-6.175761700210516,-4.128532425624459,-4.942642958329285,-8.807931080610832,-6.175761700210516],[-6.805066829718983,-0.21168367840235192,-1.8253393048652677,3.0894514477121673,-0.16394888696845644,-0.21168367840235192],[12.5197498143886,-14.72333415139444,-13.293423483292354,-18.111741884048353,-14.545925499496011,-14.72333415139444],[12.5197498143886,152.9302405196078,151.68962245274597,156.37991411946888,152.53447729406548,152.9302405196078],[12.5197498143886,-2.017424354188008,0.04905006680980861,-4.942642958329285,-2.696297061156375,-2.017424354188008],[-31.65772711420718,-21.60879947230844,-22.540718593097157,-18.111741884048353,-22.33573863194349,-21.60879947230844],[-31.65772711420718,-32.6688170035566,-34.54220748808443,-34.21960043849704,-30.059799530548176,-32.6688170035566],[-31.65772711420718,-36.85541573358376,-35.021136111637965,-40.00747948102076,-37.194487765750935,-36.85541573358376],[-46.06217951791717,-36.62341537291892,-39.010656193650874,-34.21960043849704,-35.37644410964542,-36.62341537291892]],\"ys\":[[-141.43195492316931,-143.1036014837218,-141.4459033312156,-146.37918054221225,-143.20750153390307,-143.1036014837218],[26.8250862178223,20.40371937001509,18.35171905335844,19.18005005376656,23.036177379039714,20.40371937001509],[26.8250862178223,19.992992668983387,18.968959451940204,17.361354830535326,22.265365128148705,19.992992668983387],[26.8250862178223,38.835540768548064,38.069851249021276,42.33438781184292,37.941523164809084,38.835540768548064],[-149.86496953886694,-147.54215383474002,-145.46003318820456,-146.37918054221225,-150.17594051122532,-147.54215383474002],[-149.86496953886694,-151.83044855550276,-153.9553181820807,-152.90399699369698,-149.19633232054383,-151.83044855550276],[32.55511799827421,30.139945049401486,32.7569845054814,29.42291883724415,27.863032925885708,30.139945049401486],[32.55511799827421,34.18285290520235,31.570271584578425,34.851882467682195,36.47807450224215,34.18285290520235],[76.14428069155251,60.43463635068979,61.73522720202786,57.00149749918813,60.76258339669061,60.43463635068979],[76.14428069155251,85.9958898557928,84.67299809008213,89.4222184982506,85.69347420332562,85.9958898557928],[-149.60570618132508,-147.5599774969812,-149.4118735415866,-144.4222919267058,-147.19646863452886,-147.5599774969812],[37.19976305162342,20.76958559122385,20.379378509364148,17.64794512343082,22.640568727755507,20.76958559122385],[37.19976305162342,20.230615576508924,22.342809398889017,17.361354830535326,19.47947939388056,20.230615576508924],[37.19976305162342,53.994023617402775,52.0019424198987,57.00149749918813,54.5594846274938,53.994023617402775],[-140.3922770855331,-142.90094576882674,-144.7915882881992,-144.4222919267058,-140.2886400775749,-142.90094576882674],[-140.3922770855331,-138.75535448043976,-136.96228180613488,-137.07274852058956,-141.34658525158534,-138.75535448043976],[53.96466500077084,44.11079327237937,42.378055621138095,42.33438781184292,46.686183591821916,44.11079327237937],[53.96466500077084,61.00265901686882,62.71616965827157,62.808082530055444,58.43273075324113,61.00265901686882],[-144.97809028556364,-145.94876277009706,-148.32770060507394,-146.37918054221225,-143.36565269394472,-145.94876277009706],[-144.97809028556364,-144.56577789951336,-142.101911503003,-144.4222919267058,-147.09770805766027,-144.56577789951336],[0.01367303858752807,-1.7934469675513647,0.832113449057096,-2.6236818957972776,-4.025178557879905,-1.7934469675513647],[0.01367303858752807,14.664159624878687,15.26324462662143,17.64794512343082,12.649691216840885,14.664159624878687],[0.01367303858752807,-0.4126997177899751,-2.8771587630537736,-0.553959854560857,2.1187672453196256,-0.4126997177899751],[15.122781689567564,27.178960240129705,24.728161467355687,29.42291883724415,28.565318635299473,27.178960240129705],[15.122781689567564,18.520255863771172,20.81894335541434,19.18005005376656,15.9085895241034,18.520255863771172],[15.122781689567564,0.4589691052098659,2.3740288544980555,-2.6236818957972776,0.006190433546576113,0.4589691052098659],[34.84819716524268,30.427468310039664,28.270910630905448,29.42291883724415,33.060542365866226,30.427468310039664],[34.84819716524268,41.70618512561362,44.01658964698427,42.33438781184292,39.09778744812958,41.70618512561362],[34.84819716524268,2.6251875397319404,2.3335676073737392,-0.553959854560857,4.4248624144550215,2.6251875397319404],[34.84819716524268,53.65093015095514,53.57894532693062,57.00149749918813,52.133545555272974,53.65093015095514],[-13.496628475304133,-3.079607626227354,-1.947898631775193,-0.553959854560857,-5.409378595274366,-3.079607626227354],[-13.496628475304133,-20.266852976838415,-21.545929119087905,-22.635106090529064,-17.864376321833944,-20.266852976838415],[15.029871711418627,16.883317213836765,18.225027208371532,19.18005005376656,14.452132941775353,16.883317213836765],[15.029871711418627,16.392152855389142,13.760766834067123,17.64794512343082,18.427843395651173,16.392152855389142],[0.6402053798270149,-1.9117888710212778,-4.190683038924748,-2.6236818957972776,0.704797659424365,-1.9117888710212778],[0.6402053798270149,14.209406336935382,14.548676255131095,17.361354830535326,12.374983500574857,14.209406336935382],[29.42291883724415,17.36674028668201,19.81753905945603,15.122781689567564,15.980381891512241,17.36674028668201],[29.42291883724415,33.84364769244717,36.00020537158139,34.84819716524268,31.21057363662061,33.84364769244717],[29.42291883724415,31.83809178611688,29.221052330036965,32.55511799827421,34.115003909632655,31.83809178611688],[34.851882467682195,16.55814668554415,19.17868192578645,15.122781689567564,14.61848873968774,16.55814668554415],[34.851882467682195,-141.66189952308758,-140.0758534376732,-144.97809028556364,-141.67488300745535,-141.66189952308758],[34.851882467682195,34.84848465666672,37.348552835203996,34.84819716524268,32.34855285207161,34.84848465666672],[19.18005005376656,17.326604551348424,15.984894556813657,15.029871711418627,19.757788823409832,17.326604551348424],[19.18005005376656,15.782575879562952,13.483888387919782,15.122781689567564,18.394242219230726,15.782575879562952],[19.18005005376656,25.60141690157377,27.65341721823042,26.8250862178223,22.968958892549146,25.60141690157377],[-2.6236818957972776,-0.07168764494898461,2.2072065229544857,0.6402053798270149,-2.6882741753946275,-0.07168764494898461],[-2.6236818957972776,12.04013068856042,10.12507093927223,15.122781689567564,12.49290936022371,12.04013068856042],[-2.6236818957972776,-0.8165618896583853,-3.4421223062668456,0.01367303858752807,1.4151697006701547,-0.8165618896583853],[17.64794512343082,16.285663979460303,18.917050000782325,15.029871711418627,14.249973439198271,16.285663979460303],[17.64794512343082,2.9974585371396607,2.398373535396918,0.01367303858752807,5.0119269451774615,2.9974585371396607],[17.64794512343082,34.078122583830385,34.46832966569009,37.19976305162342,32.20713944729874,34.078122583830385],[17.361354830535326,3.792153873426959,3.452883955231246,0.6402053798270149,5.626576709787485,3.792153873426959],[17.361354830535326,24.19344837937424,25.21748159641742,26.8250862178223,21.92107592020892,24.19344837937424],[17.361354830535326,34.33050230564982,32.21830848326973,37.19976305162342,35.08163848827819,34.33050230564982],[42.33438781184292,30.323933261117162,31.08962278064395,26.8250862178223,31.217950864856142,30.323933261117162],[42.33438781184292,35.47639985147198,33.16599533010133,34.84819716524268,38.084797528956024,35.47639985147198],[42.33438781184292,52.1882595402344,53.92099719147567,53.96466500077084,49.61286922079184,52.1882595402344],[62.808082530055444,29.339954137710123,28.197697987444442,26.8250862178223,31.67515875044411,29.339954137710123],[62.808082530055444,-141.61388168314963,-141.50557120205312,-144.97809028556364,-140.12635190244362,-141.61388168314963],[62.808082530055444,36.0642104492831,34.00836083305719,34.84819716524268,38.6968860554806,36.0642104492831],[-0.553959854560857,-0.12758709818335354,2.3368719470804455,0.01367303858752807,-2.6590540612929545,-0.12758709818335354],[-0.553959854560857,31.669049770949883,31.960669703308085,34.84819716524268,29.8693748962268,31.669049770949883],[-0.553959854560857,-10.970980703637636,-12.102689698089797,-13.496628475304133,-8.641209734590625,-10.970980703637636],[-22.635106090529064,-1.8348674810279688,-0.1504319112274803,0.01367303858752807,-4.396173582774341,-1.8348674810279688],[-22.635106090529064,-141.78092120700796,-140.0053927756598,-144.97809028556364,-142.03984596054374,-141.78092120700796],[-22.635106090529064,31.94398827846345,32.65041948627574,34.84819716524268,29.859921490360087,31.94398827846345],[57.00149749918813,40.20723693340878,42.19931813091286,37.19976305162342,39.64177592331775,40.20723693340878],[57.00149749918813,38.19876451347567,38.27074933750019,34.84819716524268,39.71614910915784,38.19876451347567],[57.00149749918813,72.71114184005084,71.41055098871279,76.14428069155251,72.38319479405003,72.71114184005084],[89.4222184982506,40.50180116123407,42.11383786492622,37.19976305162342,40.45611363028396,40.50180116123407],[89.4222184982506,-141.4859222252798,-140.4905004004007,-144.97809028556364,-140.82480515789678,-141.4859222252798],[89.4222184982506,38.348187967387666,39.17258136175548,34.84819716524268,39.184044247785394,38.348187967387666],[-146.37918054221225,-145.40850805767883,-143.02957022270195,-144.97809028556364,-147.99161813383117,-145.40850805767883],[-146.37918054221225,-144.70753398165976,-146.36523213416598,-141.43195492316931,-144.6036339314785,-144.70753398165976],[-146.37918054221225,-148.70199624633918,-150.78411689287464,-149.86496953886694,-146.06820956985388,-148.70199624633918],[-152.90399699369698,-145.8548416969062,-143.6424976122773,-144.97809028556364,-148.48308008749717,-145.8548416969062],[-152.90399699369698,-176.9754158068829,-179.29920101204294,-177.56681419580656,-174.37109586938425,-176.9754158068829],[-152.90399699369698,-143.35369791274564,-141.72005341809376,-141.43195492316931,-145.8989371382956,-143.35369791274564],[-144.4222919267058,-144.83460431275608,-147.29847070926644,-144.97809028556364,-142.30267415460918,-144.83460431275608],[-144.4222919267058,-146.4680206110497,-144.61612456644428,-149.60570618132508,-146.83152947350206,-146.4680206110497],[-144.4222919267058,-141.91362324341216,-140.0229807240397,-140.3922770855331,-144.525928934664,-141.91362324341216],[-137.07274852058956,-147.06175772252126,-148.17539686128018,-149.60570618132508,-144.74137552639178,-147.06175772252126]]},\"selected\":{\"id\":\"1160\"},\"selection_policy\":{\"id\":\"1161\"}},\"id\":\"1041\",\"type\":\"ColumnDataSource\"},{\"attributes\":{},\"id\":\"1168\",\"type\":\"Selection\"},{\"attributes\":{\"fill_color\":{\"value\":\"#abdda4\"},\"size\":{\"units\":\"screen\",\"value\":8}},\"id\":\"1089\",\"type\":\"Square\"},{\"attributes\":{\"fill_color\":{\"value\":\"#2b83ba\"},\"size\":{\"units\":\"screen\",\"value\":8}},\"id\":\"1079\",\"type\":\"Square\"},{\"attributes\":{},\"id\":\"1167\",\"type\":\"UnionRenderers\"},{\"attributes\":{\"edge_renderer\":{\"id\":\"1014\"},\"inspection_policy\":{\"id\":\"1144\"},\"layout_provider\":{\"id\":\"1020\"},\"node_renderer\":{\"id\":\"1010\"},\"selection_policy\":{\"id\":\"1143\"}},\"id\":\"1007\",\"type\":\"GraphRenderer\"},{\"attributes\":{\"data_source\":{\"id\":\"1041\"},\"glyph\":{\"id\":\"1054\"},\"hover_glyph\":{\"id\":\"1064\"},\"muted_glyph\":null,\"selection_glyph\":{\"id\":\"1059\"},\"view\":{\"id\":\"1043\"}},\"id\":\"1042\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"source\":{\"id\":\"1013\"}},\"id\":\"1015\",\"type\":\"CDSView\"},{\"attributes\":{},\"id\":\"1170\",\"type\":\"Selection\"},{\"attributes\":{\"fill_color\":{\"value\":\"#fdae61\"},\"size\":{\"units\":\"screen\",\"value\":8}},\"id\":\"1084\",\"type\":\"Square\"},{\"attributes\":{},\"id\":\"1161\",\"type\":\"UnionRenderers\"},{\"attributes\":{},\"id\":\"1153\",\"type\":\"NodesOnly\"},{\"attributes\":{},\"id\":\"1169\",\"type\":\"UnionRenderers\"},{\"attributes\":{\"data_source\":{\"id\":\"1013\"},\"glyph\":{\"id\":\"1012\"},\"hover_glyph\":null,\"muted_glyph\":null,\"view\":{\"id\":\"1015\"}},\"id\":\"1014\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"line_color\":{\"value\":\"#abdda4\"},\"line_width\":{\"value\":5}},\"id\":\"1064\",\"type\":\"MultiLine\"},{\"attributes\":{\"line_alpha\":{\"value\":0.2},\"line_width\":{\"value\":4}},\"id\":\"1054\",\"type\":\"MultiLine\"},{\"attributes\":{\"data\":{\"color\":[\"purple\",\"green\",\"cyan\",\"green\",\"cyan\",\"cyan\",\"cyan\",\"green\",\"cyan\",\"cyan\",\"cyan\",\"orange\",\"cyan\",\"grey\",\"green\",\"cyan\",\"green\",\"green\",\"blue\",\"blue\",\"blue\",\"blue\",\"blue\",\"blue\",\"blue\",\"blue\",\"blue\",\"blue\",\"blue\",\"blue\",\"blue\",\"blue\",\"blue\",\"blue\"],\"index\":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33],\"k\":[null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,100,0.01,100,100,100,100,100,0.05,100,0.05,100,0.05,100,1.5,100,0.000555556],\"k_r\":[null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,100,0,50,50,50,50,10,0,10,0,10,0,10.0,0,10,0],\"species\":[\"nothing\",\"protein_Ribo\",\"complex_dna_mydna_protein_hrpR\",\"protein_GFP\",\"complex_protein_Ribo_rna_mydna\",\"complex_dna_mydna_protein_RNAP\",\"complex_dna_mydna_protein_hrpR_protein_hrpS_protein_RNAP\",\"protein_RNAase\",\"complex_dna_mydna_protein_hrpR_protein_hrpS\",\"complex_protein_RNAase_rna_mydna\",\"complex_dna_mydna_protein_hrpR_protein_RNAP\",\"rna_mydna\",\"complex_dna_mydna_protein_hrpS\",\"dna_mydna\",\"protein_RNAP\",\"complex_dna_mydna_protein_hrpS_protein_RNAP\",\"protein_hrpR\",\"protein_hrpS\",\"dna_mydna + protein_RNAP <--> complex_dna_mydna_protein_RNAP massaction: k_f(dna_mydna,protein_RNAP)=100*dna_mydna*protein_RNAP k_r(complex_dna_mydna_protein_RNAP)=100*complex_dna_mydna_protein_RNAP\",\"complex_dna_mydna_protein_RNAP --> dna_mydna + rna_mydna + protein_RNAP massaction: k_f(complex_dna_mydna_protein_RNAP)=0.01*complex_dna_mydna_protein_RNAP\",\"protein_hrpR + dna_mydna <--> complex_dna_mydna_protein_hrpR massaction: k_f(protein_hrpR,dna_mydna)=100*protein_hrpR*dna_mydna k_r(complex_dna_mydna_protein_hrpR)=50*complex_dna_mydna_protein_hrpR\",\"protein_hrpS + dna_mydna <--> complex_dna_mydna_protein_hrpS massaction: k_f(protein_hrpS,dna_mydna)=100*protein_hrpS*dna_mydna k_r(complex_dna_mydna_protein_hrpS)=50*complex_dna_mydna_protein_hrpS\",\"protein_hrpR + complex_dna_mydna_protein_hrpS <--> complex_dna_mydna_protein_hrpR_protein_hrpS massaction: k_f(protein_hrpR,complex_dna_mydna_protein_hrpS)=100*protein_hrpR*complex_dna_mydna_protein_hrpS k_r(complex_dna_mydna_protein_hrpR_protein_hrpS)=50*complex_dna_mydna_protein_hrpR_protein_hrpS\",\"protein_hrpS + complex_dna_mydna_protein_hrpR <--> complex_dna_mydna_protein_hrpR_protein_hrpS massaction: k_f(protein_hrpS,complex_dna_mydna_protein_hrpR)=100*protein_hrpS*complex_dna_mydna_protein_hrpR k_r(complex_dna_mydna_protein_hrpR_protein_hrpS)=50*complex_dna_mydna_protein_hrpR_protein_hrpS\",\"complex_dna_mydna_protein_hrpR + protein_RNAP <--> complex_dna_mydna_protein_hrpR_protein_RNAP massaction: k_f(complex_dna_mydna_protein_hrpR,protein_RNAP)=100*complex_dna_mydna_protein_hrpR*protein_RNAP k_r(complex_dna_mydna_protein_hrpR_protein_RNAP)=10*complex_dna_mydna_protein_hrpR_protein_RNAP\",\"complex_dna_mydna_protein_hrpR_protein_RNAP --> complex_dna_mydna_protein_hrpR + rna_mydna + protein_RNAP massaction: k_f(complex_dna_mydna_protein_hrpR_protein_RNAP)=0.05*complex_dna_mydna_protein_hrpR_protein_RNAP\",\"complex_dna_mydna_protein_hrpS + protein_RNAP <--> complex_dna_mydna_protein_hrpS_protein_RNAP massaction: k_f(complex_dna_mydna_protein_hrpS,protein_RNAP)=100*complex_dna_mydna_protein_hrpS*protein_RNAP k_r(complex_dna_mydna_protein_hrpS_protein_RNAP)=10*complex_dna_mydna_protein_hrpS_protein_RNAP\",\"complex_dna_mydna_protein_hrpS_protein_RNAP --> complex_dna_mydna_protein_hrpS + rna_mydna + protein_RNAP massaction: k_f(complex_dna_mydna_protein_hrpS_protein_RNAP)=0.05*complex_dna_mydna_protein_hrpS_protein_RNAP\",\"complex_dna_mydna_protein_hrpR_protein_hrpS + protein_RNAP <--> complex_dna_mydna_protein_hrpR_protein_hrpS_protein_RNAP massaction: k_f(complex_dna_mydna_protein_hrpR_protein_hrpS,protein_RNAP)=100*complex_dna_mydna_protein_hrpR_protein_hrpS*protein_RNAP k_r(complex_dna_mydna_protein_hrpR_protein_hrpS_protein_RNAP)=10*complex_dna_mydna_protein_hrpR_protein_hrpS_protein_RNAP\",\"complex_dna_mydna_protein_hrpR_protein_hrpS_protein_RNAP --> complex_dna_mydna_protein_hrpR_protein_hrpS + rna_mydna + protein_RNAP massaction: k_f(complex_dna_mydna_protein_hrpR_protein_hrpS_protein_RNAP)=0.05*complex_dna_mydna_protein_hrpR_protein_hrpS_protein_RNAP\",\"rna_mydna + protein_Ribo <--> complex_protein_Ribo_rna_mydna massaction: k_f(rna_mydna,protein_Ribo)=100*rna_mydna*protein_Ribo k_r(complex_protein_Ribo_rna_mydna)=10.0*complex_protein_Ribo_rna_mydna\",\"complex_protein_Ribo_rna_mydna --> rna_mydna + protein_GFP + protein_Ribo massaction: k_f(complex_protein_Ribo_rna_mydna)=1.5*complex_protein_Ribo_rna_mydna\",\"rna_mydna + protein_RNAase <--> complex_protein_RNAase_rna_mydna massaction: k_f(rna_mydna,protein_RNAase)=100*rna_mydna*protein_RNAase k_r(complex_protein_RNAase_rna_mydna)=10*complex_protein_RNAase_rna_mydna\",\"complex_protein_RNAase_rna_mydna --> protein_RNAase massaction: k_f(complex_protein_RNAase_rna_mydna)=0.000555556*complex_protein_RNAase_rna_mydna\"],\"type\":[\"nothing\",\"protein\",\"complex\",\"protein\",\"complex\",\"complex\",\"complex\",\"protein\",\"complex\",\"complex\",\"complex\",\"rna\",\"complex\",\"dna\",\"protein\",\"complex\",\"protein\",\"protein\",\"massaction\",\"massaction\",\"massaction\",\"massaction\",\"massaction\",\"massaction\",\"massaction\",\"massaction\",\"massaction\",\"massaction\",\"massaction\",\"massaction\",\"massaction\",\"massaction\",\"massaction\",\"massaction\"]},\"selected\":{\"id\":\"1162\"},\"selection_policy\":{\"id\":\"1163\"}},\"id\":\"1037\",\"type\":\"ColumnDataSource\"},{\"attributes\":{\"attachment\":\"right\",\"callback\":null,\"renderers\":[{\"id\":\"1021\"}],\"tooltips\":[[\"name\",\"@species\"],[\"type\",\"@type\"]]},\"id\":\"1110\",\"type\":\"HoverTool\"},{\"attributes\":{\"fill_color\":{\"value\":\"#fdae61\"},\"size\":{\"units\":\"screen\",\"value\":15}},\"id\":\"1099\",\"type\":\"Circle\"},{\"attributes\":{\"graph_layout\":{\"0\":[-128.06534390538394,188.8110737063345],\"1\":[-4.942642958329285,-141.43195492316931],\"10\":[-63.05482954977653,53.96466500077084],\"11\":[-18.111741884048353,-144.97809028556364],\"12\":[-0.03034153180732158,0.01367303858752807],\"13\":[-1.289279313130396,15.122781689567564],\"14\":[-2.279250371726325,34.84819716524268],\"15\":[26.43926448068255,-13.496628475304133],\"16\":[-17.653612018224468,15.029871711418627],\"17\":[-26.542599340112336,0.6402053798270149],\"18\":[15.827931173971795,29.42291883724415],\"19\":[42.58663923851341,34.851882467682195],\"2\":[-42.912667181668425,26.8250862178223],\"20\":[-22.425925393415437,19.18005005376656],\"21\":[-10.831238753170846,-2.6236818957972776],\"22\":[-10.842673172635013,17.64794512343082],\"23\":[-34.61463764843533,17.361354830535326],\"24\":[-43.31085414311069,42.33438781184292],\"25\":[-77.741780780435,62.808082530055444],\"26\":[14.022429470966996,-0.553959854560857],\"27\":[36.38357800981411,-22.635106090529064],\"28\":[-8.968942098927226,57.00149749918813],\"29\":[-2.4043658578715292,89.4222184982506],\"3\":[156.37991411946888,-177.56681419580656],\"30\":[-6.805066829718983,-146.37918054221225],\"31\":[12.5197498143886,-152.90399699369698],\"32\":[-31.65772711420718,-144.4222919267058],\"33\":[-46.06217951791717,-137.07274852058956],\"4\":[3.0894514477121673,-149.86496953886694],\"5\":[30.79277003241157,32.55511799827421],\"6\":[-5.172597935166938,76.14428069155251],\"7\":[-34.21960043849704,-149.60570618132508],\"8\":[-20.756455984906772,37.19976305162342],\"9\":[-40.00747948102076,-140.3922770855331]}},\"id\":\"1034\",\"type\":\"StaticLayoutProvider\"},{\"attributes\":{\"data\":{\"end\":[],\"start\":[]},\"selected\":{\"id\":\"1168\"},\"selection_policy\":{\"id\":\"1169\"}},\"id\":\"1027\",\"type\":\"ColumnDataSource\"},{\"attributes\":{},\"id\":\"1171\",\"type\":\"UnionRenderers\"},{\"attributes\":{},\"id\":\"1125\",\"type\":\"EdgesAndLinkedNodes\"},{\"attributes\":{},\"id\":\"1144\",\"type\":\"NodesOnly\"},{\"attributes\":{},\"id\":\"1026\",\"type\":\"MultiLine\"},{\"attributes\":{\"data_source\":{\"id\":\"1037\"},\"glyph\":{\"id\":\"1049\"},\"hover_glyph\":null,\"muted_glyph\":null,\"view\":{\"id\":\"1039\"}},\"id\":\"1038\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"callback\":null},\"id\":\"1112\",\"type\":\"TapTool\"},{\"attributes\":{},\"id\":\"1012\",\"type\":\"MultiLine\"},{\"attributes\":{\"source\":{\"id\":\"1041\"}},\"id\":\"1043\",\"type\":\"CDSView\"},{\"attributes\":{\"fill_color\":{\"value\":\"#abdda4\"},\"size\":{\"units\":\"screen\",\"value\":15}},\"id\":\"1104\",\"type\":\"Circle\"},{\"attributes\":{\"bottom_units\":\"screen\",\"fill_alpha\":0.5,\"fill_color\":\"lightgrey\",\"left_units\":\"screen\",\"level\":\"overlay\",\"line_alpha\":1.0,\"line_color\":\"black\",\"line_dash\":[4,4],\"line_width\":2,\"render_mode\":\"css\",\"right_units\":\"screen\",\"top_units\":\"screen\"},\"id\":\"1159\",\"type\":\"BoxAnnotation\"},{\"attributes\":{\"active_drag\":\"auto\",\"active_inspect\":\"auto\",\"active_multi\":null,\"active_scroll\":\"auto\",\"active_tap\":\"auto\",\"tools\":[{\"id\":\"1109\"},{\"id\":\"1110\"},{\"id\":\"1111\"},{\"id\":\"1112\"},{\"id\":\"1113\"},{\"id\":\"1114\"},{\"id\":\"1115\"}]},\"id\":\"1116\",\"type\":\"Toolbar\"},{\"attributes\":{\"attachment\":\"right\",\"callback\":null,\"renderers\":[{\"id\":\"1007\"}],\"tooltips\":[[\"reaction\",\"@species\"],[\"type\",\"@type\"],[\"k_f\",\"@k\"],[\"k_r\",\"@k_r\"]]},\"id\":\"1111\",\"type\":\"HoverTool\"},{\"attributes\":{},\"id\":\"1115\",\"type\":\"WheelZoomTool\"},{\"attributes\":{\"source\":{\"id\":\"1023\"}},\"id\":\"1025\",\"type\":\"CDSView\"},{\"attributes\":{\"data\":{\"end\":[],\"start\":[]},\"selected\":{\"id\":\"1164\"},\"selection_policy\":{\"id\":\"1165\"}},\"id\":\"1013\",\"type\":\"ColumnDataSource\"}],\"root_ids\":[\"1004\"]},\"title\":\"Bokeh Application\",\"version\":\"2.0.2\"}};\n", + " var render_items = [{\"docid\":\"9928c12b-e691-4cdb-9e7f-98f5884c7443\",\"root_ids\":[\"1004\"],\"roots\":{\"1004\":\"dd2c33e0-0319-4473-a862-2301ac5db20f\"}}];\n", " root.Bokeh.embed.embed_items_notebook(docs_json, render_items);\n", "\n", " }\n", @@ -545,7 +555,7 @@ }, "metadata": { "application/vnd.bokehjs_exec.v0+json": { - "id": "2020" + "id": "1004" } }, "output_type": "display_data" @@ -554,12 +564,12 @@ "name": "stdout", "output_type": "stream", "text": [ - "{('phrpL_hrpR', 'cooperativity'): 1.0, ('phrpL_hrpS', 'cooperativity'): 1.0, ('phrpL_hrpR', 'ku'): 50, ('phrpL_hrpS', 'ku'): 50, ('phrpL_leak', 'ktx'): 0.01, ('phrpL_leak', 'ku'): 100, ('translation_mm', 'B0030', 'ku'): 10.0, ('translation_mm', 'B0030', 'ktl'): 1.5, 'kb': 100.0, 'ku': 10.0, 'ktx': 0.05, 'ktl': 0.05, 'kdeg': 2, ('e coli', 'Ribo'): 120.0, ('e coli', 'RNAP'): 15.0, ('e coli', 'RNAase'): 30.0, ('e coli extract 1', 'Ribo'): 24.0, ('e coli extract 1', 'RNAP'): 3.0, ('e coli extract 1', 'RNAase'): 6.0, ('e coli extract 2', 'Ribo'): 12.0, ('e coli extract 2', 'RNAP'): 6.0, ('e coli extract 2', 'RNAase'): 3.0, 'cooperativity': 2.0, 'kdil': 0.001, ('rna_degredation_mm', 'kdeg'): 0.000555556, ('rna_degredation', 'kdil'): 0.002, ('simple_transcription', 'ktx'): 0.1875, ('simple_translation', 'ktl'): 1.5, ('gene_expression', 'kexpress'): 0.28125, ('negativehill_transcription', 'k'): 0.01875, ('negativehill_transcription', 'K'): 10.0, ('negativehill_transcription', 'n'): 2.0, ('negativehill_transcription', 'kleak'): 1e-06, ('J23103', 'ku'): 588.2352941, ('J23116', 'ku'): 25.25252525, ('J23107', 'ku'): 11.01321586, ('J23106', 'ku'): 8.438818565, ('J23102', 'ku'): 4.589261129, ('J23100', 'ku'): 3.926187672, ('simple_transcription', 'J23103', 'ktx'): 0.0031875, ('simple_transcription', 'J23116', 'ktx'): 0.07425, ('simple_transcription', 'J23107', 'ktx'): 0.17025, ('simple_transcription', 'J23106', 'ktx'): 0.2221875, ('simple_transcription', 'J23102', 'ktx'): 0.4085625, ('simple_transcription', 'J23100', 'ktx'): 0.4775625, ('simple_transcription', 'pT7', 'ktx'): 0.327, ('BCD2', 'ku'): 0.5, ('BCD8', 'ku'): 10.0, ('BCD12', 'ku'): 5.0, ('simple_translation', 'BCD2', 'ktl'): 3.0, ('simple_translation', 'BCD8', 'ktl'): 0.15, ('simple_translation', 'BCD12', 'ktl'): 0.3, ('MX', 'pT7', 'k1'): 0.072, ('MX', 'pT7', 'k2'): 4.0, ('MX', 'pT7', 'k_iso'): 0.36, ('MX', 'pT7', 'ktx_solo'): 0.085, ('MX', 'pT7', 'max_occ'): 40.0, ('multi_tl', 'RBSG', 'kbr'): 1.0, ('multi_tl', 'RBSG', 'kur'): 100.0, ('multi_tl', 'RBSG', 'k_iso_r'): 0.3, ('multi_tl', 'RBSG', 'ktl_solo'): 0.02, ('multi_tl', 'RBSG', 'max_occ'): 22.0}\n" + "{(None, 'phrpL_hrpR', 'cooperativity'): 1.0, (None, 'phrpL_hrpS', 'cooperativity'): 1.0, (None, 'phrpL_hrpR', 'ku'): 50, (None, 'phrpL_hrpS', 'ku'): 50, (None, 'phrpL_leak', 'ktx'): 0.01, (None, 'phrpL_leak', 'ku'): 100, ('translation_mm', 'B0030', 'ku'): 10.0, ('translation_mm', 'B0030', 'ktl'): 1.5, 'kb': 100, 'ku': 10, 'ktx': 0.05, 'ktl': 0.2, 'kdeg': 2}\n" ] }, { "data": { - "image/png": "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\n", + "image/png": "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\n", "text/plain": [ "
" ] @@ -573,18 +583,16 @@ "source": [ "#these are the additional parameters that you need:\n", "parameters = {\n", - " ('phrpL_hrpR', 'cooperativity'): 1.0, #default is 2, but these proteins bind at cooperativity = 1\n", - " ('phrpL_hrpS', 'cooperativity'): 1.0, \n", - " ('phrpL_hrpR', 'ku'):50, #these are the regulator unbinding rates\n", - " ('phrpL_hrpS', 'ku'):50,\n", - " ('phrpL_leak', 'ktx'): 0.01, #this is the leak rate\n", - " ('phrpL_leak', 'ku'): 100, #this is the leak polymerase unbinding rate\n", + " (None, 'phrpL_hrpR', 'cooperativity'): 1.0, #default is 2, but these proteins bind at cooperativity = 1\n", + " (None, 'phrpL_hrpS', 'cooperativity'): 1.0, \n", + " (None, 'phrpL_hrpR', 'ku'):50, #these are the regulator unbinding rates\n", + " (None, 'phrpL_hrpS', 'ku'):50,\n", + " (None, 'phrpL_leak', 'ktx'): 0.01, #this is the leak rate\n", + " (None, 'phrpL_leak', 'ku'): 100, #this is the leak polymerase unbinding rate\n", "\n", " ('translation_mm', 'B0030', 'ku'): 10.0, #Unbinding\n", " ('translation_mm', 'B0030', 'ktl'): 1.5, #Translation Rate\n", "\n", - " #('transcription_mm', 'ktx'): .01, #These are the parameters for transcription leak\n", - " #('transcription_mm', 'ku'): 100,\n", " \"kb\":100, \"ku\":10, \"ktx\":.05, \"ktl\":.2, \"kdeg\":2 #some default parameters\n", "}\n", "#above you can see the desired part_id is very simple. The general syntax is _.\n", @@ -622,8 +630,9 @@ "dna = DNAassembly(\"mydna\",promoter=phrpL,rbs=\"B0030\",protein=\"GFP\")\n", "\n", "#TxTl Extract is a Mixture with more complex internal models\n", - "extract_1_TXTL = TxTlExtract(name = \"e coli extract 1\", components = [dna,hrpR,hrpS], \\\n", - " parameters=parameters, parameter_file = \"default_parameters.txt\")\n", + "extract_1_TXTL = TxTlExtract(name = \"e coli extract 1\", components = [dna,hrpR,hrpS], \n", + " parameters=parameters, parameter_file = \"default_parameters.txt\", \n", + " overwrite_parameters = True) #Overwrite parameters will overwrite the parameters in the file with the dictionary\n", "CRN_extract_1 = extract_1_TXTL.compile_crn()\n", "\n", "print(\"The species and reactions in the CRN:\\n\", CRN_extract_1.pretty_print())\n", @@ -635,23 +644,22 @@ " graphPlot(DG,DGspec,DGrxn,plot)\n", " bokeh.io.show(plot)\n", "\n", - "#this is just a normal time trace of the model, with both proteins present\n", - "try:\n", + " #this is just a normal time trace of the model, with both proteins present\n", + "\n", " timepoints = np.linspace(0, 200, 1000)\n", " x0 = {\"dna_mydna\":5.0, \"protein_hrpS\":10, \"protein_hrpR\":7, \"protein_RNAP\":10., \"protein_Ribo\":50.,}\n", " Re1 = CRN_extract_1.simulate_with_bioscrape(timepoints, initial_condition_dict = x0)\n", - " plt.plot(timepoints,Re1[\"protein_GFP\"], label = \"protein_GFP\")\n", - " plt.plot(timepoints,Re1[\"protein_hrpR\"], label = \"protein_hrpR\")\n", - " plt.plot(timepoints,Re1[\"protein_hrpS\"], label = \"protein_hrpS\")\n", - " plt.plot(timepoints,Re1[\"rna_mydna\"], label = \"rna_mydna\")\n", - " plt.gca().set_yscale(\"log\")\n", - " plt.title(\"Time trace of AND gate promoter phrpL\")\n", - " plt.xlabel(\"time\")\n", - " plt.ylabel(\"protein\")\n", - " plt.legend()\n", - " print(parameters)\n", - "except ModuleNotFoundError:\n", - " pass" + " if Re1 is not None:\n", + " plt.plot(timepoints,Re1[\"protein_GFP\"], label = \"protein_GFP\")\n", + " plt.plot(timepoints,Re1[\"protein_hrpR\"], label = \"protein_hrpR\")\n", + " plt.plot(timepoints,Re1[\"protein_hrpS\"], label = \"protein_hrpS\")\n", + " plt.plot(timepoints,Re1[\"rna_mydna\"], label = \"rna_mydna\")\n", + " plt.gca().set_yscale(\"log\")\n", + " plt.title(\"Time trace of AND gate promoter phrpL\")\n", + " plt.xlabel(\"time\")\n", + " plt.ylabel(\"protein\")\n", + " plt.legend()\n", + " print(parameters)\n" ] }, { @@ -664,7 +672,7 @@ }, { "cell_type": "code", - "execution_count": 15, + "execution_count": 3, "metadata": {}, "outputs": [ { @@ -673,12 +681,12 @@ "text": [ "C:\\ProgramData\\Anaconda3\\lib\\site-packages\\scipy\\integrate\\odepack.py:248: ODEintWarning: Excess work done on this call (perhaps wrong Dfun type). Run with full_output = 1 to get quantitative information.\n", " warnings.warn(warning_msg, ODEintWarning)\n", - "odeint failed with mxstep=500...odeint failed with mxstep=500...odeint failed with mxstep=500...odeint failed with mxstep=500...odeint failed with mxstep=500...odeint failed with mxstep=500...odeint failed with mxstep=500...odeint failed with mxstep=500...odeint failed with mxstep=500...odeint failed with mxstep=500...odeint failed with mxstep=500...odeint failed with mxstep=500...odeint failed with mxstep=500...odeint failed with mxstep=500...odeint failed with mxstep=500...odeint failed with mxstep=500...odeint failed with mxstep=500...odeint failed with mxstep=500...odeint failed with mxstep=500...odeint failed with mxstep=500...odeint failed with mxstep=500...odeint failed with mxstep=500...odeint failed with mxstep=500..." + "odeint failed with mxstep=500...odeint failed with mxstep=500...odeint failed with mxstep=500..." ] }, { "data": { - "image/png": "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\n", + "image/png": "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\n", "text/plain": [ "
" ] @@ -697,17 +705,19 @@ " conc_hrpR = np.linspace(0, 30, 9)\n", " conc_hrpS = np.linspace(0, 30, 9)\n", "\n", - " try:\n", - " for conc_R in conc_hrpR:\n", - " x0[\"protein_hrpR\"] = conc_R \n", - " for conc_S in conc_hrpS:\n", - " x0[\"protein_hrpS\"] = conc_S #Change my initial condition dictionary\n", - " Re1 = CRN_extract_1.simulate_with_bioscrape(timepoints, initial_condition_dict = x0)\n", - " #now we are simulating over and over again, but only taking the final protein_GFP value\n", + "\n", + " for conc_R in conc_hrpR:\n", + " x0[\"protein_hrpR\"] = conc_R\n", + " for conc_S in conc_hrpS:\n", + " x0[\"protein_hrpS\"] = conc_S #Change my initial condition dictionary\n", + " Re1 = CRN_extract_1.simulate_with_bioscrape(timepoints, initial_condition_dict = x0)\n", + " #now we are simulating over and over again, but only taking the final protein_GFP value\n", + " if Re1 is not None:\n", " GFP_max = GFP_max.append({'hrpS_conc':conc_S,\n", " 'hrpR_conc':conc_R,\n", " 'GFP_max': Re1[\"protein_GFP\"].values[-1]}, ignore_index=True)\n", - " #now, you make a 2d plot with all the data\n", + " #now, you make a 2d plot with all the data\n", + " if GFP_max is not None:\n", " data = pd.pivot_table(data = GFP_max, index = 'hrpS_conc',\n", " columns = 'hrpR_conc',\n", " values = 'GFP_max')\n", @@ -718,9 +728,7 @@ " ax.set_ylim(9,-0.5) #not sure why this is needed\n", "\n", " ax.set(xlabel='hrpS', ylabel='hrpR')\n", - " ax.set_title(\"hrpR, hrpS Combinatorial Promoter Heatmap\")\n", - " except ModuleNotFoundError:\n", - " pass" + " ax.set_title(\"hrpR, hrpS Combinatorial Promoter Heatmap\")\n" ] }, { @@ -754,21 +762,29 @@ }, { "cell_type": "code", - "execution_count": 16, + "execution_count": 5, "metadata": {}, "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "mixture.add_component: DNAassembly: mydna rna_mydna\n", + "mixture.update_species: DNAassembly: mydna rna_mydna\n" + ] + }, { "name": "stderr", "output_type": "stream", "text": [ "C:\\ProgramData\\Anaconda3\\lib\\site-packages\\scipy\\integrate\\odepack.py:248: ODEintWarning: Excess work done on this call (perhaps wrong Dfun type). Run with full_output = 1 to get quantitative information.\n", " warnings.warn(warning_msg, ODEintWarning)\n", - "odeint failed with mxstep=500...odeint failed with mxstep=500...odeint failed with mxstep=500...odeint failed with mxstep=500...odeint failed with mxstep=500...odeint failed with mxstep=500...odeint failed with mxstep=500...odeint failed with mxstep=500...odeint failed with mxstep=500...odeint failed with mxstep=500...odeint failed with mxstep=500...odeint failed with mxstep=500...odeint failed with mxstep=500...odeint failed with mxstep=500...odeint failed with mxstep=500...odeint failed with mxstep=500...odeint failed with mxstep=500..." + "odeint failed with mxstep=500...odeint failed with mxstep=500...odeint failed with mxstep=500...odeint failed with mxstep=500...odeint failed with mxstep=500...odeint failed with mxstep=500...odeint failed with mxstep=500...odeint failed with mxstep=500...odeint failed with mxstep=500...odeint failed with mxstep=500...odeint failed with mxstep=500...odeint failed with mxstep=500...odeint failed with mxstep=500...odeint failed with mxstep=500...odeint failed with mxstep=500...odeint failed with mxstep=500...odeint failed with mxstep=500...odeint failed with mxstep=500...odeint failed with mxstep=500...odeint failed with mxstep=500...odeint failed with mxstep=500..." ] }, { "data": { - "image/png": "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\n", + "image/png": "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\n", "text/plain": [ "
" ] @@ -781,15 +797,14 @@ ], "source": [ "newparam = {\n", - " ('phrpL_hrpR', 'cooperativity'): 1.0, \n", - " ('phrpL_hrpS', 'cooperativity'): 1.0, \n", - " ('phrpL_hrpR','ku'):5, #unbinding rate of each regulator\n", - " ('phrpL_hrpS','ku'):5,\n", - " ('phrpL_hrpR_hrpS_RNAP', 'ktx'): 0.17025, #these are the rates for the correctly bound promoter\n", - " ('phrpL_hrpR_hrpS_RNAP', 'ku'): 11.01321586,\n", - " ('phrpL_leak','ktx'):0.01, #this is the leak transcription rate\n", - " ('phrpL_leak', 'ku'): 100.,#this unbinding rate is now needed because we changed the tx_capable_list. Transcription from singly bound promoter uses the default \"ktx\"\n", - " \n", + " (None, 'phrpL_hrpR', 'cooperativity'): 1.0, \n", + " (None, 'phrpL_hrpS', 'cooperativity'): 1.0, \n", + " (None, 'phrpL_hrpR','ku'):5, #unbinding rate of each regulator\n", + " (None, 'phrpL_hrpS','ku'):5,\n", + " (None, 'phrpL_hrpR_hrpS_RNAP', 'ktx'): 0.17025, #these are the rates for the correctly bound promoter\n", + " (None, 'phrpL_hrpR_hrpS_RNAP', 'ku'): 11.01321586,\n", + " (None, 'phrpL_leak','ktx'):0.01, #this is the leak transcription rate\n", + " (None, 'phrpL_leak', 'ku'): 100.,#this unbinding rate is now needed because we changed the tx_capable_list. Transcription from singly bound promoter uses the default \"ktx\"\n", "}\n", "\n", "#WARNING!!!\n", @@ -809,42 +824,41 @@ "#this is our DNA\n", "dna = DNAassembly(\"mydna\",promoter=phrpL,rbs=\"B0030\",protein=\"GFP\")\n", "\n", - "extract_1_TXTL = TxTlExtract(name = \"e coli extract 1\", components = [dna,hrpR,hrpS], \\\n", - " parameters=parameters, parameter_file = \"default_parameters.txt\")\n", + "extract_1_TXTL = TxTlExtract(name = \"e coli extract 1\", components = [dna,hrpR,hrpS],\n", + " parameters=parameters, parameter_file = \"default_parameters.txt\",\n", + " overwrite_parameters = True) #Overwrite parameters will overwrite the parameters in the file with the dictionary\n", "CRN_extract_1 = extract_1_TXTL.compile_crn()\n", - "try:\n", - " if(make_heatmap):\n", - " #aggregator data frame\n", - " GFP_max = pd.DataFrame(columns = ['hrpS_conc', 'hrpR_conc', 'GFP_max'])\n", - " #Different initial values of R and S\n", - " conc_hrpR = np.linspace(0, 30, 9)\n", - " conc_hrpS = np.linspace(0, 30, 9)\n", - "\n", - "\n", - " for conc_R in conc_hrpR:\n", - " x0[\"protein_hrpR\"] = conc_R \n", - " for conc_S in conc_hrpS:\n", - " x0[\"protein_hrpS\"] = conc_S #Change my initial condition dictionary\n", - " Re1 = CRN_extract_1.simulate_with_bioscrape(timepoints, initial_condition_dict = x0)\n", - " #now we are simulating over and over again, but only taking the final protein_GFP value\n", - " GFP_max = GFP_max.append({'hrpS_conc':conc_S,\n", - " 'hrpR_conc':conc_R,\n", - " 'GFP_max': Re1[\"protein_GFP\"].values[-1]}, ignore_index=True)\n", "\n", - " #now, you make a 2d plot with all the data\n", - " data = pd.pivot_table(data = GFP_max, index = 'hrpS_conc',\n", - " columns = 'hrpR_conc',\n", - " values = 'GFP_max')\n", + "if(make_heatmap):\n", + " #aggregator data frame\n", + " GFP_max = pd.DataFrame(columns = ['hrpS_conc', 'hrpR_conc', 'GFP_max'])\n", + " #Different initial values of R and S\n", + " conc_hrpR = np.linspace(0, 30, 9)\n", + " conc_hrpS = np.linspace(0, 30, 9)\n", "\n", - " ax = sns.heatmap(data,\n", - " cmap = 'viridis',\n", - " linewidths=.2)\n", - " ax.set_ylim(9,-0.5) #not sure why this is needed\n", "\n", - " ax.set(xlabel='hrpS', ylabel='hrpR')\n", - " ax.set_title(\"hrpR, hrpS Combinatorial Promoter Heatmap\")\n", - "except ModuleNotFoundError:\n", - " pass" + " for conc_R in conc_hrpR:\n", + " x0[\"protein_hrpR\"] = conc_R \n", + " for conc_S in conc_hrpS:\n", + " x0[\"protein_hrpS\"] = conc_S #Change my initial condition dictionary\n", + " Re1 = CRN_extract_1.simulate_with_bioscrape(timepoints, initial_condition_dict = x0)\n", + " #now we are simulating over and over again, but only taking the final protein_GFP value\n", + " GFP_max = GFP_max.append({'hrpS_conc':conc_S,\n", + " 'hrpR_conc':conc_R,\n", + " 'GFP_max': Re1[\"protein_GFP\"].values[-1]}, ignore_index=True)\n", + "\n", + " #now, you make a 2d plot with all the data\n", + " data = pd.pivot_table(data = GFP_max, index = 'hrpS_conc',\n", + " columns = 'hrpR_conc',\n", + " values = 'GFP_max')\n", + "\n", + " ax = sns.heatmap(data,\n", + " cmap = 'viridis',\n", + " linewidths=.2)\n", + " ax.set_ylim(9,-0.5) #not sure why this is needed\n", + "\n", + " ax.set(xlabel='hrpS', ylabel='hrpR')\n", + " ax.set_title(\"hrpR, hrpS Combinatorial Promoter Heatmap\")" ] }, { @@ -861,34 +875,21 @@ }, { "cell_type": "code", - "execution_count": 19, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "data": { - "image/png": "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\n", - "text/plain": [ - "
" - ] - }, - "metadata": { - "needs_background": "light" - }, - "output_type": "display_data" - } - ], + "outputs": [], "source": [ "newparam = {\n", - " ('phrpL_hrpR', 'cooperativity'): 1.0, \n", - " ('phrpL_hrpS', 'cooperativity'): 1.0, \n", - " ('phrpL_hrpR','ku'):3, #we have to massively decrease the unbinding rate to make this xor gate work\n", - " ('phrpL_hrpS','ku'):3,\n", - " #('phrpL_hrpR_hrpS_RNAP', 'ku'): 100, #this time, this one is leak\n", - " ('phrpL_hrpR_RNAP', 'ktx'): 0.17, #these are now transcribing at high rates!\n", - " ('phrpL_hrpS_RNAP', 'ktx'): 0.17,\n", - " ('phrpL_hrpS_RNAP', 'ku'): 11.,\n", - " ('phrpL_hrpR_RNAP', 'ku'): 11,\n", - " ('phrpL','ku'):100,\n", + " (None, 'phrpL_hrpR', 'cooperativity'): 1.0, \n", + " (None, 'phrpL_hrpS', 'cooperativity'): 1.0, \n", + " (None, 'phrpL_hrpR','ku'):3, #we have to massively decrease the unbinding rate to make this xor gate work\n", + " (None, 'phrpL_hrpS','ku'):3,\n", + " #(None, 'phrpL_hrpR_hrpS_RNAP', 'ku'): 100, #this time, this one is leak\n", + " (None, 'phrpL_hrpR_RNAP', 'ktx'): 0.17, #these are now transcribing at high rates!\n", + " (None, 'phrpL_hrpS_RNAP', 'ktx'): 0.17,\n", + " (None, 'phrpL_hrpS_RNAP', 'ku'): 11.,\n", + " (None, 'phrpL_hrpR_RNAP', 'ku'): 11,\n", + " (None, 'phrpL','ku'):100,\n", " \n", "}\n", "\n", @@ -900,40 +901,40 @@ "dna = DNAassembly(\"mydna\",promoter=phrpL,rbs=\"B0030\",protein=\"GFP\")\n", "\n", "extract_1_TXTL = TxTlExtract(name = \"e coli extract 1\", components = [dna,hrpR,hrpS], \\\n", - " parameters=parameters, parameter_file = \"default_parameters.txt\")\n", - "CRN_extract_1 = extract_1_TXTL.compile_crn()\n", + " parameters=parameters, parameter_file = \"default_parameters.txt\",\n", + " overwrite_parameters = True) #Overwrite parameters will overwrite the parameters in the file with the dictionary\n", "\n", - "try:\n", - " if(make_heatmap):\n", - " #aggregator data frame\n", - " GFP_max = pd.DataFrame(columns = ['hrpS_conc', 'hrpR_conc', 'GFP_max'])\n", - " #Different initial values of R and S\n", - " conc_hrpR = np.linspace(0,30, 9)\n", - " conc_hrpS = np.linspace(0, 30, 9)\n", - " for conc_R in conc_hrpR:\n", - " x0[\"protein_hrpR\"] = conc_R \n", - " for conc_S in conc_hrpS:\n", - " x0[\"protein_hrpS\"] = conc_S #Change my initial condition dictionary\n", - " Re1 = CRN_extract_1.simulate_with_bioscrape(timepoints, initial_condition_dict = x0)\n", - " #now we are simulating over and over again, but only taking the final protein_GFP value\n", - " GFP_max = GFP_max.append({'hrpS_conc':conc_S,\n", - " 'hrpR_conc':conc_R,\n", - " 'GFP_max': Re1[\"protein_GFP\"].values[-1]}, ignore_index=True)\n", + "CRN_extract_1 = extract_1_TXTL.compile_crn()\n", "\n", - " #now, you make a 2d plot with all the data\n", - " data = pd.pivot_table(data = GFP_max, index = 'hrpS_conc',\n", - " columns = 'hrpR_conc',\n", - " values = 'GFP_max')\n", "\n", - " ax = sns.heatmap(data,\n", - " cmap = 'viridis',\n", - " linewidths=.2)\n", - " ax.set_ylim(9,-0.5) #not sure why this is needed\n", - "\n", - " ax.set(xlabel='hrpS', ylabel='hrpR')\n", - " ax.set_title(\"hrpR, hrpS Combinatorial Promoter Heatmap\")\n", - "except ModuleNotFoundError:\n", - " pass" + "if(make_heatmap):\n", + " #aggregator data frame\n", + " GFP_max = pd.DataFrame(columns = ['hrpS_conc', 'hrpR_conc', 'GFP_max'])\n", + " #Different initial values of R and S\n", + " conc_hrpR = np.linspace(0,30, 9)\n", + " conc_hrpS = np.linspace(0, 30, 9)\n", + " for conc_R in conc_hrpR:\n", + " x0[\"protein_hrpR\"] = conc_R \n", + " for conc_S in conc_hrpS:\n", + " x0[\"protein_hrpS\"] = conc_S #Change my initial condition dictionary\n", + " Re1 = CRN_extract_1.simulate_with_bioscrape(timepoints, initial_condition_dict = x0)\n", + " #now we are simulating over and over again, but only taking the final protein_GFP value\n", + " GFP_max = GFP_max.append({'hrpS_conc':conc_S,\n", + " 'hrpR_conc':conc_R,\n", + " 'GFP_max': Re1[\"protein_GFP\"].values[-1]}, ignore_index=True)\n", + "\n", + " #now, you make a 2d plot with all the data\n", + " data = pd.pivot_table(data = GFP_max, index = 'hrpS_conc',\n", + " columns = 'hrpR_conc',\n", + " values = 'GFP_max')\n", + "\n", + " ax = sns.heatmap(data,\n", + " cmap = 'viridis',\n", + " linewidths=.2)\n", + " ax.set_ylim(9,-0.5) #not sure why this is needed\n", + "\n", + " ax.set(xlabel='hrpS', ylabel='hrpR')\n", + " ax.set_title(\"hrpR, hrpS Combinatorial Promoter Heatmap\")" ] }, { @@ -966,4 +967,4 @@ }, "nbformat": 4, "nbformat_minor": 2 -} +} \ No newline at end of file diff --git a/examples/Specialized Component Tutorials/MultiOccupancyTxTl_Demo.ipynb b/examples/Specialized Component Tutorials/MultiOccupancyTxTl_Demo.ipynb index f35d3077..ee0c579d 100644 --- a/examples/Specialized Component Tutorials/MultiOccupancyTxTl_Demo.ipynb +++ b/examples/Specialized Component Tutorials/MultiOccupancyTxTl_Demo.ipynb @@ -114,230 +114,142 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "## Example: T7 Polymerase Transcription of GFP mRNA" + "## Example: T7 Polymerase Transcription of GFP mRNA\n", + "\n", + "Now we define a DNA assembly that use our mechanism in the following steps:\n", + "- Create a species for the relevant polymerase\n", + "- Create multi_tx Mechanism, give a maximum occupancy and polymerase (must be species)\n", + "- Associate this mechanism with a promoter\n", + "- Place this promoter into a DNA assembly\n", + "\n", + "And voila, the cassette regulated by T7p is ready to use!\n", + "\n", + "This DNAassembly will be placed in a SimpleTxTlExtract which only dilutes mRNA, not proteins. I haven't used protein dilution as it makes it easier to glean the degree of sequestration present with this mechanism. In practical use, you would of course allow your polymerase to be diluted." ] }, { "cell_type": "code", - "execution_count": 1, + "execution_count": 7, "metadata": {}, "outputs": [ { - "name": "stderr", + "name": "stdout", "output_type": "stream", "text": [ - "C:\\Users\\mkratz\\Anaconda3\\lib\\site-packages\\biocrnpyler-0.2-py3.7.egg\\biocrnpyler\\__init__.py:36: UserWarning: No module named 'fa2'\n", - "C:\\Users\\mkratz\\Anaconda3\\lib\\site-packages\\biocrnpyler-0.2-py3.7.egg\\biocrnpyler\\__init__.py:37: UserWarning: plotting is disabled because you are missing some libraries\n" + "Species (26) = {0. dna[PFL] init_conc = 0, 1. complex[dna[PFL]:protein[T7p]] init_conc = 0, 2. complex[dna[PFL]:2x_protein[T7p]] init_conc = 0, 3. complex[dna[PFL]:3x_protein[T7p]] init_conc = 0, 4. complex[dna[PFL]:4x_protein[T7p]] init_conc = 0, 5. complex[dna[PFL]:5x_protein[T7p]] init_conc = 0, 6. complex[dna[PFL]:6x_protein[T7p]] init_conc = 0, 7. complex[dna[PFL]:7x_protein[T7p]] init_conc = 0, 8. complex[dna[PFL]:8x_protein[T7p]] init_conc = 0, 9. complex[dna[PFL]:9x_protein[T7p]] init_conc = 0, 10. complex[dna[PFL]:10x_protein[T7p]] init_conc = 0, 11. complex[dna[PFL]:protein[T7p](closed)] init_conc = 0, 12. complex[dna[PFL]:2x_protein[T7p](closed)] init_conc = 0, 13. complex[dna[PFL]:3x_protein[T7p](closed)] init_conc = 0, 14. complex[dna[PFL]:4x_protein[T7p](closed)] init_conc = 0, 15. complex[dna[PFL]:5x_protein[T7p](closed)] init_conc = 0, 16. complex[dna[PFL]:6x_protein[T7p](closed)] init_conc = 0, 17. complex[dna[PFL]:7x_protein[T7p](closed)] init_conc = 0, 18. complex[dna[PFL]:8x_protein[T7p](closed)] init_conc = 0, 19. complex[dna[PFL]:9x_protein[T7p](closed)] init_conc = 0, 20. complex[dna[PFL]:10x_protein[T7p](closed)] init_conc = 0, 21. protein[T7p] init_conc = 0, 22. rna[PFL] init_conc = 0, 23. protein[GFP] init_conc = 0, 24. dna[T7_const] init_conc = 0, 25. rna[T7_const] init_conc = 0}\n", + "\n", + "Reactions (48) = [\n", + "0. protein[T7p]+complex[dna[PFL]:protein[T7p]] <--> complex[dna[PFL]:2x_protein[T7p](closed)]\n", + "1. protein[T7p]+complex[dna[PFL]:2x_protein[T7p]] <--> complex[dna[PFL]:3x_protein[T7p](closed)]\n", + "2. protein[T7p]+complex[dna[PFL]:3x_protein[T7p]] <--> complex[dna[PFL]:4x_protein[T7p](closed)]\n", + "3. protein[T7p]+complex[dna[PFL]:4x_protein[T7p]] <--> complex[dna[PFL]:5x_protein[T7p](closed)]\n", + "4. protein[T7p]+complex[dna[PFL]:5x_protein[T7p]] <--> complex[dna[PFL]:6x_protein[T7p](closed)]\n", + "5. protein[T7p]+complex[dna[PFL]:6x_protein[T7p]] <--> complex[dna[PFL]:7x_protein[T7p](closed)]\n", + "6. protein[T7p]+complex[dna[PFL]:7x_protein[T7p]] <--> complex[dna[PFL]:8x_protein[T7p](closed)]\n", + "7. protein[T7p]+complex[dna[PFL]:8x_protein[T7p]] <--> complex[dna[PFL]:9x_protein[T7p](closed)]\n", + "8. protein[T7p]+complex[dna[PFL]:9x_protein[T7p]] <--> complex[dna[PFL]:10x_protein[T7p](closed)]\n", + "9. complex[dna[PFL]:protein[T7p](closed)] --> complex[dna[PFL]:protein[T7p]]\n", + "10. complex[dna[PFL]:2x_protein[T7p](closed)] --> complex[dna[PFL]:2x_protein[T7p]]\n", + "11. complex[dna[PFL]:3x_protein[T7p](closed)] --> complex[dna[PFL]:3x_protein[T7p]]\n", + "12. complex[dna[PFL]:4x_protein[T7p](closed)] --> complex[dna[PFL]:4x_protein[T7p]]\n", + "13. complex[dna[PFL]:5x_protein[T7p](closed)] --> complex[dna[PFL]:5x_protein[T7p]]\n", + "14. complex[dna[PFL]:6x_protein[T7p](closed)] --> complex[dna[PFL]:6x_protein[T7p]]\n", + "15. complex[dna[PFL]:7x_protein[T7p](closed)] --> complex[dna[PFL]:7x_protein[T7p]]\n", + "16. complex[dna[PFL]:8x_protein[T7p](closed)] --> complex[dna[PFL]:8x_protein[T7p]]\n", + "17. complex[dna[PFL]:9x_protein[T7p](closed)] --> complex[dna[PFL]:9x_protein[T7p]]\n", + "18. complex[dna[PFL]:10x_protein[T7p](closed)] --> complex[dna[PFL]:10x_protein[T7p]]\n", + "19. complex[dna[PFL]:protein[T7p]] --> protein[T7p]+rna[PFL]+dna[PFL]\n", + "20. complex[dna[PFL]:2x_protein[T7p]] --> 2protein[T7p]+2rna[PFL]+dna[PFL]\n", + "21. complex[dna[PFL]:3x_protein[T7p]] --> 3protein[T7p]+3rna[PFL]+dna[PFL]\n", + "22. complex[dna[PFL]:4x_protein[T7p]] --> 4protein[T7p]+4rna[PFL]+dna[PFL]\n", + "23. complex[dna[PFL]:5x_protein[T7p]] --> 5protein[T7p]+5rna[PFL]+dna[PFL]\n", + "24. complex[dna[PFL]:6x_protein[T7p]] --> 6protein[T7p]+6rna[PFL]+dna[PFL]\n", + "25. complex[dna[PFL]:7x_protein[T7p]] --> 7protein[T7p]+7rna[PFL]+dna[PFL]\n", + "26. complex[dna[PFL]:8x_protein[T7p]] --> 8protein[T7p]+8rna[PFL]+dna[PFL]\n", + "27. complex[dna[PFL]:9x_protein[T7p]] --> 9protein[T7p]+9rna[PFL]+dna[PFL]\n", + "28. complex[dna[PFL]:10x_protein[T7p]] --> 10protein[T7p]+10rna[PFL]+dna[PFL]\n", + "29. complex[dna[PFL]:2x_protein[T7p](closed)] --> protein[T7p]+rna[PFL]+complex[dna[PFL]:protein[T7p](closed)]\n", + "30. complex[dna[PFL]:3x_protein[T7p](closed)] --> 2protein[T7p]+2rna[PFL]+complex[dna[PFL]:protein[T7p](closed)]\n", + "31. complex[dna[PFL]:4x_protein[T7p](closed)] --> 3protein[T7p]+3rna[PFL]+complex[dna[PFL]:protein[T7p](closed)]\n", + "32. complex[dna[PFL]:5x_protein[T7p](closed)] --> 4protein[T7p]+4rna[PFL]+complex[dna[PFL]:protein[T7p](closed)]\n", + "33. complex[dna[PFL]:6x_protein[T7p](closed)] --> 5protein[T7p]+5rna[PFL]+complex[dna[PFL]:protein[T7p](closed)]\n", + "34. complex[dna[PFL]:7x_protein[T7p](closed)] --> 6protein[T7p]+6rna[PFL]+complex[dna[PFL]:protein[T7p](closed)]\n", + "35. complex[dna[PFL]:8x_protein[T7p](closed)] --> 7protein[T7p]+7rna[PFL]+complex[dna[PFL]:protein[T7p](closed)]\n", + "36. complex[dna[PFL]:9x_protein[T7p](closed)] --> 8protein[T7p]+8rna[PFL]+complex[dna[PFL]:protein[T7p](closed)]\n", + "37. complex[dna[PFL]:10x_protein[T7p](closed)] --> 9protein[T7p]+9rna[PFL]+complex[dna[PFL]:protein[T7p](closed)]\n", + "38. dna[PFL]+protein[T7p] <--> complex[dna[PFL]:protein[T7p](closed)]\n", + "39. rna[PFL] --> rna[PFL]+protein[GFP]\n", + "40. dna[T7_const] --> dna[T7_const]+rna[T7_const]\n", + "41. rna[T7_const] --> rna[T7_const]+protein[T7p]\n", + "42. protein[T7p] --> \n", + "43. rna[PFL] --> \n", + "44. protein[GFP] --> \n", + "45. rna[T7_const] --> \n", + "46. rna[PFL] --> \n", + "47. rna[T7_const] --> \n", + "]\n", + "[DNAassembly: PFL\n", + "\tPromoter: pT7\n", + "\ttranscript = rna_PFL\n", + "\tRBS: weak\n", + "\tprotein = protein_GFP, DNAassembly: T7_const\n", + "\tPromoter: weak\n", + "\ttranscript = rna_T7_const\n", + "\tRBS: weak\n", + "\tprotein = protein_T7p]\n" ] } ], "source": [ "from biocrnpyler import *\n", "\n", - "class multi_tx(Mechanism):\n", - " '''\n", - " Multi-RNAp Transcription w/ Isomerization:\n", - " Detailed transcription mechanism accounting for each individual \n", - " RNAp occupancy states of gene.\n", - " \n", - " n ={0, max_occ}\n", - " DNA:RNAp_n + RNAp <--> DNA:RNAp_n_c --> DNA:RNAp_n+1\n", - " DNA:RNAp_n --> DNA:RNAp_0 + n RNAp + n mRNA\n", - " DNA:RNAp_n_c --> DNA:RNAp_0_c + n RNAp + n mRNA\n", - " \n", - " n --> number of open configuration RNAp on DNA\n", - " max_occ --> Physical maximum number of RNAp on DNA (based on RNAp and DNA dimensions)\n", - " DNA:RNAp_n --> DNA with n open configuration RNAp on it\n", - " DNA:RNAp_n_c --> DNA with n open configuration RNAp and 1 closed configuration RNAp on it\n", - " \n", - " For more details, see examples/MultiTX_Demo.ipynb\n", - " '''\n", - " \n", - " # initialize mechanism subclass\n", - " def __init__(self, pol, name='multi_tx', mechanism_type='transcription', **keywords):\n", - "\n", - " if isinstance(pol,str):\n", - " self.pol = Species(name=pol, material_type='protein')\n", - " \n", - " elif isinstance(pol,Species):\n", - " self.pol = pol\n", - " \n", - " else:\n", - " raise ValueError(\"'pol' must be a string or Species\")\n", - " \n", - " \n", - " Mechanism.__init__(self, name=name, mechanism_type=mechanism_type, **keywords)\n", - " \n", - " # species update\n", - " def update_species(self, dna, transcript, component, part_id, **keywords):\n", - " max_occ = int(component.get_parameter(\"max_occ\", part_id = part_id, mechanism = self))\n", - " cp_open = []\n", - " cp_closed = []\n", - " for n in range(1,max_occ + 1):\n", - " name_open = self.pol.name + 'x' + dna.name + '_' + str(n)\n", - " cp_open.append(ComplexSpecies([dna]+[self.pol for i in range(n)],name=name_open))\n", - " if n > 1:\n", - " name_closed = self.pol.name + 'x' + dna.name + '_closed' + '_' + str(n-1)\n", - " cp_closed.append(ComplexSpecies([dna]+[self.pol for i in range(n-1)],name=name_closed))\n", - " else:\n", - " name_closed = self.pol.name + 'x' + dna.name + '_closed' + '_' + str(0)\n", - " cp_closed.append(ComplexSpecies([dna]+[self.pol for i in range(1)],name=name_closed))\n", - " \n", - " cp_misc = [self.pol,dna,transcript]\n", - " \n", - " \n", - " return cp_open + cp_closed + cp_misc\n", - " \n", - " def update_reactions(self, dna, transcript, component, part_id, **keywords):\n", - " \n", - " '''\n", - " DNA:RNAp_n + RNAp <--> DNA:RNAp_n_c --> DNA:RNAp_n+1\n", - " kf1 = k1, kr1 = k2, kf2 = k_iso\n", - " DNA:RNAp_n --> DNA:RNAp_0 + n RNAp + n mRNA\n", - " kf = ktx_solo\n", - " DNA:RNAp_n_c --> DNA:RNAp_0_c + n RNAp + n mRNA\n", - " kf = ktx_solo\n", - " \n", - " max_occ = maximum occupancy of gene (physical limit)\n", - " '''\n", - " \n", - " # parameter loading\n", - " k1 = component.get_parameter(\"k1\", part_id = part_id, mechanism = self)\n", - " k2 = component.get_parameter(\"k2\", part_id = part_id, mechanism = self)\n", - " k_iso = component.get_parameter(\"k_iso\", part_id = part_id, mechanism = self)\n", - " ktx_solo = component.get_parameter(\"ktx_solo\", part_id = part_id, mechanism = self)\n", - " max_occ = int(component.get_parameter(\"max_occ\", part_id = part_id, mechanism = self))\n", - " \n", - " # complex species instantiation\n", - " cp_open = []\n", - " cp_closed = []\n", - " for n in range(1,max_occ + 1):\n", - " name_open = self.pol.name + 'x' + dna.name + '_' + str(n)\n", - " cp_open.append(ComplexSpecies([dna]+[self.pol for i in range(n)],name=name_open))\n", - " if n > 1:\n", - " name_closed = self.pol.name + 'x' + dna.name + '_closed' + '_' + str(n-1)\n", - " cp_closed.append(ComplexSpecies([dna]+[self.pol for i in range(n-1)],name=name_closed))\n", - " else:\n", - " name_closed = self.pol.name + 'x' + dna.name + '_closed' + '_' + str(0)\n", - " cp_closed.append(ComplexSpecies([dna]+[self.pol for i in range(1)],name=name_closed))\n", - " \n", - " \n", - " # Reactions\n", - " # polymerase + complex(n) --> complex(n_closed)\n", - " rxn_open_pf = [Reaction(inputs=[self.pol, cp_open[n]], outputs=[cp_closed[n+1]], k=k1) for n in range(0,max_occ-1)]\n", - " rxn_open_pr = [Reaction(inputs=[cp_closed[n+1]], outputs=[self.pol, cp_open[n],], k=k2) for n in range(0,max_occ-1)]\n", - " \n", - " # isomerization\n", - " rxn_iso = [Reaction(inputs=[cp_closed[n]], outputs=[cp_open[n]], k=k_iso) for n in range(0,max_occ)]\n", - " \n", - " # release/transcription from open and closed states\n", - " rxn_release_open = []\n", - " rxn_release_closed = []\n", - " for n in range(0,max_occ):\n", - " rxn_temp1 = Reaction(inputs= [cp_open[n]], outputs=[self.pol for i in range(n+1)] + \n", - " [transcript for i in range(n+1)] + [dna], k=ktx_solo)\n", - " rxn_release_open.append(rxn_temp1)\n", - " \n", - " for n in range(1,max_occ):\n", - " rxn_temp2 = Reaction(inputs= [cp_closed[n]], outputs=[self.pol for i in range(n)] + \n", - " [transcript for i in range(n)] + [cp_closed[0]], k=ktx_solo)\n", - " rxn_release_closed.append(rxn_temp2)\n", - " \n", - " # missing reactions (0 --> 0_closed and v.v. 0_closed --> 0)\n", - " rxn_m1 = Reaction(inputs=[dna,self.pol], outputs=[cp_closed[0]], k=k1)\n", - " rxn_m2 = Reaction(inputs=[cp_closed[0]], outputs=[dna,self.pol], k=k2)\n", - " \n", - " rxn_all = rxn_open_pf + rxn_open_pr + rxn_iso + rxn_release_open + rxn_release_closed + [rxn_m1, rxn_m2]\n", - " \n", - " return rxn_all" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "First we define a dilution mixture class, a mixture based of ExpressionExtract which adds dilution and degredation interactions to RNA species, respectively. I haven't added this for proteins as it makes it easier to glean the degree of sequestration present with this mechanism. In practical use, you would of course allow your polymerase to be diluted." - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "metadata": {}, - "outputs": [], - "source": [ - "class DilutionMixture(Mixture):\n", - " def __init__(self, name=\"\", **keywords):\n", - " \n", - " simple_transcription = SimpleTranscription() #Transcription will not involve machinery\n", - " simple_translation = SimpleTranslation()\n", - " \n", - " default_mechanisms = {\n", - " \"transcription\": simple_transcription, #This will be overwritten by the NegativeHillPromotor\n", - " \"translation\": simple_translation\n", - " }\n", - " \n", - " #By Default Species are diluted S-->0 Unless:\n", - " # They are of type 'dna'\n", - " # They have the attribute 'machinery'\n", - " dilution_mechanism = Dilution(filter_dict = {\"dna\":False,'protein':False,'complex':False}, default_on = True)\n", - " dilution_mrn = Dilution(name = \"rna_degredation\", filter_dict = {\"rna\":True}, default_on = False)\n", - "\n", - " #Add this mechanism to a dictionary which is passed into the Mixture txtl.TxTlExtract\n", - " global_mechanisms = {\"dilution\":dilution_mechanism, \"rna_degredation\":dilution_mrn}\n", - " \n", - " #Always call the superclass __init__ with **keywords\n", - " Mixture.__init__(self, name=name, default_mechanisms=default_mechanisms, global_mechanisms = global_mechanisms, **keywords)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Now we define a DNA assembly that use our mechanism in the following steps:\n", - "- Create a species for the relevant polymerase\n", - "- Create multi_tx object, give a maximum occupancy and polymerase (must be species or str)\n", - "- Associate this mechanism with a promoter\n", - "- Place this promoter into a DNA assembly\n", + "#the most important parameters for multi_tx\n", + "#max_occ is the number of ribosomes that can bind to a transcript\n", + "#k_iso is the rate of isomerization\n", + "parameters = {\"max_occ\":10, \"k_iso\":10}\n", "\n", - "And voila, the cassette regulated by T7p is ready to use!" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "metadata": {}, - "outputs": [], - "source": [ "# Define Polymerase, and max occupancy and instatiate Mechanism Object\n", "T7P = Species('T7p','protein')\n", + "#Multi-tx mechanism\n", "MX = multi_tx(pol=T7P,name='MX')\n", "\n", "# create promoter object, associated MX and params with it\n", - "pT7 = Promoter(name='pT7',mechanisms={'transcription':MX})\n", + "pT7_mx = Promoter(name='pT7',mechanisms={'transcription':MX})\n", "\n", - "# place promoter object into DNA assembly\n", - "PFL = DNAassembly('PFL',dna=Species('T7',material_type='dna'),promoter=pT7,transcript='GFP')\n", + "# place promoter object into DNA assembly with GFP reporter\n", + "GFP = Species(\"GFP\", material_type = \"protein\")\n", + "PFL_mx = DNAassembly('PFL', promoter=pT7_mx, rbs = \"weak\", protein=GFP)\n", "\n", - "# create simple promoter and DNA assembly objects that synthesize polymerase, uncomment if you want\n", - "# a constant source of T7p\n", - "# pJ = Promoter('J23107',mechanisms={'transcription':OneStepGeneExpression()})\n", - "# SC = DNAassembly('SCF',dna='T7_source',promoter=pJ,protein=T7P)\n", - "# Test_EX = DilutionMixture(components=[PFL,SC],parameter_file = \"default_parameters.txt\")\n", - "# CRN = Test_EX.compile_crn()\n", + "# create simple promoter and DNA assembly objects that synthesize polymerase\n", + "SC = DNAassembly('T7_const', promoter=\"weak\", rbs = \"weak\", protein=T7P)\n", "\n", "# make extract with T7p source and GFP and compile CRN \n", - "Test_EX = DilutionMixture(components=[PFL],parameter_file = \"default_parameters.txt\")\n", - "CRN1 = Test_EX.compile_crn()" + "mixture = SimpleTxTlDilutionMixture(components=[PFL_mx, SC], parameter_file = \"default_parameters.txt\", parameters = parameters)\n", + "\n", + "CRN1 = mixture.compile_crn()\n", + "\n", + "print(CRN1.pretty_print(show_rates = False))\n", + "print(mixture.components)" ] }, { "cell_type": "code", - "execution_count": 4, + "execution_count": 2, "metadata": {}, "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "C:\\ProgramData\\Anaconda3\\lib\\site-packages\\html5lib\\_trie\\_base.py:3: DeprecationWarning: Using or importing the ABCs from 'collections' instead of from 'collections.abc' is deprecated, and in 3.8 it will stop working\n", + " from collections import Mapping\n", + "C:\\ProgramData\\Anaconda3\\lib\\importlib\\_bootstrap.py:219: RuntimeWarning: numpy.ufunc size changed, may indicate binary incompatibility. Expected 192 from C header, got 216 from PyObject\n", + " return f(*args, **kwds)\n" + ] + }, { "data": { - "image/png": "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773Hu+++y3vvvcd7773H+++/X0pA1N2XP667nz9/ftEfoU1169aNVVZZhZ49e7LKKqt84tbc8R49etCjRw+6d+++3Pum9jX1nA022KBdvouOmrT4C9A/IrYE3gKOBI4qIpAOULUjSZIkSe1m4cKFzJo1q96tYTKi7lY3Nm/evKLD/oSIYI011qBXr16sscYarLbaaqy22mqsuuqq9e4bG2tqX93jVVddtZRkKE829OjRg27duhX98atGh0xapJSWRsQpwCNAN+DmlNLL7fX+UVZoYc5CkiRJUmf34YcfMmPGDGbMmFFKRMycObPRxx988EEhMa655pqsvfbarL322qy11lqsvfbarLnmmvTq1auUeKi7L3+8vLFVV12VCKvsi9YhkxYAKaXxwPgi3tv/bCVJkiR1BrW1tcycOZO33nqLt956ixkzZpQel2/PnTu3onHU1NTQu3dv+vTpU+/Wu3fvekmI5T1ec801qampqWiMKkaHTVpUi47Q1VWSJElS17Ro0SLeeOMNpk2bxr/+9a9699OmTWP69OksW9a2KyJ269aN9ddfn/XXX58NNtiAvn37st5669VLRqy77rr1ttdee22TDmqUSYuWsERIkiRJUhVIKfHOO+8wZcqU0u21114rJSfefvvtNnmfHj16sPHGG7PxxhuzwQYbsMEGG9RLTJQ/XmeddUxAqM2YtGgl6ywkSZIkVdp7773H5MmTmTJlClOnTi0lKKZOndrqqRt9+/Zl4403ZpNNNmGTTTYpPS4fW3fddU1EqBAmLVrAOgtJkiRJlfDuu+/y8ssv88orr9S7nzlzZoter6amhk022YR+/fqxxRZbfOJ+s802Y9VVV23jTyG1HZMWrWRLC0mSJEkra8GCBUyaNIkXXniBF198sZScmDVr1kq/1hprrEH//v1Lt6222oott9ySfv36semmm9KjR48KfAKpfZi0aAFbWkiSJElqrnfffZcXXnihdHv++ed59dVXqa2tbfZrrLrqqmyzzTalxMTWW29derzBBhu4NKc6LZMWrWaphSRJkqTMhx9+yHPPPcfEiROZOHEizzzzDG+++Wazn7/aaqux3Xbbsf3227PDDjuU7vv160e3bt0qGLlUnUxatIA5TEmSJEnLli3j73//eylBMXHiRCZNmtSsCoqIoH///uy8887svPPOfOYzn2H77benX79+NryUypi0aCV7WkiSJEldw5IlS3juueeYMGECEyZM4E9/+lOzVu7o2bMnn/nMZ0oJis997nPstNNO9OrVqx2iljo2kxYt4HwxSZIkqfNbsGABEydOLCUpnnrqKT766KMmnxMRbL/99uy6666l2/bbb28zTKmFTFq0koUWkiRJUuewbNkyXnjhBR577DEeffRR/vSnP7F48eImn7PBBhuw2267lRIUAwYMYK211mqniKXOz6RFC1hnIUmSJHUO06dPLyUpHn/8cd55550mj99yyy3ZY489+PKXv8wee+zBpz71KSuxpQoyadFK9rSQJEmSOo5ly5bxzDPPMHbsWH79618zadKkJo/fdtttSwmK3Xffnc0226ydIpUEJi1axESqJEmS1HF8+OGHPPbYY4wdO5Zx48Yxa9as5R7bt29f9t1339Jtk002acdIJTVk0qKVkqUWkiRJUtWZM2cODz30EPfddx+PP/44ixYtavS4nj17svvuu7Pvvvvy1a9+lZ122sklR6UqYtKiBcKuFpIkSVLVmTNnDmPHjuXee+/l0UcfZcmSJY0et/766/O1r32Ngw8+mK985SusscYa7RyppOYyadFK1llIkiRJxfnwww958MEHueeee3jkkUeWu9rHjjvuyMEHH8xBBx3EF7/4RasppA7CpEVLlBVaODtEkiRJal/Lli1jwoQJ3Hbbbdx///3Mnz+/0eMGDBjAN7/5TQ477DA+9alPtXOUktqCSQtJkiRJHcKUKVO4/fbbGTNmDNOmTWv0mF122YXDDz/cRIXUSZi0aIHyjhbJCSKSJElSxSxatIgHHniA6667jieffLLRY7bZZhsGDx7MkUceaaJC6mRMWrSAS55KkiRJlTV16lRGjx7NLbfcwjvvvPOJ/X369GHQoEEMHjyYL3zhC4QX6VKnZNKitSy0kCRJktpEbW0tY8eO5ec//zmPPfbYJ/Z3796dAw88kGOPPZYDDjiAnj17FhClpPZk0qIFXPJUkiRJajvz5s3j5ptvZtSoUbz++uuf2L/55pszdOhQjj/+eDbaaKMCIpRUFJMWrWShhSRJktQy06ZN46qrruKGG27ggw8+qLevpqaGAw88kGHDhjFw4EC6detWUJSSimTSogWcLidJkiS13AsvvMCll17K/fffT21tbb19ffr04cQTT2TYsGFsvvnmBUUoqVqYtGilZKmFJEmS1CwTJ07koosu4je/+c0n9m2zzTYMHz6cwYMHs/rqqxcQnaRqZNKiBay0kCRJkppvwoQJXHTRRY0219x7770588wz2X///ampqSkgOknVzKRFKyW7WkiSJEmNmjBhAj/84Q+ZMGFCvfGI4L//+78ZMWIEn/vc5wqKTlJHYNKiBVw9RJIkSVq+559/nhEjRvDwww/XG6+pqWHQoEGMGDGC7bffvqDoJHUkJi1ayZ4WkiRJUmbKlCn88Ic/5J577qk33r17dwYPHsw555zD1ltvXVB0kjoikxYtYE8LSZIk6WMzZ87kvPPO48Ybb6y3GkhEMHjwYM4//3z69etXXICSOiyTFq1koYUkSZK6qkWLFjFq1Cguuugi5s2bV2/fN77xDS666CJ22GGHgqKT1BmYtJAkSZK0UlJKjB07lu9973u89tpr9fbttdde/PjHP2a33XYrKDpJnYlJi1ZKNrWQJElSF/Lyyy8zfPhwHn/88Xrj2267LVdccQUDBw4knE8tqY24EHIL+JewJEmSupqPPvqIs88+m5133rlewmKdddZh1KhRvPTSS+y///5eK0tqU1ZatJJ1FpIkSersxo8fz3e/+13+9a9/lcZqamo46aSTuOCCC1h33XWLC05Sp2bSogXMHUuSJKkrmDFjBqeffjr3339/vfHdd9+da6+9lh133LGgyCR1FU4PaS1LLSRJktTJpJS48cYb2W677eolLPr06cNNN93EH//4RxMWktqFlRYtUD5NL5m1kCRJUicyffp0vv3tb/PII4/UGz/22GMZOXIkffv2LSgySV2RSYsWcHqIJEmSOpuUErfddhvDhw9n7ty5pfH+/fszevRo9txzz+KCk9RlOT2klVzxVJIkSR3dv//9bw466CCOO+64UsIiIjjjjDN48cUXTVhIKoyVFi3gMk6SJEnqLMaPH8+QIUOYPXt2aWyrrbbilltuYffddy8wMkmy0qLVrLSQJElSR7Ro0SKGDx/OgQceWC9hceqpp/Liiy+asJBUFay0aAHrLCRJktSRvfrqqwwaNIgXXnihNLbRRhsxZswY9tlnnwIjk6T6rLRoJQstJEmS1JHceuut7LLLLvUSFl/72td46aWXTFhIqjomLVrAlhaSJEnqaBYuXMiwYcM47rjj+OijjwDo2bMnV111FWPHjmW99dYrOEJJ+iSnh7RS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\n", + "image/png": "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\n", "text/plain": [ "
" ] @@ -349,28 +261,29 @@ } ], "source": [ - "import numpy as np\n", - "import matplotlib.pyplot as plt\n", + "try:\n", + " import numpy as np\n", + " import matplotlib.pyplot as plt\n", "\n", - "ts = np.arange(0,2000,1)\n", - "x0_dict = {repr(T7P):10000,repr(PFL.dna):1}\n", + " ts = np.arange(0,5000,1)\n", "\n", - "# Do not use simulate_with_bioscrape_via_sbml, not working at time of writing (5/31/2020) because of a bug related to sbml model writing \n", - "try:\n", - " R1= CRN1.simulate_with_bioscrape(ts, initial_condition_dict = x0_dict, stochastic = False,)\n", - "\n", - " fig, ax = plt.subplots(1,2,figsize=(18,8))\n", - " ax[0].set_title('Polymerase Levels',pad=20,fontdict={'fontsize':18})\n", - " ax[0].plot(R1['protein_T7p'],linewidth=3)\n", - " ax[0].set_xlabel('Time (sec)',labelpad=15,fontdict={'fontsize':14})\n", - " ax[0].set_ylabel('Polymerase Count',labelpad=15,fontdict={'fontsize':14})\n", - "\n", - " ax[1].set_title('Transcript Levels',pad=20,fontdict={'fontsize':18})\n", - " ax[1].plot(R1['rna_GFP'],linewidth=3,c='k')\n", - " ax[1].set_xlabel('Time (sec)',labelpad=15,fontdict={'fontsize':14})\n", - " ax[1].set_ylabel('Transcript Count',labelpad=15,fontdict={'fontsize':14})\n", + " x0_dict = {repr(PFL_mx.dna):1.,repr(SC.dna):.1}\n", + "\n", + " R1 = CRN1.simulate_with_bioscrape_via_sbml(ts, initial_condition_dict = x0_dict, stochastic = False)\n", + " if R1 is not None:\n", + " fig, ax = plt.subplots(1,2,figsize=(18,8))\n", + " ax[0].set_title('Polymerase Levels',pad=20,fontdict={'fontsize':18})\n", + " ax[0].plot(R1[str(T7P)],linewidth=3)\n", + " ax[0].set_xlabel('Time (sec)',labelpad=15,fontdict={'fontsize':14})\n", + " ax[0].set_ylabel('Polymerase Count',labelpad=15,fontdict={'fontsize':14})\n", + "\n", + " ax[1].set_title('GFP Levels',pad=20,fontdict={'fontsize':18})\n", + " ax[1].plot(R1[str(GFP)],linewidth=3,c='k')\n", + " ax[1].set_xlabel('Time (sec)',labelpad=15,fontdict={'fontsize':14})\n", + " ax[1].set_ylabel('[GFP]',labelpad=15,fontdict={'fontsize':14})\n", "except ModuleNotFoundError:\n", - " pass" + " print('please install the plotting libraries: pip install biocrnpyler[all]')\n", + "\n" ] }, { @@ -389,21 +302,23 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": 3, "metadata": {}, "outputs": [], "source": [ "# place promoter object into DNA assembly\n", - "PFL = DNAassembly('PFL',dna='T7',promoter='pT7',transcript='GFP')\n", + "mech_default = Transcription_MM(rnap=T7P,name='MX')\n", + "pT7 = Promoter(\"pT7\", mechanisms = [mech_default])\n", + "PFL_default = DNAassembly('PFL',dna='T7',promoter=pT7,rbs = \"weak\", protein = GFP)\n", "\n", "# make extract with T7p source and GFP and compile CRN \n", - "Test_EX = DilutionMixture(components=[PFL],parameter_file = \"default_parameters.txt\")\n", + "Test_EX = SimpleTxTlDilutionMixture(components=[PFL_default, SC],parameter_file = \"default_parameters.txt\")\n", "CRN2 = Test_EX.compile_crn()" ] }, { "cell_type": "code", - "execution_count": 6, + "execution_count": 4, "metadata": {}, "outputs": [ { @@ -413,14 +328,14 @@ "\n", " \n", "\n", - "MX Model predicts 119.0 transcripts and RPU Model predicts 109.0 transcripts at SS \n", + "MX Model predicts 49121.0 GFP and RPU Model predicts 24740.0 GFP at SS \n", " \n", "\n" ] }, { "data": { - "image/png": "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eDh//PEHQUFBXuuLFClCnz59ePbZZyldujRVq1bl9ddf5+DBg/Tt2xeA3r17M2HCBPr370/fvn3ZvHkz06ZN87jP4MGDadKkCb179+axxx4jPDycbdu28dFHH3msnyfZ68SJEyxatIh3332X1atXe21TokQJOnToQMeOHbn11lsJDQ3N5ijFH6x1EqqjR5OTsqTj+PG0Zanrc/owojEQFuYchQpB4cKe56woK1jQM/FK+TooKLCT8iTnUTKXDwwcOJBu3boxePBgqlSpkmn74OBgPvvsM55//nkefvhhDh06RGRkJP369UszkzQzmQ3Jjh8/HoBu3bpx/Phx6tWrx4oVK9w9gpUrV+aDDz5g4MCBvP322zRo0IBx48bxyCOPuO9Rt25dVq9ezQsvvECLFi1ISEigWrVqdOjQ4YJilUuXmJjI559/zuzZs/nwww/dk3BSCg8P59577+X+++/ntttuUwKXC5w7B0eOJB+HD3uevZVl0eT4S1KoEBQr5hzh4VCkSNojLMx7eUZtCxdWMiU5i/HlmaS8qGHDhja9nQy2bt1KrVq1sjkiySn0+79w+/fvZ/bs2URHRxMbG5umPigoiFatWhEVFUW7du3STIaR7BcfD4cOwZ9/OseBA8mvUx6HDjlDltkpLAxKlICSJZ1zeLhnUpb0OqPr8HBnSE8krzDGbLDWNvRWp545EbkoCQkJrFy5kunTp7N8+XISvIyNXXfddURFRfHggw9q0d5skpjo9I7t2+cce/c656RkLel85Ih/J3YVKQIREU5Clt6RlLClLtPjkiIXRsmciFyQQ4cOMX36dKZPn87evXvT1EdERNClSxe6devGNddcE4AI8y5rnUTt99/TJmtJr//4wxkWzUoFCkDp0s5Rpkza16nLSpVyetdEJHsomRMRn2zcuJGJEycSExPDWS9rM7Rs2ZJevXrRoUMHChUqFIAI84YTJ2D3bu9HbKyzfEZWMMZJvMqXT3tUqOCcy5VzjhIlNPNQJCdTMici6YqPj+fDDz9k4sSJ/Oc//0lTX7p0abp160bPnj258sorAxBh7mOtM8y5fTvs2OGcd+1KTtb++uvSP6NECbj8crjssuRzxYrJSVr58k4ip2fKRPIGJXPpSLmumeQf+XVCUGp///03M2bMYOLEiV53Zrj++ut58sknue+++7QeXDqOHfNM2FKeT526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\n", + "image/png": "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7ty5hISEsHbtWuLi4ggODs7Ue2vVqkW9evWYP38+P/30E126dCEkJMSnz6+//kp8fDyNGzf2tgUEBNCoUSO2bt0KwLZt22jYsKHPb3ONGjXyOc66deuIiYlhwYIF3rbks6a//vqrwp+IuCI2NpYDBw5w4MAB9u/f733dv38/Bw8e9Al48fHx2V5PYGAgpUuXplSpUt7XkiVLpglyGYW7ggUVNfyN/otkE3+/xiG1nj178uijj1K0aFFeeOGFqzrWP/7xDzZt2sTatWtp2bIlo0aNYtKkSZdVy/Tp09m5cycrVqxIsz/5zza90/TJbZn5809KSqJ3794MGTIkzb6wsHSf9icicsXi4+PZt28f+/bt84a59ALe8ePHs+XzjTHeAJe8pAx0KV9TrhcpUiTfDYvmdQp/AsAdd9xBUFAQhw8fpn379ld8nJ9//plRo0Yxe/ZsateuzZw5c2jTpg333Xefz5m6i+ncuTORkZGEh4fToEGDNPurV69OUFAQ3377LdWqVQOceZq+//57HnroIQBq167NokWLsNZ6f2itWbPG5zg33ngjW7ZsoXr16lf8fUVEwPmF89ChQ+zZs4fff/893dcDBw5k+YmB0NBQypUrl6mldOnSBAQEZOnnS+6k8CeA8xvhpk2bsNZSqFChKzpGQkIC3bp1o02bNnTt2hWAFi1a0Lt3b3r06MFPP/2UZgg3PaGhoezbty/DH1JFihRhwIABjBgxgjJlylC1alWmTJnCwYMHGThwIAD9+/dn0qRJREZGMnDgQDZv3szMmTN9jjN8+HAaNmxI//796devH6Ghofz8888sXbqUN99884r+DEQkb0pKSmL//v3s3LmTXbt2sXPnTnbv3u0Nd3v37uXcuXNZ8lkFCxakQoUKXHPNNVSsWNHntUKFCpQvX55y5cpRtmxZChcunCWfKfmLwp94hYaGXtX7X375ZX777TeWLVvm0/7qq69St25dRo4cyWuvvZapYxUvXvyi+ydMmABAjx49OH78OPXr12f58uVUrFgRgCpVqrB48WKGDh3Km2++yU033cT48eN5+OGHvceoW7cu33zzDaNHj6Zp06YkJiZSrVo1OnTocDlfW0TyiBMnTviEu9RB72onAzbGUKFCBSpVqsQ111zjXVIHvDJlylCggF8+fVXyCJPbrk1zU0REhI2Ojk5337Zt26hVq1YOVyT+QP/tRXKP06dPs2PHDrZv3+6zxMTEcPTo0Usf4CJKlChBlSpVqFy5MpUrV/auJ7+GhYXpjlXJUcaYddbaiNTtOvMnIiJ5Snx8PDt37kwT8LZv387+/fuv+LhlypShWrVqVK1a1fuaMuxd7eiJSE5R+BMRkVwpPj6eHTt2sGXLFrZs2cLWrVvZsmUL27dvv6JHgQUHB/sEu2rVqnnXq1atqnAneYbCn4iI+LWEhARiYmK8IS952b59+2XPcxcYGMhf//pXrr32Wp+lRo0aVKhQQdfaSb6g8CciIn7j1KlTbNq0iZ9++omNGzfy008/sXnz5st+xFilSpWoWbOmT8CrWbMmf/nLXzTpsOR7+hsgIiI5zlrL/v37+emnn3yWmJiYyzpO5cqVqVOnjnepXbs2tWvX1hCtyEUo/ImISLb7888/Wbt2rc9y6NChTL8/LCyM66+/3ifo1apVi2LFimVj1SJ5k8KfiIhkqVOnTrFu3TqfoLd79+5MvTcgIIDatWtTr149brjhBm644Qbq1atHmTJlsrdokXxE4U9ERK6YtZaYmBhWr17Nd999x+rVq9m6dWumHmMWGhrqDXjJS+3atQkODs6BykXyL4U/ERHJtHPnzrF+/Xq+++47b9jLzPBtoUKFqF+/PjfffLN3ufbaa3V3rYgLFP4kz4uOjubmm29m165dhIeHZ+o93bt35/Dhw3z66afZW5yInzt9+jTffvstq1at4ttvvyU6OvqSz7ANCAigTp06PkHv//7v/wgMDMyhqkXkYvQrVz7WvXt3jDEYYyhYsCBVqlRhwIABHDt2zKdfeHi4t19ISAjXX389b775pnf/mDFjuP7669Mcf/fu3RhjyOiReADNmjXDGMO4cePS7OvUqRPGGB577LGr+JYicjnOnDnD559/zjPPPEOjRo0oUaIErVu3ZsKECXz33XfpBr8SJUrQpk0bXnzxRVatWsWJEyfYuHEjs2fPpl+/ftx4440KfiJ+RGf+8rk777yTd999l4SEBLZu3UrPnj05fvw48+fP9+n33HPPMWDAAE6fPs3cuXPp378/JUqUoHPnzlddQ+XKlXn77bcZNWoUxhgAjhw5wpIlS6hcufJVH19EMhYbG8vq1atZtWoVX331FT/++OMlJ06uXr06jRs3pnHjxtx6663UqlVLw7ciuYj+tuZzhQoVokKFClSqVIkWLVrQuXNnVq5cmaZfaGgoFSpUoHr16owbN44aNWrwySefZEkNrVu35vTp06xatcrb9t5779GgQQOqVavm0/fcuXNERkZSvnx5goODadiwId9++61Pn+XLl3PdddcRHBzM7bffzvbt29N85urVq2natCkhISGEhYUxYMAATp48mSXfR8SfWWvZsmULkydPpmXLlpQqVYo777yTcePG8d1336Ub/OrVq0dkZCSLFy/mjz/+YMeOHcydO5c+ffpQp04dBT+RXEZn/rKJ5wSWKzJxk126du7cyfLlyzM1PBMcHHzZj1XKSGBgIN26dSMqKormzZsDEBUVxbBhw4iKivLp+/TTT/Phhx8SFRVFtWrVmDx5Mq1atWLHjh1UrFiRPXv20L59e/r06cOgQYPYtGkTQ4cO9TnG5s2badGiBc8//zyzZ8/m6NGjREZG0rNnTxYuXJgl30nEnxw9epT//Oc/rFixgpUrV7J3796L9r/++utp3rw5zZs3p0mTJpQuXTqHKhWRnKDwl88tX76cokWLkpiY6H180uTJkzPsn5CQwHvvvcfmzZsZMGBAltXRs2dPIiIimDZtGtu3b2f37t107NjRJ/ydOXOGGTNmMHv2bO6++24AZs6cyZdffsm0adMYN24cM2bMoEqVKrz++usYY7juuuvYvn07zz77rPc4EydOpHPnzgwbNszbNmPGDOrXr8+hQ4coV65cln0vETdYa9mwYQNLly7l3//+N2vXriUpKSnD/jVr1uSOO+6gefPmNG3alLJly+ZgtSKS0xT+8rkmTZowa9YsYmNjeeutt/j111954okn0vQbNWoUY8aM4dy5cwQFBfHUU0/Rr1+/LKujVq1a1KtXj/nz5/PTTz/RpUsXQkJCfPr8+uuvxMfH07hxY29bQEAAjRo1YuvWrQBs27aNhg0beq8dBGjUqJHPcdatW0dMTAwLFizwtiXPSfbrr78q/EmuFBcXx5dffsnSpUtZunQp+/bty7Bv8eLFufPOO2nZsiUtW7akSpUqOVipiLhN4S+bXOnQa04LCQmhevXqALz++us0b96csWPHMmbMGJ9+Q4cOpVevXoSEhFCxYkWfcFWsWDFOnDiR5tjHjx8HnH9oMqNnz55Mnz6dnTt3smLFijT7kwOaSWdMPbktMxPLJiUl0bt3b4YMGZJmX1hYWKZqFfEHBw8eZNmy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PEuMtXantfY88IGnr4jkMufOneOVV17hr3/9K1OnTiUhIcG7r3Pnzvz8889MmTJF07aIiHj48zV//wCeBpLHZkoDx621yT/Z9wJhnvUwYA+AtTbBGHPC0z8MWJPimCnfsydVe4Os/gIikr2WLVtGZGQkMTExPu233XYbr776Kg0a6K+1iEhqfnnmzxhzD3DIWrsuZXM6Xe0l9l1ue3q19DXGRBtjov/888+LVC0iOSUmJoZ77rmHe+65xyf4XXvttXz88cd88803Cn4iIhnwy/AHNAbuNcbsxhmS/RvOmcASxpjks5WVgOSp+fcClQ10bX8AACAASURBVAE8+4sDR1O2p3pPRu1pWGtnWWsjrLURGjYScdfp06d55plnqFOnDsuWLfO2Fy9enH/84x/873//o3379jhXfYiISHr8MvxZa0daaytZa8Nxbtj40lrbFfgK6Ojp9ijwL8/6Es82nv1fWmutp72L527gqkAN4EdgLVDDc/dwkOczluTAVxORK2CtZcGCBVx33XW8/PLLnD9/HgBjDL1792b79u0MHjyYwMBAlysVEfF//nzNX3qGAx8YY8YBG4A5nvY5wLvGmBicM35dAKy1W4wxHwJbgQRgkLU2EcAY8xiwAggAoqy1vjPAiohf2LVrFwMHDmT58uU+7Q0aNGDq1KncfPPNLlUmIpI7GecEmWRGRESEjY6OdrsMkXwhPj6eKVOmMGbMGGJjY73t5cuXZ8KECTzyyCMUKOCXgxciIn7BGLPOWhuRuj23nfkTkXzghx9+oG/fvmzatMnbZoxh0KBBjBs3juLFi7tYnYhI7qbwJyJ+4+TJkzzzzDNMnz6dlKMS9erVY9asWdxyyy0uVicikjco/ImIX1i5ciW9e/dmz54LU3CGhITw/PPPExkZScGC+nElIpIV9NNURFx18uRJhg0bxuzZs33aW7duzfTp0wkPD3enMBGRPErhT0Rck97ZvjJlyvDGG2/QqVMnzdcnIpINdKuciOS4kydP0qdPH1q2bOkT/Dp27MiWLVvo3Lmzgp+ISDbRmT8RyVFff/013bp14/fff/e2lS5dmunTp9OpUycXKxMRyR905k9EcsT58+cZOXIkzZs39wl+999/P1u3blXwExHJITrzJyLZ7pdffqFr166sW7fO21ayZEmmT5+uIV4RkRymM38ikm2stbz11lvceOON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KFfOvfpERCT3UPgTv/bVV1/x4YcferenTp1KwYL553/b06fhlVfg1VchNvZCuzHw8MPw/PNQtap79YmISO6Tf/4VlVwnPj6exx9/3Lv94IMP0qRJExcryjlJSfDuu87NHPv3++67+2546SWoW9ed2kREJHdT+BO/NX36dLZ4bmMtUqQIEydOdLminPHf/zrP2F23zre9fn2YPBmaNXOlLBERySP0+HbxSwcPHuS5557zbj/77LOEhYW5WFH2270bHngAmjTxDX4VKkBUFKxdq+AnIiJXT2f+xC+NHDmSkydPAnDttdcSGRnpckXZJy4OJk50hnLj4i60Bwc7d/COGOHczSsiIpIVFP7E76xZs4a3337bu/3aa69RqFAhFyvKPsuXw+OPQ0yMb/uDD8L48VClijt1iYhI3qXwJ34lKSnJ5yaPdu3a0apVKxcryh6//+5c17d47utQugAAG9lJREFUsW97/frwxhtw663u1CUiInmfrvkTvxIVFUV0dDQAhQoVYvLkyS5XlLXOnYOXX4brrvMNfiVKwLRpznV9Cn4iIpKddOZP/MaxY8cYOXKkd3v48OFUq1bNxYqy1jffQN++8Msvvu3du8OECZqkWUREcobO/InfeO655zh8+DAAVapUYfjw4S5XlDWOH4d+/aBpU9/gV7eu84zet99W8BMRkZyj8Cd+YePGjUyfPt27PXnyZEJCQlysKGssXgy1a8OsWRfaQkPhtdec6VwaN3avNhERyZ807Cuus9by+OP/3969R0dVnf8ffz8EAsg9CAVFBZT6g6ptABFvX9Si4gVboV5QIF6j9AumclGUri+CgOIPtFy05aIYVETkogG1SP2i8rN4QRCFFksErRAEBaFyD2T//jgnMxMIEJLMnEnO57XWrJn95MzZz8xea3jY5+xz+lFQUABA586d6datW8BZlU1eHvTtC/PmFY1fd513bl+zZsHkJSIiopk/CdzMmTNZsmQJAFWrVmX8+PGYWcBZlU5BAUyaBK1bFy38mjSBV1+F115T4SciIsHSzJ8EaufOnQwcODDSzsrKonXr1gFmVHpffw133AGLFxeN33UXPPEENGgQSFoiIiJFqPiTQI0YMYK8vDwAmjRpUuSWbhWFczBlinc3jp07o/FWrbxz/XRLNhERSSY67CuB+fLLL4tcx++JJ56gbt26AWZ0/L79Frp0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\n", "text/plain": [ "
" ] @@ -432,28 +347,28 @@ } ], "source": [ - "import numpy as np\n", - "import matplotlib.pyplot as plt\n", - "\n", - "ts = np.arange(0,2000,1)\n", - "x0_dict = {repr(PFL.dna):1}\n", - "\n", - "# Do not use simulate_with_bioscrape_via_sbml, not working at time of writing (5/31/2020) because of a bug related to sbml model writing\n", "try:\n", - " R2 = CRN2.simulate_with_bioscrape(ts, initial_condition_dict = x0_dict, stochastic = False,)\n", - "\n", - " fig = plt.figure(figsize=(10,6))\n", - " plt.title('Transcript Levels',pad=20,fontdict={'fontsize':18})\n", - " plt.plot(R1['rna_GFP'],linewidth=3,c='k',label='MTX Model')\n", - " plt.plot(R2['rna_GFP'],linewidth=3,c='b', label='RPU Model')\n", - " plt.xlabel('Time (sec)',labelpad=15,fontdict={'fontsize':14})\n", - " plt.ylabel('Transcript Count',labelpad=15,fontdict={'fontsize':14})\n", - " plt.legend(fontsize=14)\n", - "\n", - " print('\\n \\n')\n", - " print(f\"MX Model predicts {np.round(R1['rna_GFP'].iloc[-1])} transcripts and RPU Model predicts {np.round(R2['rna_GFP'].iloc[-1])} transcripts at SS \\n \\n\")\n", + " import numpy as np\n", + " import matplotlib.pyplot as plt\n", + "\n", + " ts = np.arange(0,5000,1)\n", + " x0_dict = {repr(PFL_default.dna):1, repr(SC.dna):.1}\n", + "\n", + " R2 = CRN2.simulate_with_bioscrape_via_sbml(ts, initial_condition_dict = x0_dict, stochastic = False,)\n", + " if R2 is not None:\n", + " fig = plt.figure(figsize=(10,6))\n", + " plt.title('GFP Levels',pad=20,fontdict={'fontsize':18})\n", + " plt.plot(R1[str(GFP)],linewidth=3,c='k',label='MTX Model')\n", + " plt.plot(R2[str(GFP)],linewidth=3,c='b', label='RPU Model')\n", + " plt.xlabel('Time (sec)',labelpad=15,fontdict={'fontsize':14})\n", + " plt.ylabel('[GFP]',labelpad=15,fontdict={'fontsize':14})\n", + " plt.legend(fontsize=14)\n", + "\n", + " print('\\n \\n')\n", + " print(f\"MX Model predicts {np.round(R1[str(str(GFP))].iloc[-1])} GFP and RPU Model predicts {np.round(R2[str(str(GFP))].iloc[-1])} GFP at SS \\n \\n\")\n", "except ModuleNotFoundError:\n", - " pass" + " print('please install the plotting libraries: pip install biocrnpyler[all]')\n", + "\n" ] }, { @@ -476,7 +391,7 @@ "source": [ "The general model of binding, isomerization and production can be readily extended to the process of translation. However, there are several caveats for translation. \n", "\n", - "- First of all, I don't have any direct data like RPU experiments to compare my model with. All I can say is that with biologically reasonable parameter sets, you get something like a few hundred proteins per mRNA (RBZ in excess) and e. coli has a protein to mRNA ratio in that range (100:1 - 1000:1) (Taniguchi et al.(2010) or bionumbers book). \n", + "- First of all, I don't have any direct data like RPU experiments to compare my model with. All I can say is that with biologically reasonable parameter sets, you get something like a few 100 proteins per mRNA (RBZ in excess) and e. coli has a protein to mRNA ratio in that range (100:1 - 1000:1) (Taniguchi et al.(2010) or bionumbers book). \n", "\n", "- Second of all, since we're no longer working with DNA complexes, the mRNA-RBZ complexes should be subject to degredation/dilution. However, it seems that at the level of the biology, initiation can have a stabilizing effect and for elongation it is uncertain (Roy et al. (2013)). In my simulations, I've effectively done as if only dilution is applied to these complexes, but there is an argument to include some form of active degredation (at a reduced rate). Depending on how this implemented, one may need to make a new degredation mechanism where the complexes effectively releases the ribosomes i.e. only mRNA degraded. This is also complicated by the fact that using subclasses like ComplexSpecies() results in inheritance of degredation/material properties. " ] @@ -485,229 +400,96 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "## Quick Example " - ] - }, - { - "cell_type": "code", - "execution_count": 7, - "metadata": {}, - "outputs": [], - "source": [ - "from biocrnpyler import *\n", - "import warnings\n", - "\n", - "class multi_tl(Mechanism):\n", - " '''\n", - " Multi-RBZ Translation w/ Isomerization:\n", - " Detailed translation mechanism accounting for each individual \n", - " RBZ occupancy states of mRNA. Still needs some work, so use with caution,\n", - " read all warnings and consult the example notebook.\n", - " \n", - " n ={0, max_occ}\n", - " mRNA:RBZ_n + RBZ <--> mRNA:RBZ_n_c --> mRNA:RBZ_n+1\n", - " mRNA:RBZ_n --> mRNA:RBZ_0 + n RBZ + n Protein\n", - " mRNA:RBZ_n_c --> mRNA:RBZ_0_c + n RBZ + n Protein\n", - " \n", - " n --> number of open configuration RBZ on mRNA\n", - " max_occ --> Physical maximum number of RBZ on mRNA (based on RBZ and mRNA dimensions)\n", - " mRNA:RBZ_n --> mRNA with n open configuration RBZ on it\n", - " mRNA:RBZ_n_c --> mRNA with n open configuration RBZ and 1 closed configuration RBZ on it\n", - " \n", - " For more details, see examples/MultiTX_Demo.ipynb\n", - " ''' \n", - " \n", - " # initialize mechanism subclass\n", - " def __init__(self, ribosome, name='multi_tl', mechanism_type='translation', **keywords):\n", - "\n", - " if isinstance(ribosome,str):\n", - " self.ribosome = Species(name=ribosome, material_type='protein')\n", - " \n", - " elif isinstance(ribosome,Species):\n", - " self.ribosome = ribosome\n", - " \n", - " else:\n", - " raise ValueError(\"'ribosome' must be a string or Species\")\n", - " \n", - " warnings.warn('This mechanism still needs some extra validation, use at your own peril and read the warnings!')\n", - " warnings.warn(\"To properly use this mechanism, set dilution for mRNA-RBZ complexes!\")\n", - " warnings.warn(\"I've set RBZ and mRNA-RBZ complexes as protein Species to apply dilution to them, edit if you want something else!\")\n", - "\n", - " Mechanism.__init__(self, name=name, mechanism_type=mechanism_type, **keywords)\n", - " \n", - " # species update\n", - " def update_species(self, transcript, protein, component, part_id, **keywords):\n", - " max_occ = int(component.get_parameter(\"max_occ\", part_id = part_id, mechanism = self))\n", - " cp_open = []\n", - " cp_closed = []\n", - " for n in range(1,max_occ + 1):\n", - " name_open = self.ribosome.name + 'x' + transcript.name + '_' + str(n)\n", - " cp_open.append(ComplexSpecies([transcript]+[self.ribosome for i in range(n)],name=name_open))\n", - " \n", - " if n > 1:\n", - " name_closed = self.ribosome.name + 'x' + transcript.name + '_closed' + '_' + str(n-1)\n", - " cp_closed.append(ComplexSpecies([transcript]+[self.ribosome for i in range(n-1)],name=name_closed))\n", - " else:\n", - " name_closed = self.ribosome.name + 'x' + transcript.name + '_closed' + '_' + str(0)\n", - " cp_closed.append(ComplexSpecies([transcript]+[self.ribosome for i in range(1)],name=name_closed))\n", - " \n", - "\n", - " cp_misc = [self.ribosome,transcript,protein]\n", - "\n", - " return cp_open + cp_closed + cp_misc\n", - " \n", - " def update_reactions(self, transcript, protein, component, part_id, **keywords):\n", - " '''\n", - " mRNA:RBZ_n + RBZ <--> mRNA:RBZ_n_c --> mRNA:RBZ_n+1\n", - " kf1 = kbr, kr1 = kur, kf2 = k_iso_r\n", - " mRNA:RBZ_n --> mRNA:RBZ_0 + n RBZ + n Protein\n", - " kf = ktl_solo\n", - " mRNA:RBZ_n_c --> mRNA:RBZ_0_c + n RBZ + n Protein\n", - " kf = ktl_solo\n", - " '''\n", - " \n", - " # parameter loading\n", - " kbr = component.get_parameter(\"kbr\", part_id = part_id, mechanism = self)\n", - " kur = component.get_parameter(\"kur\", part_id = part_id, mechanism = self)\n", - " k_iso_r = component.get_parameter(\"k_iso_r\", part_id = part_id, mechanism = self)\n", - " ktl_solo = component.get_parameter(\"ktl_solo\", part_id = part_id, mechanism = self)\n", - " max_occ = int(component.get_parameter(\"max_occ\", part_id = part_id, mechanism = self))\n", - "\n", - " \n", - " # complex species instantiation\n", - " cp_open = []\n", - " cp_closed = []\n", - " for n in range(1,max_occ + 1):\n", - " name_open = self.ribosome.name + 'x' + transcript.name + '_' + str(n)\n", - " cp_open.append(ComplexSpecies([transcript]+[self.ribosome for i in range(n)],name=name_open))\n", - " \n", - " if n > 1:\n", - " name_closed = self.ribosome.name + 'x' + transcript.name + '_closed' + '_' + str(n-1)\n", - " cp_closed.append(ComplexSpecies([transcript]+[self.ribosome for i in range(n-1)],name=name_closed))\n", - " else:\n", - " name_closed = self.ribosome.name + 'x' + transcript.name + '_closed' + '_' + str(0)\n", - " cp_closed.append(ComplexSpecies([transcript]+[self.ribosome for i in range(1)],name=name_closed))\n", - " \n", - " # Reactions\n", - " # ribosome + complex(n) --> complex(n_closed)\n", - " rxn_open_pf = [Reaction(inputs=[self.ribosome, cp_open[n]], outputs=[cp_closed[n+1]], k=kbr) for n in range(0,max_occ-1)]\n", - " rxn_open_pr = [Reaction(inputs=[cp_closed[n+1]], outputs=[self.ribosome, cp_open[n],], k=kur) for n in range(0,max_occ-1)]\n", - " \n", - " # isomerization\n", - " rxn_iso = [Reaction(inputs=[cp_closed[n]], outputs=[cp_open[n]], k=k_iso_r) for n in range(0,max_occ)]\n", - " \n", - " # release/translation from open and closed states\n", - " rxn_release_open = []\n", - " rxn_release_closed = []\n", - " for n in range(0,max_occ):\n", - " rxn_temp1 = Reaction(inputs= [cp_open[n]], outputs=[self.ribosome for i in range(n+1)] + \n", - " [protein for i in range(n+1)] + [transcript], k=ktl_solo)\n", - " rxn_release_open.append(rxn_temp1)\n", - " \n", - " for n in range(1,max_occ):\n", - " rxn_temp2 = Reaction(inputs= [cp_closed[n]], outputs=[self.ribosome for i in range(n)] + \n", - " [protein for i in range(n)] + [cp_closed[0]], k=ktl_solo)\n", - " rxn_release_closed.append(rxn_temp2)\n", - " \n", - " # missing reactions (0 --> 0_closed and v.v. 0_closed --> 0)\n", - " rxn_m1 = Reaction(inputs=[transcript,self.ribosome], outputs=[cp_closed[0]], k=kbr)\n", - " rxn_m2 = Reaction(inputs=[cp_closed[0]], outputs=[transcript,self.ribosome], k=kur)\n", - " \n", - " rxn_all = rxn_open_pf + rxn_open_pr + rxn_iso + rxn_release_open + rxn_release_closed + [rxn_m1, rxn_m2]\n", - " \n", - " return rxn_all" - ] - }, - { - "cell_type": "code", - "execution_count": 8, - "metadata": {}, - "outputs": [], - "source": [ - "class DilutionMixture(Mixture):\n", - " def __init__(self, name=\"\", **keywords):\n", - " \n", - " simple_transcription = SimpleTranscription() #Transcription will not involve machinery\n", - " simple_translation = SimpleTranslation()\n", - " \n", - " default_mechanisms = {\n", - " \"transcription\": simple_transcription, #This will be overwritten by the NegativeHillPromotor\n", - " \"translation\": simple_translation\n", - " }\n", - " \n", - " #By Default Species are diluted S-->0 Unless:\n", - " # They are of type 'dna'\n", - " # They have the attribute 'machinery'\n", - " dilution_mechanism = Dilution(filter_dict = {\"dna\":False,'protein':True,'complex':True}, default_on = True)\n", - " dilution_mrn = Dilution(name = \"rna_degredation\", filter_dict = {\"rna\":True}, default_on = False)\n", - "\n", - " #Add this mechanism to a dictionary which is passed into the Mixture txtl.TxTlExtract\n", - " global_mechanisms = {\"dilution\":dilution_mechanism, \"rna_degredation\":dilution_mrn}\n", - " \n", - " #Always call the superclass __init__ with **keywords\n", - " Mixture.__init__(self, name=name, default_mechanisms=default_mechanisms, global_mechanisms = global_mechanisms, **keywords)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ + "## Quick Example \n", "PFL is transcribed through simple transcription and translated through my multi_tl mechanism. We also have a constitutive source of our RBZ being produced to provide a constant saturating concentration of RBZ." ] }, { "cell_type": "code", - "execution_count": 9, + "execution_count": 8, "metadata": {}, "outputs": [ { - "name": "stderr", + "name": "stdout", "output_type": "stream", "text": [ - "C:\\Users\\mkratz\\Anaconda3\\lib\\site-packages\\ipykernel_launcher.py:36: UserWarning: This mechanism still needs some extra validation, use at your own peril and read the warnings!\n", - "C:\\Users\\mkratz\\Anaconda3\\lib\\site-packages\\ipykernel_launcher.py:37: UserWarning: To properly use this mechanism, set dilution for mRNA-RBZ complexes!\n", - "C:\\Users\\mkratz\\Anaconda3\\lib\\site-packages\\ipykernel_launcher.py:38: UserWarning: I've set RBZ and mRNA-RBZ complexes as protein Species to apply dilution to them, edit if you want something else!\n" + "Species (29) = {0. dna[T7] init_conc = 0, 1. protein[RNAP(machinery)] init_conc = 0, 2. rna[GFP] init_conc = 0, 3. complex[dna[T7]:protein[RNAP]] init_conc = 0, 4. complex[protein[Ribo]:rna[GFP]] init_conc = 0, 5. complex[2x_protein[Ribo]:rna[GFP]] init_conc = 0, 6. complex[protein[Ribo]:rna[GFP](closed)] init_conc = 0, 7. complex[2x_protein[Ribo]:rna[GFP](closed)] init_conc = 0, 8. protein[Ribo(machinery)] init_conc = 0, 9. protein[GFP] init_conc = 0, 10. protein[RNAase(machinery)] init_conc = 0, 11. dna[cellular_processes] init_conc = 0, 12. rna[cellular_processes] init_conc = 0, 13. complex[dna[cellular_processes]:protein[RNAP]] init_conc = 0, 14. complex[protein[Ribo]:rna[cellular_processes]] init_conc = 0, 15. complex[2x_protein[Ribo]:rna[cellular_processes]] init_conc = 0, 16. complex[protein[Ribo]:rna[cellular_processes](closed)] init_conc = 0, 17. complex[2x_protein[Ribo]:rna[cellular_processes](closed)] init_conc = 0, 18. protein[cellular_processes] init_conc = 0, 19. complex[protein[RNAase]:rna[GFP]] init_conc = 0, 20. complex[complex[protein[Ribo]:rna[GFP]]:protein[RNAase]] init_conc = 0, 21. complex[complex[2x_protein[Ribo]:rna[GFP]]:protein[RNAase]] init_conc = 0, 22. complex[complex[protein[Ribo]:rna[GFP]]:protein[RNAase]] init_conc = 0, 23. complex[complex[2x_protein[Ribo]:rna[GFP]]:protein[RNAase]] init_conc = 0, 24. complex[protein[RNAase]:rna[cellular_processes]] init_conc = 0, 25. complex[complex[protein[Ribo]:rna[cellular_processes]]:protein[RNAase]] init_conc = 0, 26. complex[complex[2x_protein[Ribo]:rna[cellular_processes]]:protein[RNAase]] init_conc = 0, 27. complex[complex[protein[Ribo]:rna[cellular_processes]]:protein[RNAase]] init_conc = 0, 28. complex[complex[2x_protein[Ribo]:rna[cellular_processes]]:protein[RNAase]] init_conc = 0}\n", + "\n", + "Reactions (42) = [\n", + "0. dna[T7]+protein[RNAP(machinery)] <--> complex[dna[T7]:protein[RNAP]]\n", + "1. complex[dna[T7]:protein[RNAP]] --> dna[T7]+rna[GFP]+protein[RNAP(machinery)]\n", + "2. protein[Ribo(machinery)]+complex[protein[Ribo]:rna[GFP]] <--> complex[2x_protein[Ribo]:rna[GFP](closed)]\n", + "3. complex[protein[Ribo]:rna[GFP](closed)] --> complex[protein[Ribo]:rna[GFP]]\n", + "4. complex[2x_protein[Ribo]:rna[GFP](closed)] --> complex[2x_protein[Ribo]:rna[GFP]]\n", + "5. complex[protein[Ribo]:rna[GFP]] --> protein[Ribo(machinery)]+protein[GFP]+rna[GFP]\n", + "6. complex[2x_protein[Ribo]:rna[GFP]] --> 2protein[Ribo(machinery)]+2protein[GFP]+rna[GFP]\n", + "7. complex[2x_protein[Ribo]:rna[GFP](closed)] --> protein[Ribo(machinery)]+protein[GFP]+complex[protein[Ribo]:rna[GFP](closed)]\n", + "8. rna[GFP]+protein[Ribo(machinery)] <--> complex[protein[Ribo]:rna[GFP](closed)]\n", + "9. dna[cellular_processes]+protein[RNAP(machinery)] <--> complex[dna[cellular_processes]:protein[RNAP]]\n", + "10. complex[dna[cellular_processes]:protein[RNAP]] --> dna[cellular_processes]+rna[cellular_processes]+protein[RNAP(machinery)]\n", + "11. protein[Ribo(machinery)]+complex[protein[Ribo]:rna[cellular_processes]] <--> complex[2x_protein[Ribo]:rna[cellular_processes](closed)]\n", + "12. complex[protein[Ribo]:rna[cellular_processes](closed)] --> complex[protein[Ribo]:rna[cellular_processes]]\n", + "13. complex[2x_protein[Ribo]:rna[cellular_processes](closed)] --> complex[2x_protein[Ribo]:rna[cellular_processes]]\n", + "14. complex[protein[Ribo]:rna[cellular_processes]] --> protein[Ribo(machinery)]+protein[cellular_processes]+rna[cellular_processes]\n", + "15. complex[2x_protein[Ribo]:rna[cellular_processes]] --> 2protein[Ribo(machinery)]+2protein[cellular_processes]+rna[cellular_processes]\n", + "16. complex[2x_protein[Ribo]:rna[cellular_processes](closed)] --> protein[Ribo(machinery)]+protein[cellular_processes]+complex[protein[Ribo]:rna[cellular_processes](closed)]\n", + "17. rna[cellular_processes]+protein[Ribo(machinery)] <--> complex[protein[Ribo]:rna[cellular_processes](closed)]\n", + "18. rna[GFP]+protein[RNAase(machinery)] <--> complex[protein[RNAase]:rna[GFP]]\n", + "19. complex[protein[RNAase]:rna[GFP]] --> protein[RNAase(machinery)]\n", + "20. complex[protein[Ribo]:rna[GFP]]+protein[RNAase(machinery)] <--> complex[complex[protein[Ribo]:rna[GFP]]:protein[RNAase]]\n", + "21. complex[complex[protein[Ribo]:rna[GFP]]:protein[RNAase]] --> protein[Ribo(machinery)]+protein[RNAase(machinery)]\n", + "22. complex[2x_protein[Ribo]:rna[GFP]]+protein[RNAase(machinery)] <--> complex[complex[2x_protein[Ribo]:rna[GFP]]:protein[RNAase]]\n", + "23. complex[complex[2x_protein[Ribo]:rna[GFP]]:protein[RNAase]] --> 2protein[Ribo(machinery)]+protein[RNAase(machinery)]\n", + "24. complex[protein[Ribo]:rna[GFP](closed)]+protein[RNAase(machinery)] <--> complex[complex[protein[Ribo]:rna[GFP]]:protein[RNAase]]\n", + "25. complex[complex[protein[Ribo]:rna[GFP]]:protein[RNAase]] --> protein[Ribo(machinery)]+protein[RNAase(machinery)]\n", + "26. complex[2x_protein[Ribo]:rna[GFP](closed)]+protein[RNAase(machinery)] <--> complex[complex[2x_protein[Ribo]:rna[GFP]]:protein[RNAase]]\n", + "27. complex[complex[2x_protein[Ribo]:rna[GFP]]:protein[RNAase]] --> 2protein[Ribo(machinery)]+protein[RNAase(machinery)]\n", + "28. rna[cellular_processes]+protein[RNAase(machinery)] <--> complex[protein[RNAase]:rna[cellular_processes]]\n", + "29. complex[protein[RNAase]:rna[cellular_processes]] --> protein[RNAase(machinery)]\n", + "30. complex[protein[Ribo]:rna[cellular_processes]]+protein[RNAase(machinery)] <--> complex[complex[protein[Ribo]:rna[cellular_processes]]:protein[RNAase]]\n", + "31. complex[complex[protein[Ribo]:rna[cellular_processes]]:protein[RNAase]] --> protein[Ribo(machinery)]+protein[RNAase(machinery)]\n", + "32. complex[2x_protein[Ribo]:rna[cellular_processes]]+protein[RNAase(machinery)] <--> complex[complex[2x_protein[Ribo]:rna[cellular_processes]]:protein[RNAase]]\n", + "33. complex[complex[2x_protein[Ribo]:rna[cellular_processes]]:protein[RNAase]] --> 2protein[Ribo(machinery)]+protein[RNAase(machinery)]\n", + "34. complex[protein[Ribo]:rna[cellular_processes](closed)]+protein[RNAase(machinery)] <--> complex[complex[protein[Ribo]:rna[cellular_processes]]:protein[RNAase]]\n", + "35. complex[complex[protein[Ribo]:rna[cellular_processes]]:protein[RNAase]] --> protein[Ribo(machinery)]+protein[RNAase(machinery)]\n", + "36. complex[2x_protein[Ribo]:rna[cellular_processes](closed)]+protein[RNAase(machinery)] <--> complex[complex[2x_protein[Ribo]:rna[cellular_processes]]:protein[RNAase]]\n", + "37. complex[complex[2x_protein[Ribo]:rna[cellular_processes]]:protein[RNAase]] --> 2protein[Ribo(machinery)]+protein[RNAase(machinery)]\n", + "38. rna[GFP] --> \n", + "39. protein[GFP] --> \n", + "40. rna[cellular_processes] --> \n", + "41. protein[cellular_processes] --> \n", + "]\n" ] } ], "source": [ - "# Instantiate RBZ species\n", - "RBZ = Species('RBZ',material_type='protein')\n", - "\n", - "# make RBZ source\n", - "JP = Promoter('J23101')\n", - "RBZ_S = DNAassembly('RBZ_source',promoter=JP,transcript=RBZ)\n", - "\n", - "# Instantiate mechanism and mixture\n", - "ML = multi_tl(RBZ)\n", - "PFL = DNAassembly('PFL',dna='T7',rbs='RBSG',promoter='pT7',transcript='GFP',protein='GFP')\n", - "EM = DilutionMixture('EM',components=[PFL,RBZ_S],parameter_file = \"default_parameters.txt\",mechanisms={'translation':ML})\n", - "CRN3 = EM.compile_crn()" + "#the most important parameters for multi_tl\n", + "#max_occ is the number of ribosomes that can bind to a transcript\n", + "#k_iso is the rate of isomerization\n", + "parameters = {\"max_occ\":2, \"k_iso\":10}\n", + "\n", + "#Create a DNA assembly and Mixture\n", + "PFL = DNAassembly('PFL', dna='T7', rbs='medium', promoter='medium',transcript='GFP',protein='GFP')\n", + "EM = TxTlDilutionMixture(name = 'e coli',components=[PFL], parameter_file = \"default_parameters.txt\", parameters = parameters)\n", + "\n", + "# Instantiate mechanism and pass it the ribosome\n", + "ML = multi_tl(EM.ribosome.get_species())\n", + "\n", + "#Overwrite the translation mechanism\n", + "EM.add_mechanism(ML, overwrite = True)\n", + "\n", + "CRN3 = EM.compile_crn()\n", + "print(CRN3.pretty_print(show_rates = False))" ] }, { "cell_type": "code", - "execution_count": 10, + "execution_count": 6, "metadata": {}, "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\n", - "\n", - "The ratio of protein to mRNA is 209.0 protein per mRNA\n", - "\n", - "\n", - "The average mRNA occupancy is 11.0 ribosomes per mRNA\n", - "\n", - " \n", - "\n" - ] - }, { "data": { - "image/png": "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\n", + "image/png": "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1wa50My6lPz8/pnyga5mNh5vNbfWeImbnUQlPZxza81sNfA7/3ETsMM5Nz7GPUs6y8waxKjf4Jx7AW/ekb7Av8zsLPyV4vAmOj8Db76Ss0tcOxJvqdin8L6seY19XY236t40MxuJl5hIxnvvfoO3BO/wUmJuDCwzs3fwlsLdBLTHW0Z2M3snbBcplZIbIpXEObfMzI4DrsD7g/YWvHXQs/H+EH4B7w/cRcFFefCcc/n+B+PdeA2rgXgNhjeBu51zq6PO3WNmg/CGSDwBpOGNq53kH7/CH2s5FG+ZslS8htssv1xVUvEaVrEsAeY75yb6E57djjeJZ1NgK94wnceI3ZV1JF6yAYqPU41wzv3NzGbiTar1//AmUsvCG299037ifgcvEXIh3sSje/C6iV6NtySeiIgkqBrUrljoJ3L+jrdyWz7wJV7Phpfxvkg4EMvwPntPxWurpOKtwPIU8GD0ajDOuf/nfxZfj/c5b8AqvB6X+Qf4/EXCeAmEx/HaGmnAVOBW51zJiUYvxpsk9kG8oTqLKN8f+ef4W0nfAy8453L9L0P+gDfE5G/+8XXANLz3uRjn3FQzW4w34eoHzrl9hgc555abWXe89+xcvC+/duO9d2P9rTTbgX/hJV36AbXxVvJ7G3jAOVfW5KcigL9Ws4iIiIiIiFQeMxsD/MY5p+XaRSqB5twQERERERERkYSm5IaIiIiIiIiIJDQlN0REREREREQkoWnODRERERERERFJaOq5ISIiIiIiIiIJTckNEREREREREUloSm6IiIiIiIiISEJTckNEREREREREEpqSGyIiIiIiIiKS0JTcEBEREREREZGEpuSGiIiIiIiIiCQ0JTdEREREREREJKEpuSEiIiIiIiIiCU3JDRERERERERFJaEpuiIiIiIiIiEhCU3JDRERERERERBKakhsiIiIiIiIiktCU3BARERERERGRhKbkhoiIiIiIiIgktOSgA4g3TZo0cW3btg06DBERkbgzc+bMzc65pkHHUROoPSIiIhJbae0RJTdKaNu2LTNmzAg6DBERkbhjZiuDjqGmUHtEREQkttLaIxqWIiIiIiIiIiIJTckNEREREREREUloSm6IiIiIiIiISEJTckNEREREREREEpqSGyIiIiIiIiKS0JTcEBEREREREZGEpuSGiIiIiIiIiCQ0JTdEREREREREJKEp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zpx8hoz4NpLYMIP7zzuKi3tq7XURERGRkgoKCvjjH//I008/Halr374977zzDl27dg0wMhGpjpTcECmHPXmFXPnyDOas2Q54iY1HLujG+ce1DjgyERERkfiza9cuBg0axIcffhipO+mkkxg3bhyNGzcOMDIRqa4054bIfuQWFDL0vzP4dsXeVVH+8ZujlNgQERERiWHTpk2ceuqpxRIbgwYN4uOPP1ZiQ0QqjZIbImUIhx03v/49Xy7eHKm7e8CRXPJLDUURERERKWnt2rWccsopzJw5M1J3++238+qrr5Kenh5gZCJS3WlYikgZHvhoAR/+sD5S/tPph3PVSYcFGJGIiIhIfFq+fDl9+/Zl+fLlAJgZTz31FNdee23AkYlITaDkhkgpRk5dwfNfLo+Uf9+7LX/s2yHAiERERETi04IFCzj99NNZt24dAMnJyYwaNYqLLroo4MhEpKZQckMkhk/mb+Sv78+LlM/q0px7zumMmQUYlYiIiEj8mTt3LqeddhqbNm0CIC0tjbfffpsBAwYEHJmI1CRKboiUMHftdv4wehZh55WPadOAJy7qTihJiQ0RERGRaAsXLqRv376RxEZGRgbvv/8+ffr0CTgyEalplNwQibJlVy7X/HcmOflhADIb1eaFIT2olRoKODIRERGR+LJ48WJOO+00srKyAKhbty4ff/wxvXr1CjgyEamJtFqKiC+/MMyNr81m7bY9ANRNS+al3/+CJnXSAo5MREREJL4sXbqUPn36sH69N/F6RkYGEyZMUGJDRAKj5IaI7/7xC5i2bAsAZvDPi4+hQ7M6AUclIiIiEl/WrFlD3759Wbt2LQC1atVi/Pjx9O7dO+DIRKQmU3JDBBg7aw0j/rciUr759MM5rVPz4AISERERiUNbt26lX79+rFy5EoD09HTef/99Tj755IAjE5GaTskNqfGWZO3krnFzI+V+XVpwQx8t+SoiIiISbc+ePfzqV79i3jxvRbnk5GTGjRtH3759A45MRETJDanhcvILueHV2ezJLwSgfdMMHrmwG0laGUVEREQkoqCggIsvvpivvvoqUvfyyy/Tr1+/AKMSEdlLyQ2p0f72wXwWbdwJQFpyEv+59FjqpGkRIREREZEizjmuv/563n333Ujdo48+yqWXXhpgVCIixSm5ITXWh3PW89o3qyLlv5zbmU4t6gUYkYiIiEj8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\n", "text/plain": [ "
" ] @@ -719,61 +501,31 @@ } ], "source": [ - "import numpy as np\n", - "import matplotlib.pyplot as plt\n", + "try:\n", "\n", - "ts = np.arange(0,10000,1)\n", - "x0_dict = {repr(RBZ_S.dna):100,repr(PFL.dna):1}\n", + " import numpy as np\n", + " import matplotlib.pyplot as plt\n", "\n", - "try:\n", - " # Do not use simulate_with_bioscrape_via_sbml, not working at time of writing (5/31/2020) because of a bug related to sbml model writing \n", - " R3 = CRN3.simulate_with_bioscrape(ts, initial_condition_dict = x0_dict, stochastic = False,)\n", - "\n", - " fig, ax = plt.subplots(1,2,figsize=(18,8))\n", - " ax[0].set_title('GFP Protein Levels',pad=20,fontdict={'fontsize':18})\n", - " ax[0].plot(R3['protein_GFP'],linewidth=3)\n", - " ax[0].set_xlabel('Time (sec)',labelpad=15,fontdict={'fontsize':14})\n", - " ax[0].set_ylabel('GFP Protein Count',labelpad=15,fontdict={'fontsize':14})\n", - "\n", - " ax[1].set_title('GFP Transcript Levels',pad=20,fontdict={'fontsize':18})\n", - " ax[1].plot(R3['rna_GFP'],linewidth=3,c='k')\n", - " ax[1].set_xlabel('Time (sec)',labelpad=15,fontdict={'fontsize':14})\n", - " ax[1].set_ylabel('GFP Transcript Count',labelpad=15,fontdict={'fontsize':14})\n", - "\n", - "\n", - " # tiny script to aggregate T7m containing species\n", - " import pandas as pd\n", - " j = pd.DataFrame()\n", - " for col in R3.columns:\n", - " if 'xGFP' in col:\n", - " j[col] = R3[col]\n", - " j['sum'] = j.sum(axis=1)\n", - "\n", - " # tiny script to calculate total ribosomes bound to mRNA\n", - " rbz_sum = 0\n", - " for col in j.columns[0:-1]:\n", - " if 'closed' in col:\n", - " c = int(col.split('_')[-1])\n", - " c+=1\n", - " else:\n", - " c = int(col.split('_')[-1])\n", - " rbz_sum += c * j[col].iloc[-1]\n", - "\n", - " print('\\n')\n", - " print(f\"The ratio of protein to mRNA is {np.round(R3['protein_GFP'].iloc[-1]/j['sum'].iloc[-1])} protein per mRNA\")\n", - " print('\\n')\n", - " print(f\"The average mRNA occupancy is {np.round(rbz_sum/j['sum'].iloc[-1])} ribosomes per mRNA\")\n", - " print('\\n \\n')\n", + " ts = np.arange(0,10000,1)\n", + " x0_dict = {repr(PFL.dna):1, repr(EM.ribosome.get_species()):100, repr(EM.rnap.get_species()):20}\n", + "\n", + " R3 = CRN3.simulate_with_bioscrape_via_sbml(ts, initial_condition_dict = x0_dict, stochastic = False,)\n", "\n", + " if R3 is not None:\n", + " fig, ax = plt.subplots(1,2,figsize=(18,8))\n", + " ax[0].set_title('GFP Protein Levels',pad=20,fontdict={'fontsize':18})\n", + " ax[0].plot(R3[str(PFL.protein)],linewidth=3)\n", + " #ax[0].plot(R3[str(EM.ribosome.get_species())],linewidth=3)\n", + " ax[0].set_xlabel('Time (sec)',labelpad=15,fontdict={'fontsize':14})\n", + " ax[0].set_ylabel('GFP Protein Count',labelpad=15,fontdict={'fontsize':14})\n", + "\n", + " ax[1].set_title('GFP Transcript Levels',pad=20,fontdict={'fontsize':18})\n", + " ax[1].plot(R3[str(PFL.transcript)],linewidth=3,c='k')\n", + " ax[1].set_xlabel('Time (sec)',labelpad=15,fontdict={'fontsize':14})\n", + " ax[1].set_ylabel('GFP Transcript Count',labelpad=15,fontdict={'fontsize':14})\n", "except ModuleNotFoundError:\n", - " pass" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "GFP transcript count is very low as all of it is currently occupied in various RBZ-transcript complexes" + " print('please install the plotting libraries: pip install biocrnpyler[all]')\n", + "\n" ] }, { @@ -843,4 +595,4 @@ }, "nbformat": 4, "nbformat_minor": 4 -} +} \ No newline at end of file diff --git a/examples/Specialized Component Tutorials/default_parameters.txt b/examples/Specialized Component Tutorials/default_parameters.txt index d007f0e1..41536aae 100644 --- a/examples/Specialized Component Tutorials/default_parameters.txt +++ b/examples/Specialized Component Tutorials/default_parameters.txt @@ -1,4 +1,7 @@ mechanism_id part_id param_name param_val comments + Ribo 120 uM assuming similar to e coli + RNAP 15 uM assuming similar to e coli + RNAase 30 uM assuming similar to e coli e coli Ribo 120 uM assuming ~72000 Ribosomes / e. coli with a volume 1 um^3 e coli RNAP 15 uM assuming ~10000 RNAP molecules / e. coli with a volume 1 um^3 e coli RNAase 30 uM assuming ~20000 RNAP molecules / e. coli with a volume 1 um^4 @@ -42,14 +45,6 @@ simple_transcription pT7 ktx 0.327 Above rescaled by ktx for simple transcriptio simple_translation BCD2 ktl 3 Above rescaled by ktl for simple translation simple_translation BCD8 ktl 0.15 Above rescaled by ktl for simple translation simple_translation BCD12 ktl 0.3 Above rescaled by ktl for simple translation -MX pT7 k1 0.072 -MX pT7 k2 4 -MX pT7 k_iso 0.36 -MX pT7 ktx_solo 0.085 -MX pT7 max_occ 40 -multi_tl RBSG kbr 1 -multi_tl RBSG kur 100 -multi_tl RBSG k_iso_r 0.3 -multi_tl RBSG ktl_solo 0.02 -multi_tl RBSG max_occ 22 +multi_tx kb 0.072 +multi_tx ku 4 diff --git a/examples/build_crns_directly.xml b/examples/build_crns_directly.xml deleted file mode 100644 index a03617ac..00000000 --- a/examples/build_crns_directly.xml +++ /dev/null @@ -1,70 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - type=massaction k=3.0 - - - - - - - - - - - - k - m1_A_attribute - - - - - - - - - - type=massaction k=1.4 - - - - - - - - - - - - - k - m1_B - - - - - - - - - - diff --git a/examples/default_parameters.txt b/examples/default_parameters.txt index bb2695cb..3d16e4bf 100644 --- a/examples/default_parameters.txt +++ b/examples/default_parameters.txt @@ -3,12 +3,12 @@ mechanism_id part_id param_name param_val comments e coli RNAP 15 uM assuming ~10000 RNAP molecules / e. coli with a volume 1 um^3 e coli RNAase 45 uM assuming ~30000 RNAP molecules / e. coli with a volume 1 um^4 e coli cellular_processes 5 somewhat arbitary concentration for ~3000 genes in e. coli assuming weak loading on all of them - e coli extract Ribo 24 1/5 th the Ribosome concentration of E. Coli - e coli extract RNAP 3 1/5 th the rnap concentration of E. Coli - e coli extract RNAase 6 1/5 th the rnaase concentration of E. Coli - e coli extract 2 Ribo 12 - e coli extract 2 RNAP 6 - e coli extract 2 RNAase 3 + e coli extract protein_Ribo 24 1/5 th the Ribosome concentration of E. Coli + e coli extract protein_RNAP 3 1/5 th the rnap concentration of E. Coli + e coli extract protein_RNAase 6 1/5 th the rnaase concentration of E. Coli + e coli extract 2 protein_Ribo 12 + e coli extract 2 protein_RNAP 6 + e coli extract 2 protein_RNAase 3 ktx 0.05 transcripts / second per polymerase assuming 50nt/s and transcript length of 1000 ktl 0.05 proteins / second per ribosome assuming 15aa/s and protein length of 300 cooperativity 2 Seems like a good default diff --git a/examples/temp_sbml_file.xml b/examples/temp_sbml_file.xml deleted file mode 100644 index a03617ac..00000000 --- a/examples/temp_sbml_file.xml +++ /dev/null @@ -1,70 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - type=massaction k=3.0 - - - - - - - - - - - - k - m1_A_attribute - - - - - - - - - - type=massaction k=1.4 - - - - - - - - - - - - - k - m1_B - - - - - - - - - - diff --git a/index.rst b/index.rst new file mode 100644 index 00000000..df79be72 --- /dev/null +++ b/index.rst @@ -0,0 +1,20 @@ +.. BioCRNpyler documentation master file, created by + sphinx-quickstart on Wed Jul 29 22:40:30 2020. + You can adapt this file completely to your liking, but it should at least + contain the root `toctree` directive. + +Welcome to BioCRNpyler's documentation! +======================================= + +.. toctree:: + :maxdepth: 2 + :caption: Contents: + + + +Indices and tables +================== + +* :ref:`genindex` +* :ref:`modindex` +* :ref:`search` diff --git a/make.bat b/make.bat new file mode 100644 index 00000000..922152e9 --- /dev/null +++ b/make.bat @@ -0,0 +1,35 @@ +@ECHO OFF + +pushd %~dp0 + +REM Command file for Sphinx documentation + +if "%SPHINXBUILD%" == "" ( + set SPHINXBUILD=sphinx-build +) +set SOURCEDIR=. +set BUILDDIR=_build + +if "%1" == "" goto help + +%SPHINXBUILD% >NUL 2>NUL +if errorlevel 9009 ( + echo. + echo.The 'sphinx-build' command was not found. Make sure you have Sphinx + echo.installed, then set the SPHINXBUILD environment variable to point + echo.to the full path of the 'sphinx-build' executable. Alternatively you + echo.may add the Sphinx directory to PATH. + echo. + echo.If you don't have Sphinx installed, grab it from + echo.http://sphinx-doc.org/ + exit /b 1 +) + +%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% +goto end + +:help +%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% + +:end +popd diff --git a/pytest.ini b/pytest.ini index 6aba9665..2edf408a 100644 --- a/pytest.ini +++ b/pytest.ini @@ -4,4 +4,4 @@ minversion = 5.4 addopts = --nbval-lax --cov=biocrnpyler testpaths = Tests - examples \ No newline at end of file + examples diff --git a/setup.py b/setup.py index 566ff245..ff99d1e7 100644 --- a/setup.py +++ b/setup.py @@ -6,33 +6,41 @@ setup( name='biocrnpyler', - version='0.2.1', + version='0.9.0', author='BuildACell', - url='https://github.com/BuildACell/biocrnplyler/', + url='https://github.com/BuildACell/biocrnpyler/', description='A chemical reaction network compiler for generating large biological circuit models', long_description=long_description, packages=['biocrnpyler'], classifiers=[ - 'Development Status :: 3 - Alpha', + 'Development Status :: 4 - Beta', 'Intended Audience :: Science/Research', - 'Intended Audience :: Developers', 'License :: OSI Approved :: BSD License', - 'Programming Language :: Python :: 3', 'Programming Language :: Python :: 3.6', 'Topic :: Software Development', 'Topic :: Scientific/Engineering', - 'Operating System :: POSIX', - 'Operating System :: Unix' - 'Operating System :: MacOS' + 'Operating System :: OS Independent', ], install_requires=[ - 'python-libsbml', - 'numpy', - 'matplotlib<=3.2.2', - 'networkx', - 'bokeh==1.4.0', - 'fa2', - ], + "python-libsbml", + ], + extras_require = { + "all": [ + "numpy", + "matplotlib", + "networkx", + "bokeh", + "fa2" + ] + }, setup_requires=["pytest-runner"], + python_requires='>=3.6', + keywords="SBML synthetic biology modeling Chemical Reaction Network CRN model", tests_require=["pytest", "pytest-cov", "nbval"], + project_urls={ + 'Documentation': 'https://readthedocs.org/projects/biocrnpyler/', + 'Funding': 'http://www.cds.caltech.edu/~murray/wiki/index.php?title=Developing_Standardized_Cell-Free_Platforms_for_Rapid_Prototyping_of_Synthetic_Biology_Circuits_and_Pathways', + 'Source': 'https://github.com/BuildACell/biocrnpyler', + 'Tracker': 'https://github.com/BuildACell/BioCRNPyler/issues', + }, # give an installation message about bioscrape / roadrunner. ) diff --git a/temp_sbml_file.xml b/temp_sbml_file.xml deleted file mode 100644 index d6355df1..00000000 --- a/temp_sbml_file.xml +++ /dev/null @@ -1,65 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - type=proportionalhillpositive k=1.0 K=10.0 n=2 s1=protein_A d=dna_G - - - - - - - - - - - - - - - k - dna_G - - - protein_A - n - - - - - - - protein_A - n - - K - - - - - - - - - - - - -