From 27d476b10582cc4a0481e9452a0d31cdb2e434a1 Mon Sep 17 00:00:00 2001 From: Eran Date: Thu, 15 Feb 2024 09:23:56 -0500 Subject: [PATCH] progress on demo --- builder/__init__.py | 2 +- builder/builder_api.py | 52 +-- notebooks/demo.ipynb | 722 +++++++++++++++++++++++++---------------- 3 files changed, 453 insertions(+), 323 deletions(-) diff --git a/builder/__init__.py b/builder/__init__.py index 299bced..ec81090 100644 --- a/builder/__init__.py +++ b/builder/__init__.py @@ -1,2 +1,2 @@ from builder.builder_api import Builder -from process_bigraph.composite import Process, Step, Composite +from process_bigraph.composite import Process, Step, Composite, ProcessTypes diff --git a/builder/builder_api.py b/builder/builder_api.py index c29e4bf..373de6d 100644 --- a/builder/builder_api.py +++ b/builder/builder_api.py @@ -82,7 +82,7 @@ def merge_dicts(original, new): class Builder(dict): - def __init__(self, tree=None, schema=None, parent=None, core=None): + def __init__(self, tree=None, schema=None, core=None, parent=None): super().__init__() self.builder_tree = builder_tree_from_dict(tree) self.schema = schema or {} # TODO -- need to track schema @@ -135,6 +135,9 @@ def decorator(cls): else: raise TypeError(f"Unsupported address type for {process_name}: {type(address)}. Registration failed.") + def register_type(self, key, schema): + self.core.type_registry.register(key, schema) + def top(self): # recursively get the top parent if self.parent: @@ -158,8 +161,8 @@ def __setitem__(self, keys, value): self.builder_tree[first_key].__setitem__(remaining, value) elif isinstance(value, dict): self.builder_tree[first_key] = Builder(tree=value, - core=self.core, - schema=self.schema.get(first_key)) + schema=self.schema.get(first_key), + core=self.core) else: self.builder_tree[first_key] = value @@ -173,7 +176,7 @@ def __getitem__(self, keys): first_key = keys[0] if first_key not in self.builder_tree: self.builder_tree[first_key] = Builder( - parent=self, core=self.core, schema=self.schema.get(first_key, {})) + parent=self, schema=self.schema.get(first_key, {}), core=self.core) remaining = keys[1:] if len(remaining) > 0: @@ -216,7 +219,7 @@ def add_process( self.schema, state = self.core.complete(initial_schema, initial_state) self.builder_tree = builder_tree_from_dict(state) - # # complete the composite + # complete the composite # self.complete() def complete(self): @@ -239,22 +242,22 @@ def connect_all(self): if v.get('_type') in EDGE_KEYS: for port in self.schema[k]['_inputs'].keys(): if port not in v.get('inputs', {}): - self.builder_tree[k].connect(port=port, target=[port]) + self[k].connect(port=port, target=[port]) for port in self.schema[k]['_outputs'].keys(): if port not in v.get('outputs', {}): - self.builder_tree[k].connect(port=port, target=[port]) - else: - pass - # v.connect_all() + self[k].connect(port=port, target=[port]) + elif isinstance(v, Builder): + v.connect_all() # TODO -- propagate down def connect(self, port=None, target=None): assert self.core.check('edge', self.get_tree()) # self.complete() if port in self.schema['_inputs']: - self.builder_tree['inputs'][port] = target + self['inputs'][port] = target if port in self.schema['_outputs']: - self.builder_tree['outputs'][port] = target + self['outputs'][port] = target + def document(self): doc = self.core.serialize( @@ -390,18 +393,18 @@ def build_gillespie(): ## visualize part-way through build gillespie.visualize(filename='bigraph1', out_dir='out') + # gillespie.connect_all() # This can maybe be used to connect all ports to stores of the same name? gillespie['event_process'].connect(port='DNA', target=['DNA_store']) gillespie['event_process'].connect(port='mRNA', target=['mRNA_store']) gillespie['interval_process'].connect(port='DNA', target=['DNA_store']) gillespie['interval_process'].connect(port='mRNA', target=['mRNA_store']) gillespie['interval_process'].connect(port='interval', target=['interval_store']) - # gillespie.complete() + gillespie.complete() ## set some states gillespie['DNA_store'] = {'A gene': 2.0, 'B gene': 1.0} # TODO this should check the type gillespie['mRNA_store'] = {'A mRNA': 0.0, 'B mRNA': 0.0} - # gillespie.connect_all() # This can maybe be used to connect all ports to stores of the same name? gillespie.complete() gillespie.compile() @@ -416,8 +419,6 @@ def build_gillespie(): # gillespie['event_process'].emit(port='mRNA') # this should turn on an emit from this port # gillespie['interval_process'].emit(port='interval') - - # TODO: move states from one location to another. # TODO: add custom types # TODO: add reactions, apply reactions to bigraph @@ -465,25 +466,6 @@ def schema(self): def update(self, state, interval): return {'C': state['A'] + state['B']} - # b.register('toy', Toy) - # print(b.list_types()) - # - # b['toy'].add_process(name='toy') - # - # # b.tree - # ports = b['toy'].ports() - # print(ports) - # # b.plot(filename='toy[1]') - # - # b['toy'].connect(port='A', target=['A_store']) - # b['A_store'] = 2.3 - # b['toy'].connect(port='B', target=['B_store']) - # - # # plot the bigraph - # b.visualize(filename='toy[2]') - # - # b.write(filename='toy[2]', outdir='out') - if __name__ == '__main__': diff --git a/notebooks/demo.ipynb b/notebooks/demo.ipynb index debda1f..cc54d7e 100644 --- a/notebooks/demo.ipynb +++ b/notebooks/demo.ipynb @@ -1,5 +1,13 @@ { "cells": [ + { + "cell_type": "markdown", + "id": "808b6a4b-0894-4a8e-99d8-bf11b3164b6a", + "metadata": {}, + "source": [ + "# Bigraph-Builder Demo" + ] + }, { "cell_type": "code", "execution_count": 1, @@ -12,12 +20,39 @@ }, "outputs": [], "source": [ + "# imports\n", "from builder import Builder, Process" ] }, + { + "cell_type": "markdown", + "id": "a403d619-4dbe-49cc-8f24-29a83e31fe15", + "metadata": {}, + "source": [ + "## Initialize the builder" + ] + }, { "cell_type": "code", "execution_count": 2, + "id": "b6260555-2bad-4834-adc5-e6d358063579", + "metadata": {}, + "outputs": [], + "source": [ + "b = Builder()" + ] + }, + { + "cell_type": "markdown", + "id": "dd85f98e-c5e3-467b-97ab-1ced7e810a17", + "metadata": {}, + "source": [ + "### register new types" + ] + }, + { + "cell_type": "code", + "execution_count": 3, "id": "30297af1-2d65-43d9-9ab7-0589d94a8cfe", "metadata": { "ExecuteTime": { @@ -27,12 +62,31 @@ }, "outputs": [], "source": [ - "b = Builder()" + "b.register_type(\n", + " 'default 1', {\n", + " '_inherit': 'float',\n", + " '_default': 1.0})" + ] + }, + { + "cell_type": "markdown", + "id": "4f7cb796-ae5f-4209-b81c-dec1544f0840", + "metadata": {}, + "source": [ + "## Register some processes" + ] + }, + { + "cell_type": "markdown", + "id": "603e75fd-7b86-4e4c-9e95-adb9faf9668b", + "metadata": {}, + "source": [ + "### list built-in processes" ] }, { "cell_type": "code", - "execution_count": 3, + "execution_count": 4, "id": "979e0bd85a31d4b0", "metadata": { "ExecuteTime": { @@ -49,7 +103,7 @@ "name": "stdout", "output_type": "stream", "text": [ - "['ram-emitter', 'console-emitter']\n" + "['console-emitter', 'ram-emitter']\n" ] } ], @@ -57,101 +111,166 @@ "b.list_processes()" ] }, + { + "cell_type": "markdown", + "id": "9710444c-97c5-484c-83b0-8d82c3fdb92f", + "metadata": {}, + "source": [ + "### register by passing in process class" + ] + }, { "cell_type": "code", - "execution_count": 4, + "execution_count": 5, "id": "5bff2ea4-42f9-430e-b1cc-f0581510ec8d", "metadata": {}, "outputs": [], "source": [ - "from process_bigraph.experiments.minimal_gillespie import GillespieEvent , GillespieInterval\n", - "b.register_process('GillespieEvent', GillespieEvent)\n", - "b.register_process('GillespieInterval', GillespieInterval)" + "from process_bigraph.experiments.minimal_gillespie import GillespieEvent\n", + "b.register_process('GillespieEvent', GillespieEvent)" ] }, { - "cell_type": "code", - "execution_count": 5, - "id": "40cde984-cfdf-4571-af9c-3a3755e3763c", + "cell_type": "markdown", + "id": "c3635047-66dd-4c80-85ea-481c74da2a86", "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "['GillespieInterval', 'ram-emitter', 'console-emitter', 'GillespieEvent']\n" - ] - } - ], "source": [ - "b.list_processes()" + "### register by address" ] }, { "cell_type": "code", "execution_count": 6, - "id": "503863ee-0a58-44b3-accc-20e0167b947b", + "id": "f2893d4a-c13a-4d95-b85e-d5e9dce53a89", "metadata": {}, "outputs": [], "source": [ - "## add processes\n", - "b['event_process'].add_process(\n", - " name='GillespieEvent',\n", - " kdeg=1.0, # kwargs fill parameters in the config\n", + "b.register_process(\n", + " 'GillespieInterval',\n", + " address='local:!process_bigraph.experiments.minimal_gillespie.GillespieInterval', # currently only supports local addresses\n", ")" ] }, + { + "cell_type": "markdown", + "id": "731974c5-b470-4ddf-a037-4d4aeebc7b42", + "metadata": {}, + "source": [ + "### register with decorator" + ] + }, { "cell_type": "code", "execution_count": 7, - "id": "b094f1e5-5202-48d0-8bdd-57bbdded7fd1", + "id": "aec69dcc-471e-4c18-b22b-824cfe440e79", "metadata": {}, "outputs": [], "source": [ - "# b.compile()" + "@b.register_process('toy')\n", + "class Toy(Process):\n", + " config_schema = {\n", + " 'A': 'float',\n", + " 'B': 'float',\n", + " }\n", + "\n", + " def __init__(self, config, core):\n", + " super().__init__(config, core)\n", + "\n", + " def schema(self):\n", + " return {\n", + " 'inputs': {\n", + " 'A': 'float',\n", + " 'B': 'float'},\n", + " 'outputs': {\n", + " 'C': 'float'}\n", + " }\n", + "\n", + " def update(self, state, interval):\n", + " update = {\n", + " 'C': state['A'] + state['B']\n", + " }\n", + " return update\n" + ] + }, + { + "cell_type": "markdown", + "id": "a108cbf0-a594-41d4-996a-de9bf9b6aeea", + "metadata": {}, + "source": [ + "### list registered processes" ] }, { "cell_type": "code", "execution_count": 8, - "id": "5ea31425-a8bb-45c3-a31d-77714cc8c137", + "id": "40cde984-cfdf-4571-af9c-3a3755e3763c", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "{\n", - "'_inputs': {},\n", - "'_outputs': {}\n", - "}\n" + "['GillespieEvent', 'console-emitter', 'ram-emitter', 'toy', 'GillespieInterval']\n" ] } ], "source": [ - "b['event_process'].ports(True)" + "b.list_processes()" + ] + }, + { + "cell_type": "markdown", + "id": "dfa2d764-8cdb-4a1e-84c5-fd81cc4e6afe", + "metadata": {}, + "source": [ + "## Add processes to the bigraph" ] }, { "cell_type": "code", "execution_count": 9, - "id": "6e496c34-72a4-4197-aadc-1f95c031d743", + "id": "503863ee-0a58-44b3-accc-20e0167b947b", "metadata": {}, "outputs": [], "source": [ - "# b.schema" + "## add processes\n", + "b['event_process'].add_process(\n", + " name='GillespieEvent',\n", + " kdeg=1.0, # kwargs fill parameters in the config\n", + ")" ] }, { "cell_type": "code", "execution_count": 10, - "id": "da4365f0-7a55-4654-a21b-35a5b145b52d", + "id": "b094f1e5-5202-48d0-8bdd-57bbdded7fd1", "metadata": {}, "outputs": [ { "data": { + "image/svg+xml": [ + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "bigraph\n", + "\n", + "\n", + "\n", + "('event_process',)\n", + "\n", + "event_process\n", + "\n", + "\n", + "\n" + ], "text/plain": [ - "{}" + "" ] }, "execution_count": 10, @@ -160,12 +279,57 @@ } ], "source": [ - "b['event_process'].schema" + "b.visualize()" + ] + }, + { + "cell_type": "markdown", + "id": "0238392e-5d1f-403d-98c9-785576a0d91b", + "metadata": {}, + "source": [ + "### print ports" ] }, { "cell_type": "code", "execution_count": 11, + "id": "5ea31425-a8bb-45c3-a31d-77714cc8c137", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "{\n", + "'_inputs': {\n", + " 'mRNA': 'map[float]',\n", + " 'DNA': {\n", + " 'A gene': 'float',\n", + " 'B gene': 'float'\n", + " }\n", + "},\n", + "'_outputs': {\n", + " 'mRNA': 'map[float]'\n", + "}\n", + "}\n" + ] + } + ], + "source": [ + "b['event_process'].ports(True)" + ] + }, + { + "cell_type": "markdown", + "id": "8068e0af-ebdd-4f01-8c54-4fb3b07fc21e", + "metadata": {}, + "source": [ + "### connect ports" + ] + }, + { + "cell_type": "code", + "execution_count": 12, "id": "c9f462bb-5316-4724-aa8e-b3b71eb379b2", "metadata": {}, "outputs": [ @@ -181,30 +345,32 @@ " 'ktsc': 5.0\n", " },\n", " 'inputs': {\n", - " 'mRNA': ['mRNA_store']\n", + " 'mRNA': ['mRNA_store'],\n", + " 'DNA': ['DNA_store']\n", " },\n", " 'outputs': {\n", " 'mRNA': ['mRNA_store']\n", " },\n", - " 'instance': ,\n", + " 'instance': ,\n", " 'interval': 1.0\n", "}\n", "}" ] }, - "execution_count": 11, + "execution_count": 12, "metadata": {}, "output_type": "execute_result" } ], "source": [ "b['event_process'].connect(port='mRNA', target=['mRNA_store'])\n", + "b['event_process'].connect(port='DNA', target=['DNA_store'])\n", "b" ] }, { "cell_type": "code", - "execution_count": 12, + "execution_count": 13, "id": "79809baf-1d87-475a-b85f-3729f4716cb4", "metadata": {}, "outputs": [ @@ -217,45 +383,80 @@ "\n", "\n", - "\n", - "\n", + "\n", + "\n", "bigraph\n", - "\n", + "\n", "\n", "\n", "('mRNA_store',)\n", - "\n", - "mRNA_store\n", + "\n", + "mRNA_store\n", "\n", "\n", - "\n", + "\n", "('event_process',)\n", - "\n", - "event_process\n", + "\n", + "event_process\n", "\n", "\n", - "\n", + "\n", "('mRNA_store',)->('event_process',)\n", - "\n", - "\n", - "mRNA\n", + "\n", + "\n", + "mRNA\n", "\n", "\n", - "\n", + "\n", "('mRNA_store',)->('event_process',)\n", - "\n", - "\n", - "mRNA\n", + "\n", + "\n", + "mRNA\n", + "\n", + "\n", + "\n", + "('DNA_store',)\n", + "\n", + "DNA_store\n", + "\n", + "\n", + "\n", + "('DNA_store', 'A gene')\n", + "\n", + "A gene\n", + "\n", + "\n", + "\n", + "('DNA_store',)->('DNA_store', 'A gene')\n", + "\n", + "\n", + "\n", + "\n", + "('DNA_store', 'B gene')\n", + "\n", + "B gene\n", + "\n", + "\n", + "\n", + "('DNA_store',)->('DNA_store', 'B gene')\n", + "\n", + "\n", + "\n", + "\n", + "('DNA_store',)->('event_process',)\n", + "\n", + "\n", + "DNA\n", "\n", "\n", "\n" ], "text/plain": [ - "" + "" ] }, - "execution_count": 12, + "execution_count": 13, "metadata": {}, "output_type": "execute_result" } @@ -264,26 +465,13 @@ "b.visualize()" ] }, - { - "cell_type": "code", - "execution_count": 13, - "id": "72088795-49c9-4e28-b539-1bdacd70ea91", - "metadata": {}, - "outputs": [], - "source": [ - "# from builder.builder_api import Builder, dict_from_builder_tree\n", - "# tree_dict = dict_from_builder_tree(b.tree)\n", - "\n", - "# tree_dict" - ] - }, { "cell_type": "code", "execution_count": 14, - "id": "1ee84904801a9ab", + "id": "f02c15797bdb73b8", "metadata": { "ExecuteTime": { - "start_time": "2024-01-21T21:29:21.990417Z" + "start_time": "2024-01-21T21:29:21.997588Z" }, "collapsed": false, "jupyter": { @@ -292,121 +480,19 @@ }, "outputs": [], "source": [ - "@b.register_process('toy')\n", - "class Toy(Process):\n", - " config_schema = {\n", - " 'A': 'float',\n", - " 'B': 'float',\n", - " }\n", - "\n", - " def __init__(self, config, core):\n", - " super().__init__(config, core)\n", - "\n", - " def schema(self):\n", - " return {\n", - " 'inputs': {\n", - " 'A': 'float',\n", - " 'B': 'float'},\n", - " 'outputs': {\n", - " 'C': 'float'}\n", - " }\n", - "\n", - " def update(self, state, interval):\n", - " update = {\n", - " 'C': state['A'] + state['B']\n", - " }\n", - " return update\n" + "b['interval_process'].add_process(\n", + " name='GillespieInterval',\n", + " # inputs={'port_id': ['store']} # we should be able to set the wires directly like this\n", + ")" ] }, { "cell_type": "code", "execution_count": 15, - "id": "dae8ca8db70c4845", - "metadata": { - "ExecuteTime": { - "start_time": "2024-01-21T21:29:21.992233Z" - }, - "collapsed": false, - "jupyter": { - "outputs_hidden": false - } - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "['toy', 'console-emitter', 'GillespieEvent', 'ram-emitter', 'GillespieInterval']\n" - ] - } - ], - "source": [ - "b.list_processes()" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "2694ee21-d3b6-4c5d-9dbf-ea2348c97797", - "metadata": {}, - "outputs": [], - "source": [] - }, - { - "cell_type": "code", - "execution_count": 16, - "id": "8b1f49a78de17642", - "metadata": { - "ExecuteTime": { - "end_time": "2024-01-21T21:29:21.994480Z", - "start_time": "2024-01-21T21:29:21.994063Z" - }, - "collapsed": false, - "jupyter": { - "outputs_hidden": false - } - }, - "outputs": [], - "source": [ - "b['toy'].add_process(name='toy')" - ] - }, - { - "cell_type": "code", - "execution_count": 17, - "id": "329e64816e8ff626", - "metadata": { - "ExecuteTime": { - "start_time": "2024-01-21T21:29:21.995413Z" - }, - "collapsed": false, - "jupyter": { - "outputs_hidden": false - } - }, - "outputs": [ - { - "data": { - "text/plain": [ - "{'_inputs': {}, '_outputs': {}}" - ] - }, - "execution_count": 17, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "b['toy'].ports()" - ] - }, - { - "cell_type": "code", - "execution_count": 18, - "id": "3b1dd8569f3bb67a", + "id": "aeb344bcd6a120ae", "metadata": { "ExecuteTime": { - "start_time": "2024-01-21T21:29:21.996690Z" + "start_time": "2024-01-21T21:29:21.998661Z" }, "collapsed": false, "jupyter": { @@ -423,51 +509,86 @@ "\n", "\n", - "\n", - "\n", + "\n", + "\n", "bigraph\n", - "\n", + "\n", "\n", "\n", "('mRNA_store',)\n", - "\n", - "mRNA_store\n", + "\n", + "mRNA_store\n", "\n", "\n", - "\n", + "\n", "('event_process',)\n", - "\n", - "event_process\n", + "\n", + "event_process\n", "\n", "\n", - "\n", + "\n", "('mRNA_store',)->('event_process',)\n", - "\n", - "\n", - "mRNA\n", + "\n", + "\n", + "mRNA\n", "\n", "\n", - "\n", + "\n", "('mRNA_store',)->('event_process',)\n", - "\n", - "\n", - "mRNA\n", + "\n", + "\n", + "mRNA\n", "\n", - "\n", + "\n", + "\n", + "('DNA_store',)\n", + "\n", + "DNA_store\n", + "\n", + "\n", "\n", - "('toy',)\n", - "\n", - "toy\n", + "('DNA_store', 'A gene')\n", + "\n", + "A gene\n", + "\n", + "\n", + "\n", + "('DNA_store',)->('DNA_store', 'A gene')\n", + "\n", + "\n", + "\n", + "\n", + "('DNA_store', 'B gene')\n", + "\n", + "B gene\n", + "\n", + "\n", + "\n", + "('DNA_store',)->('DNA_store', 'B gene')\n", + "\n", + "\n", + "\n", + "\n", + "('DNA_store',)->('event_process',)\n", + "\n", + "\n", + "DNA\n", + "\n", + "\n", + "\n", + "('interval_process',)\n", + "\n", + "interval_process\n", "\n", "\n", "\n" ], "text/plain": [ - "" + "" ] }, - "execution_count": 18, + "execution_count": 15, "metadata": {}, "output_type": "execute_result" } @@ -478,103 +599,110 @@ }, { "cell_type": "code", - "execution_count": 19, - "id": "f02c15797bdb73b8", - "metadata": { - "ExecuteTime": { - "start_time": "2024-01-21T21:29:21.997588Z" - }, - "collapsed": false, - "jupyter": { - "outputs_hidden": false + "execution_count": 24, + "id": "a5a1f48a-41aa-4768-b931-ad268495d836", + "metadata": {}, + "outputs": [ + { + "ename": "TypeError", + "evalue": "'str' object does not support item assignment", + "output_type": "error", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mTypeError\u001b[0m Traceback (most recent call last)", + "Cell \u001b[0;32mIn[24], line 1\u001b[0m\n\u001b[0;32m----> 1\u001b[0m \u001b[43mb\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mconnect_all\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\n", + "File \u001b[0;32m~/code/bigraph-builder/builder/builder_api.py:238\u001b[0m, in \u001b[0;36mBuilder.connect_all\u001b[0;34m(self)\u001b[0m\n\u001b[1;32m 237\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21mconnect_all\u001b[39m(\u001b[38;5;28mself\u001b[39m):\n\u001b[0;32m--> 238\u001b[0m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mcomplete\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m \u001b[38;5;66;03m# this will get the schema\u001b[39;00m\n\u001b[1;32m 239\u001b[0m tree \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mget_tree()\n\u001b[1;32m 240\u001b[0m \u001b[38;5;28;01mfor\u001b[39;00m k, v \u001b[38;5;129;01min\u001b[39;00m tree\u001b[38;5;241m.\u001b[39mitems():\n", + "File \u001b[0;32m~/code/bigraph-builder/builder/builder_api.py:230\u001b[0m, in \u001b[0;36mBuilder.complete\u001b[0;34m(self)\u001b[0m\n\u001b[1;32m 228\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[1;32m 229\u001b[0m schema, tree \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mcore\u001b[38;5;241m.\u001b[39mcomplete(\u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mschema, \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mget_tree())\n\u001b[0;32m--> 230\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mschema \u001b[38;5;241m=\u001b[39m \u001b[43mmerge_dicts\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mschema\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mschema\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 231\u001b[0m \u001b[38;5;66;03m# self.builder_tree = merge_dicts(self.builder_tree, builder_tree_from_dict(tree))\u001b[39;00m\n\u001b[1;32m 232\u001b[0m \n\u001b[1;32m 233\u001b[0m \u001b[38;5;66;03m# TODO -- we may want to go through and update the existing schema and tree rather than completely redoing them...\u001b[39;00m\n\u001b[1;32m 234\u001b[0m \u001b[38;5;66;03m# self.schema = schema\u001b[39;00m\n\u001b[1;32m 235\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mbuilder_tree \u001b[38;5;241m=\u001b[39m builder_tree_from_dict(tree)\n", + "File \u001b[0;32m~/code/bigraph-builder/builder/builder_api.py:77\u001b[0m, in \u001b[0;36mmerge_dicts\u001b[0;34m(original, new)\u001b[0m\n\u001b[1;32m 75\u001b[0m original[k] \u001b[38;5;241m=\u001b[39m v\n\u001b[1;32m 76\u001b[0m \u001b[38;5;28;01melif\u001b[39;00m \u001b[38;5;28misinstance\u001b[39m(v, \u001b[38;5;28mdict\u001b[39m):\n\u001b[0;32m---> 77\u001b[0m original[k] \u001b[38;5;241m=\u001b[39m \u001b[43mmerge_dicts\u001b[49m\u001b[43m(\u001b[49m\u001b[43moriginal\u001b[49m\u001b[43m[\u001b[49m\u001b[43mk\u001b[49m\u001b[43m]\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mv\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 78\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[1;32m 79\u001b[0m original[k] \u001b[38;5;241m=\u001b[39m v\n", + "File \u001b[0;32m~/code/bigraph-builder/builder/builder_api.py:75\u001b[0m, in \u001b[0;36mmerge_dicts\u001b[0;34m(original, new)\u001b[0m\n\u001b[1;32m 73\u001b[0m \u001b[38;5;28;01mfor\u001b[39;00m k, v \u001b[38;5;129;01min\u001b[39;00m new\u001b[38;5;241m.\u001b[39mitems():\n\u001b[1;32m 74\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m k \u001b[38;5;129;01mnot\u001b[39;00m \u001b[38;5;129;01min\u001b[39;00m original:\n\u001b[0;32m---> 75\u001b[0m \u001b[43moriginal\u001b[49m\u001b[43m[\u001b[49m\u001b[43mk\u001b[49m\u001b[43m]\u001b[49m \u001b[38;5;241m=\u001b[39m v\n\u001b[1;32m 76\u001b[0m \u001b[38;5;28;01melif\u001b[39;00m \u001b[38;5;28misinstance\u001b[39m(v, \u001b[38;5;28mdict\u001b[39m):\n\u001b[1;32m 77\u001b[0m original[k] \u001b[38;5;241m=\u001b[39m merge_dicts(original[k], v)\n", + "\u001b[0;31mTypeError\u001b[0m: 'str' object does not support item assignment" + ] } - }, - "outputs": [], + ], "source": [ - "b['toy'].connect(port='A', target='A_store')\n", - "# b['toy'].connect(port='B', target='B_store') # TODO -- compile is trying to connect A at the wrong level??\n", - "# b['toy'].connect(port='C', target='C_store')" + "b.connect_all()" ] }, { "cell_type": "code", - "execution_count": 21, - "id": "aeb344bcd6a120ae", - "metadata": { - "ExecuteTime": { - "start_time": "2024-01-21T21:29:21.998661Z" - }, - "collapsed": false, - "jupyter": { - "outputs_hidden": false - } - }, + "execution_count": 22, + "id": "6e00749f-03b8-496e-9a10-106dbac3713f", + "metadata": {}, "outputs": [ { "data": { - "image/svg+xml": [ - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "bigraph\n", - "\n", - "\n", - "\n", - "('mRNA_store',)\n", - "\n", - "mRNA_store\n", - "\n", - "\n", - "\n", - "('event_process',)\n", - "\n", - "event_process\n", - "\n", - "\n", - "\n", - "('mRNA_store',)->('event_process',)\n", - "\n", - "\n", - "mRNA\n", - "\n", - "\n", - "\n", - "('mRNA_store',)->('event_process',)\n", - "\n", - "\n", - "mRNA\n", - "\n", - "\n", - "\n", - "('toy',)\n", - "\n", - "toy\n", - "\n", - "\n", - "\n" - ], "text/plain": [ - "" + "{'event_process': {\n", + " '_type': 'process',\n", + " 'address': 'local:GillespieEvent',\n", + " 'config': {\n", + " 'kdeg': 1.0,\n", + " 'ktsc': 5.0\n", + " },\n", + " 'inputs': {\n", + " 'mRNA': ['mRNA_store'],\n", + " 'DNA': ['DNA_store']\n", + " },\n", + " 'outputs': {\n", + " 'mRNA': ['mRNA_store']\n", + " },\n", + " 'instance': ,\n", + " 'interval': 1.0\n", + " },\n", + " 'interval_process': {\n", + " '_type': 'process',\n", + " 'address': 'local:GillespieInterval',\n", + " 'config': {\n", + " 'ktsc': 5.0,\n", + " 'kdeg': 0.1\n", + " },\n", + " 'inputs': {},\n", + " 'outputs': {},\n", + " 'instance': ,\n", + " 'interval': 1.0\n", + " }}" ] }, - "execution_count": 21, + "execution_count": 22, "metadata": {}, "output_type": "execute_result" } ], "source": [ - "b.visualize()" + "b.builder_tree" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 23, + "id": "e9a69f36-154c-416e-b00c-5df0726be49e", + "metadata": {}, + "outputs": [ + { + "ename": "KeyError", + "evalue": "'DNA'", + "output_type": "error", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mKeyError\u001b[0m Traceback (most recent call last)", + "Cell \u001b[0;32mIn[23], line 1\u001b[0m\n\u001b[0;32m----> 1\u001b[0m \u001b[43mb\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mcompile\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\n", + "File \u001b[0;32m~/code/bigraph-builder/builder/builder_api.py:289\u001b[0m, in \u001b[0;36mBuilder.compile\u001b[0;34m(self)\u001b[0m\n\u001b[1;32m 286\u001b[0m tree \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mget_tree()\n\u001b[1;32m 287\u001b[0m schema, tree \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mcore\u001b[38;5;241m.\u001b[39mcomplete(\n\u001b[1;32m 288\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mschema, tree)\n\u001b[0;32m--> 289\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mcompiled_composite \u001b[38;5;241m=\u001b[39m \u001b[43mComposite\u001b[49m\u001b[43m(\u001b[49m\n\u001b[1;32m 290\u001b[0m \u001b[43m \u001b[49m\u001b[43m{\u001b[49m\u001b[38;5;124;43m'\u001b[39;49m\u001b[38;5;124;43mstate\u001b[39;49m\u001b[38;5;124;43m'\u001b[39;49m\u001b[43m:\u001b[49m\u001b[43m \u001b[49m\u001b[43mtree\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;124;43m'\u001b[39;49m\u001b[38;5;124;43mcomposition\u001b[39;49m\u001b[38;5;124;43m'\u001b[39;49m\u001b[43m:\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mschema\u001b[49m\u001b[43m}\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 291\u001b[0m \u001b[43m \u001b[49m\u001b[43mcore\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mcore\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 293\u001b[0m \u001b[38;5;66;03m# reset the builder tree\u001b[39;00m\n\u001b[1;32m 294\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mupdate_tree(\u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mcompiled_composite\u001b[38;5;241m.\u001b[39mcomposition, \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mcompiled_composite\u001b[38;5;241m.\u001b[39mstate)\n", + "File \u001b[0;32m~/code/process-bigraph/process_bigraph/composite.py:834\u001b[0m, in \u001b[0;36mComposite.__init__\u001b[0;34m(self, config, core)\u001b[0m\n\u001b[1;32m 831\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mreset_step_state(\u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mstep_paths)\n\u001b[1;32m 832\u001b[0m to_run \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mcycle_step_state()\n\u001b[0;32m--> 834\u001b[0m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mrun_steps\u001b[49m\u001b[43m(\u001b[49m\u001b[43mto_run\u001b[49m\u001b[43m)\u001b[49m\n", + "File \u001b[0;32m~/code/process-bigraph/process_bigraph/composite.py:1096\u001b[0m, in \u001b[0;36mComposite.run_steps\u001b[0;34m(self, step_paths)\u001b[0m\n\u001b[1;32m 1086\u001b[0m step \u001b[38;5;241m=\u001b[39m get_path(\n\u001b[1;32m 1087\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mstate,\n\u001b[1;32m 1088\u001b[0m step_path)\n\u001b[1;32m 1090\u001b[0m state \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mcore\u001b[38;5;241m.\u001b[39mview_edge(\n\u001b[1;32m 1091\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mcomposition,\n\u001b[1;32m 1092\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mstate,\n\u001b[1;32m 1093\u001b[0m step_path,\n\u001b[1;32m 1094\u001b[0m \u001b[38;5;124m'\u001b[39m\u001b[38;5;124minputs\u001b[39m\u001b[38;5;124m'\u001b[39m)\n\u001b[0;32m-> 1096\u001b[0m step_update \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mprocess_update\u001b[49m\u001b[43m(\u001b[49m\n\u001b[1;32m 1097\u001b[0m \u001b[43m \u001b[49m\u001b[43mstep_path\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 1098\u001b[0m \u001b[43m \u001b[49m\u001b[43mstep\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 1099\u001b[0m \u001b[43m \u001b[49m\u001b[43mstate\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 1100\u001b[0m \u001b[43m \u001b[49m\u001b[38;5;241;43m-\u001b[39;49m\u001b[38;5;241;43m1.0\u001b[39;49m\u001b[43m,\u001b[49m\n\u001b[1;32m 1101\u001b[0m \u001b[43m \u001b[49m\u001b[38;5;124;43m'\u001b[39;49m\u001b[38;5;124;43moutputs\u001b[39;49m\u001b[38;5;124;43m'\u001b[39;49m\u001b[43m)\u001b[49m\n\u001b[1;32m 1103\u001b[0m updates\u001b[38;5;241m.\u001b[39mappend(step_update)\n\u001b[1;32m 1105\u001b[0m update_paths \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mapply_updates(updates)\n", + "File \u001b[0;32m~/code/process-bigraph/process_bigraph/composite.py:884\u001b[0m, in \u001b[0;36mComposite.process_update\u001b[0;34m(self, path, process, states, interval, ports_key)\u001b[0m\n\u001b[1;32m 857\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21mprocess_update\u001b[39m(\n\u001b[1;32m 858\u001b[0m \u001b[38;5;28mself\u001b[39m,\n\u001b[1;32m 859\u001b[0m path,\n\u001b[0;32m (...)\u001b[0m\n\u001b[1;32m 862\u001b[0m interval,\n\u001b[1;32m 863\u001b[0m ports_key\u001b[38;5;241m=\u001b[39m\u001b[38;5;124m'\u001b[39m\u001b[38;5;124moutputs\u001b[39m\u001b[38;5;124m'\u001b[39m):\n\u001b[1;32m 865\u001b[0m \u001b[38;5;250m \u001b[39m\u001b[38;5;124;03m\"\"\"Start generating a process's update.\u001b[39;00m\n\u001b[1;32m 866\u001b[0m \n\u001b[1;32m 867\u001b[0m \u001b[38;5;124;03m This function is similar to :py:meth:`_invoke_process` except in\u001b[39;00m\n\u001b[0;32m (...)\u001b[0m\n\u001b[1;32m 882\u001b[0m \u001b[38;5;124;03m ``store``.\u001b[39;00m\n\u001b[1;32m 883\u001b[0m \u001b[38;5;124;03m \"\"\"\u001b[39;00m\n\u001b[0;32m--> 884\u001b[0m update \u001b[38;5;241m=\u001b[39m \u001b[43mprocess\u001b[49m\u001b[43m[\u001b[49m\u001b[38;5;124;43m'\u001b[39;49m\u001b[38;5;124;43minstance\u001b[39;49m\u001b[38;5;124;43m'\u001b[39;49m\u001b[43m]\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43minvoke\u001b[49m\u001b[43m(\u001b[49m\u001b[43mstates\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43minterval\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 886\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21mdefer_project\u001b[39m(update, args):\n\u001b[1;32m 887\u001b[0m schema, state, path \u001b[38;5;241m=\u001b[39m args\n", + "File \u001b[0;32m~/code/process-bigraph/process_bigraph/composite.py:401\u001b[0m, in \u001b[0;36mStep.invoke\u001b[0;34m(self, state, _)\u001b[0m\n\u001b[1;32m 400\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21minvoke\u001b[39m(\u001b[38;5;28mself\u001b[39m, state, _\u001b[38;5;241m=\u001b[39m\u001b[38;5;28;01mNone\u001b[39;00m):\n\u001b[0;32m--> 401\u001b[0m update \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mupdate\u001b[49m\u001b[43m(\u001b[49m\u001b[43mstate\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 402\u001b[0m sync \u001b[38;5;241m=\u001b[39m SyncUpdate(update)\n\u001b[1;32m 403\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m sync\n", + "File \u001b[0;32m~/code/process-bigraph/process_bigraph/experiments/minimal_gillespie.py:66\u001b[0m, in \u001b[0;36mGillespieInterval.update\u001b[0;34m(self, input)\u001b[0m\n\u001b[1;32m 64\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21mupdate\u001b[39m(\u001b[38;5;28mself\u001b[39m, \u001b[38;5;28minput\u001b[39m):\n\u001b[1;32m 65\u001b[0m \u001b[38;5;66;03m# retrieve the state values\u001b[39;00m\n\u001b[0;32m---> 66\u001b[0m g \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;43minput\u001b[39;49m\u001b[43m[\u001b[49m\u001b[38;5;124;43m'\u001b[39;49m\u001b[38;5;124;43mDNA\u001b[39;49m\u001b[38;5;124;43m'\u001b[39;49m\u001b[43m]\u001b[49m[\u001b[38;5;124m'\u001b[39m\u001b[38;5;124mA gene\u001b[39m\u001b[38;5;124m'\u001b[39m]\n\u001b[1;32m 67\u001b[0m c \u001b[38;5;241m=\u001b[39m \u001b[38;5;28minput\u001b[39m[\u001b[38;5;124m'\u001b[39m\u001b[38;5;124mmRNA\u001b[39m\u001b[38;5;124m'\u001b[39m][\u001b[38;5;124m'\u001b[39m\u001b[38;5;124mA mRNA\u001b[39m\u001b[38;5;124m'\u001b[39m]\n\u001b[1;32m 69\u001b[0m array_state \u001b[38;5;241m=\u001b[39m np\u001b[38;5;241m.\u001b[39marray([g, c])\n", + "\u001b[0;31mKeyError\u001b[0m: 'DNA'" + ] + } + ], + "source": [ + "b.compile()" + ] + }, + { + "cell_type": "code", + "execution_count": 18, "id": "c975aab012b2706f", "metadata": { "ExecuteTime": { @@ -585,14 +713,26 @@ "outputs_hidden": false } }, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "{}" + ] + }, + "execution_count": 18, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ - "b.document()" + "doc = b.document()\n", + "doc" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 17, "id": "752e43636bf9fd17", "metadata": { "ExecuteTime": { @@ -603,7 +743,15 @@ "outputs_hidden": false } }, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "File 'toy_bigraph' successfully written in 'out' directory.\n" + ] + } + ], "source": [ "b.write(filename='toy_bigraph')" ]