process-bigraph 0.0.17__tar.gz → 0.0.18__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (20) hide show
  1. {process-bigraph-0.0.17/process_bigraph.egg-info → process-bigraph-0.0.18}/PKG-INFO +6 -1
  2. {process-bigraph-0.0.17 → process-bigraph-0.0.18}/process_bigraph/composite.py +163 -88
  3. process-bigraph-0.0.18/process_bigraph/experiments/growth_division.py +207 -0
  4. {process-bigraph-0.0.17 → process-bigraph-0.0.18}/process_bigraph/tests.py +1 -1
  5. {process-bigraph-0.0.17 → process-bigraph-0.0.18/process_bigraph.egg-info}/PKG-INFO +6 -1
  6. {process-bigraph-0.0.17 → process-bigraph-0.0.18}/setup.py +1 -1
  7. process-bigraph-0.0.17/process_bigraph/experiments/growth_division.py +0 -66
  8. {process-bigraph-0.0.17 → process-bigraph-0.0.18}/AUTHORS.md +0 -0
  9. {process-bigraph-0.0.17 → process-bigraph-0.0.18}/LICENSE +0 -0
  10. {process-bigraph-0.0.17 → process-bigraph-0.0.18}/README.md +0 -0
  11. {process-bigraph-0.0.17 → process-bigraph-0.0.18}/process_bigraph/__init__.py +0 -0
  12. {process-bigraph-0.0.17 → process-bigraph-0.0.18}/process_bigraph/experiments/__init__.py +0 -0
  13. {process-bigraph-0.0.17 → process-bigraph-0.0.18}/process_bigraph/experiments/minimal_gillespie.py +0 -0
  14. {process-bigraph-0.0.17 → process-bigraph-0.0.18}/process_bigraph/experiments/parameter_scan.py +0 -0
  15. {process-bigraph-0.0.17 → process-bigraph-0.0.18}/process_bigraph/protocols.py +0 -0
  16. {process-bigraph-0.0.17 → process-bigraph-0.0.18}/process_bigraph.egg-info/SOURCES.txt +0 -0
  17. {process-bigraph-0.0.17 → process-bigraph-0.0.18}/process_bigraph.egg-info/dependency_links.txt +0 -0
  18. {process-bigraph-0.0.17 → process-bigraph-0.0.18}/process_bigraph.egg-info/requires.txt +0 -0
  19. {process-bigraph-0.0.17 → process-bigraph-0.0.18}/process_bigraph.egg-info/top_level.txt +0 -0
  20. {process-bigraph-0.0.17 → process-bigraph-0.0.18}/setup.cfg +0 -0
@@ -1,9 +1,12 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: process-bigraph
3
- Version: 0.0.17
3
+ Version: 0.0.18
4
+ Summary: UNKNOWN
4
5
  Home-page: https://github.com/vivarium-collective/process-bigraph
5
6
  Author: Ryan Spangler, Eran Agmon
6
7
  Author-email: ryan.spangler@gmail.com, agmon.eran@gmail.com
8
+ License: UNKNOWN
9
+ Platform: UNKNOWN
7
10
  Classifier: Development Status :: 3 - Alpha
8
11
  Classifier: Intended Audience :: Developers
9
12
  Classifier: License :: OSI Approved :: MIT License
@@ -70,3 +73,5 @@ diagraph of a whole-cell E. coli model.
70
73
  ## License
71
74
 
72
75
  Bigraph-schema is open-source software released under the [Apache 2 License](https://github.com/vivarium-collective/process-bigraph/blob/main/LICENSE).
76
+
77
+
@@ -7,12 +7,13 @@ Composite, Process, and Step classes
7
7
  import abc
8
8
  import copy
9
9
  import math
10
+ import types
10
11
  import collections
11
12
  from typing import Dict
12
13
 
13
14
 
14
15
  from bigraph_schema import Edge, TypeSystem, get_path, establish_path, set_path, deep_merge
15
- from bigraph_schema.registry import Registry, validate_merge
16
+ from bigraph_schema.registry import Registry, validate_merge, visit_method
16
17
 
17
18
  from process_bigraph.protocols import local_lookup, local_lookup_module
18
19
 
@@ -33,8 +34,50 @@ def check_process(schema, state, core):
33
34
  Edge)
34
35
 
35
36
 
36
- def divide_process(schema, value, core):
37
- return value
37
+ def fold_visit(schema, state, method, values, core):
38
+ visit = visit_method(
39
+ schema,
40
+ state,
41
+ method,
42
+ values,
43
+ core)
44
+
45
+ return visit
46
+
47
+
48
+ def divide_process(schema, state, values, core):
49
+ # daughter_configs must have a config per daughter
50
+
51
+ daughter_configs = values.get(
52
+ 'daughter_configs',
53
+ [{} for index in range(values['divisions'])])
54
+
55
+ if 'config' not in state:
56
+ return daughter_configs
57
+
58
+ existing_config = state['config']
59
+
60
+ divisions = []
61
+ for index in range(values['divisions']):
62
+ daughter_config = copy.deepcopy(
63
+ existing_config)
64
+ daughter_config = deep_merge(
65
+ daughter_config,
66
+ daughter_configs[index])
67
+
68
+ # TODO: provide a way to override inputs and outputs
69
+ daughter_state = {
70
+ 'address': state['address'],
71
+ 'config': daughter_config,
72
+ 'inputs': copy.deepcopy(state['inputs']),
73
+ 'outputs': copy.deepcopy(state['outputs'])}
74
+
75
+ if 'interval' in state:
76
+ daughter_state['interval'] = state['interval']
77
+
78
+ divisions.append(daughter_state)
79
+
80
+ return divisions
38
81
 
39
82
 
40
83
  def serialize_process(schema, value, core):
@@ -70,8 +113,8 @@ def deserialize_process(schema, encoded, core):
70
113
  :returns: The deserialized state with an instantiated process.
71
114
  """
72
115
  deserialized = encoded.copy()
73
- if 'address' not in encoded:
74
- import ipdb; ipdb.set_trace()
116
+ if 'address' not in deserialized:
117
+ return deserialized
75
118
 
76
119
  protocol, address = encoded['address'].split(':', 1)
77
120
 
@@ -154,6 +197,7 @@ process_types = {
154
197
  '_serialize': serialize_process,
155
198
  '_deserialize': deserialize_step,
156
199
  '_check': check_process,
200
+ '_fold': fold_visit,
157
201
  '_divide': divide_process,
158
202
  '_description': '',
159
203
  # TODO: support reference to type parameters from other states
@@ -167,11 +211,13 @@ process_types = {
167
211
  '_serialize': serialize_process,
168
212
  '_deserialize': deserialize_process,
169
213
  '_check': check_process,
214
+ '_fold': fold_visit,
170
215
  '_divide': divide_process,
171
216
  '_description': '',
172
217
  # TODO: support reference to type parameters from other states
173
218
  'interval': 'interval',
174
- }
219
+ 'address': 'protocol',
220
+ 'config': 'tree[any]'},
175
221
  }
176
222
 
177
223
 
@@ -187,8 +233,8 @@ def register_protocols(core):
187
233
 
188
234
 
189
235
  def register_emitters(core):
190
- core.process_registry.register('console-emitter', ConsoleEmitter)
191
- core.process_registry.register('ram-emitter', RAMEmitter)
236
+ core.register_process('console-emitter', ConsoleEmitter)
237
+ core.register_process('ram-emitter', RAMEmitter)
192
238
 
193
239
 
194
240
  class ProcessTypes(TypeSystem):
@@ -201,8 +247,10 @@ class ProcessTypes(TypeSystem):
201
247
  register_protocols(self)
202
248
  register_emitters(self)
203
249
 
250
+ self.register_process('composite', Composite)
204
251
 
205
- def register_process(name, process_data):
252
+
253
+ def register_process(self, name, process_data):
206
254
  self.process_registry.register(name, process_data)
207
255
 
208
256
 
@@ -227,19 +275,20 @@ class ProcessTypes(TypeSystem):
227
275
  key: value
228
276
  for key, value in state.items()
229
277
  if key.startswith('_')}
278
+
230
279
  state_schema = self.access(
231
280
  state_type)
232
281
 
233
- hydrated_state = self.deserialize(state_schema, state)
234
- top_state = set_path(
235
- top_state,
236
- path,
237
- hydrated_state)
282
+ hydrated_state = self.deserialize(
283
+ state_schema,
284
+ state)
238
285
 
239
- schema = set_path(
286
+ schema, top_state = self.set_slice(
240
287
  schema,
288
+ top_state,
241
289
  path,
242
- state_schema)
290
+ state_schema,
291
+ hydrated_state)
243
292
 
244
293
  # TODO: fix is_descendant
245
294
  # if core.type_registry.is_descendant('process', state_schema) or core.registry.is_descendant('step', state_schema):
@@ -252,13 +301,6 @@ class ProcessTypes(TypeSystem):
252
301
  subschema = port_schema.get(
253
302
  port_key, {})
254
303
 
255
- # _, schema = self.set_slice(
256
- # 'schema',
257
- # schema,
258
- # path + (f'_{port_key}',),
259
- # 'schema',
260
- # subschema)
261
-
262
304
  schema = set_path(
263
305
  schema,
264
306
  path + (f'_{port_key}',),
@@ -272,7 +314,7 @@ class ProcessTypes(TypeSystem):
272
314
  hydrated_state,
273
315
  ports,
274
316
  top_schema=schema,
275
- path=path[:-1])
317
+ path=path)
276
318
 
277
319
  elif '_type' in schema:
278
320
  hydrated_state = self.deserialize(schema, state)
@@ -295,21 +337,11 @@ class ProcessTypes(TypeSystem):
295
337
  pass
296
338
 
297
339
  else:
298
- type_schema = TYPE_SCHEMAS.get(str(type(state)), schema)
299
-
300
- peer = get_path(schema, path)
301
- destination = establish_path(
302
- peer,
303
- path[:-1],
304
- top=schema,
305
- cursor=path[:-1])
306
-
307
- path_key = path[-1]
308
- if path_key in destination:
309
- # TODO: validate
310
- pass
311
- else:
312
- destination[path_key] = type_schema
340
+ schema, top_state = super().infer_schema(
341
+ schema,
342
+ state,
343
+ top_state,
344
+ path)
313
345
 
314
346
  return schema, top_state
315
347
 
@@ -333,23 +365,32 @@ class ProcessTypes(TypeSystem):
333
365
 
334
366
  def initialize_edge_state(self, schema, path, edge):
335
367
  initial_state = edge['instance'].initial_state()
368
+ if not initial_state:
369
+ return initial_state
370
+
336
371
  input_ports = get_path(schema, path + ('_inputs',))
337
372
  output_ports = get_path(schema, path + ('_outputs',))
338
- ports = {'_inputs': input_ports, '_outputs': output_ports}
339
-
340
- input_state = self.project_edge(
341
- ports,
342
- edge,
343
- path[:-1],
344
- initial_state,
345
- ports_key='inputs')
346
-
347
- output_state = self.project_edge(
348
- ports,
349
- edge,
350
- path[:-1],
351
- initial_state,
352
- ports_key='outputs')
373
+ ports = {
374
+ '_inputs': input_ports,
375
+ '_outputs': output_ports}
376
+
377
+ input_state = {}
378
+ if input_ports:
379
+ input_state = self.project_edge(
380
+ ports,
381
+ edge,
382
+ path[:-1],
383
+ initial_state,
384
+ ports_key='inputs')
385
+
386
+ output_state = {}
387
+ if output_ports:
388
+ output_state = self.project_edge(
389
+ ports,
390
+ edge,
391
+ path[:-1],
392
+ initial_state,
393
+ ports_key='outputs')
353
394
 
354
395
  state = deep_merge(input_state, output_state)
355
396
 
@@ -362,6 +403,7 @@ class ProcessTypes(TypeSystem):
362
403
  if protocol == 'local':
363
404
  self.lookup_local(config)
364
405
 
406
+
365
407
  def hierarchy_depth(hierarchy, path=()):
366
408
  """
367
409
  Create a mapping of every path in the hierarchy to the node living at
@@ -372,7 +414,9 @@ def hierarchy_depth(hierarchy, path=()):
372
414
 
373
415
  for key, inner in hierarchy.items():
374
416
  down = tuple(path + (key,))
375
- if isinstance(inner, dict) and 'instance' not in inner:
417
+ if key.startswith('_'):
418
+ base[path] = inner
419
+ elif isinstance(inner, dict) and 'instance' not in inner:
376
420
  base.update(hierarchy_depth(inner, down))
377
421
  else:
378
422
  base[down] = inner
@@ -524,19 +568,19 @@ def find_instances(state, instance_type='process_bigraph.composite.Process'):
524
568
  found = {}
525
569
 
526
570
  for key, inner in state.items():
527
- if isinstance(inner, dict) and isinstance(inner.get('instance'), process_class):
528
- found[key] = inner
571
+ if isinstance(inner, dict):
572
+ if isinstance(inner.get('instance'), process_class):
573
+ found[key] = inner
574
+ elif not key.startswith('_'):
575
+ inner_instances = find_instances(
576
+ inner,
577
+ instance_type=instance_type)
578
+
579
+ if inner_instances:
580
+ found[key] = inner_instances
529
581
  return found
530
582
 
531
583
 
532
- def find_processes(state):
533
- return find_instances(state, 'process_bigraph.composite.Process')
534
-
535
-
536
- def find_steps(state):
537
- return find_instances(state, 'process_bigraph.composite.Step')
538
-
539
-
540
584
  def find_instance_paths(state, instance_type='process_bigraph.composite.Process'):
541
585
  instances = find_instances(state, instance_type)
542
586
  return hierarchy_depth(instances)
@@ -745,7 +789,7 @@ class Composite(Process):
745
789
  config_schema = {
746
790
  'composition': 'schema',
747
791
  'state': 'tree[any]',
748
- 'schema': {
792
+ 'interface': {
749
793
  'inputs': 'schema',
750
794
  'outputs': 'schema'},
751
795
  'bridge': {
@@ -775,22 +819,10 @@ class Composite(Process):
775
819
  self.core.access(composition))
776
820
 
777
821
  # TODO: add flag to self.core.access(copy=True)
778
- initial_schema = self.core.access(
779
- self.config.get('schema', {})) or {}
780
822
  self.bridge = self.config.get('bridge', {})
781
823
 
782
- # find all processes, steps, and emitter in the state
783
- self.process_paths = find_instance_paths(
784
- state,
785
- 'process_bigraph.composite.Process')
786
-
787
- self.step_paths = find_instance_paths(
788
- state,
789
- 'process_bigraph.composite.Step')
790
-
791
- self.emitter_paths = find_instance_paths(
792
- state,
793
- 'process_bigraph.composite.Emitter')
824
+ self.find_instance_paths(
825
+ state)
794
826
 
795
827
  # merge the processes and steps into a single "edges" dict
796
828
  self.edge_paths = self.process_paths.copy()
@@ -808,7 +840,7 @@ class Composite(Process):
808
840
  edge)
809
841
 
810
842
  try:
811
- edge_state = validate_merge(state, edge_state, initial)
843
+ edge_state = deep_merge(edge_state, initial)
812
844
  except:
813
845
  raise Exception(
814
846
  f'initial state from edge does not match initial state from other edges:\n{path}\n{edge}\n{edge_state}')
@@ -875,8 +907,27 @@ class Composite(Process):
875
907
  return to_run
876
908
 
877
909
 
878
- def interface(self):
879
- return self.process_schema
910
+ def find_instance_paths(self, state):
911
+ # find all processes, steps, and emitter in the state
912
+ self.process_paths = find_instance_paths(
913
+ state,
914
+ 'process_bigraph.composite.Process')
915
+
916
+ self.step_paths = find_instance_paths(
917
+ state,
918
+ 'process_bigraph.composite.Step')
919
+
920
+ self.emitter_paths = find_instance_paths(
921
+ state,
922
+ 'process_bigraph.composite.Emitter')
923
+
924
+
925
+ def inputs(self):
926
+ return self.process_schema.get('inputs', {})
927
+
928
+
929
+ def outputs(self):
930
+ return self.process_schema.get('outputs', {})
880
931
 
881
932
 
882
933
  def merge(self, initial_state):
@@ -1030,6 +1081,34 @@ class Composite(Process):
1030
1081
  # self.state.build_topology_views()
1031
1082
 
1032
1083
 
1084
+ def expire_process_paths(self, update_paths):
1085
+ for update_path in update_paths:
1086
+ for process_path in self.process_paths.copy():
1087
+ updated = all([
1088
+ update == process
1089
+ for update, process in zip(update_path, process_path)])
1090
+
1091
+ if updated:
1092
+ self.find_instance_paths(
1093
+ self.state)
1094
+ return
1095
+
1096
+ # del self.process_paths[process_path]
1097
+
1098
+ # target_schema, target_state = self.core.slice(
1099
+ # self.composition,
1100
+ # self.state,
1101
+ # update_path)
1102
+
1103
+ # process_subpaths = find_instance_paths(
1104
+ # target_state,
1105
+ # 'process_bigraph.composite.Process')
1106
+
1107
+ # for subpath, process in process_subpaths.items():
1108
+ # process_path = update_path + subpath
1109
+ # self.process_paths[process_path] = process
1110
+
1111
+
1033
1112
  def run(self, interval, force_complete=False):
1034
1113
  if self.to_run:
1035
1114
  self.run_steps(self.to_run)
@@ -1076,6 +1155,7 @@ class Composite(Process):
1076
1155
  # get all update paths, then trigger steps that
1077
1156
  # depend on those paths
1078
1157
  update_paths = self.apply_updates(updates)
1158
+ self.expire_process_paths(update_paths)
1079
1159
  self.trigger_steps(update_paths)
1080
1160
 
1081
1161
  # # display and emit
@@ -1204,11 +1284,6 @@ class Composite(Process):
1204
1284
  self.merge(
1205
1285
  projection)
1206
1286
 
1207
- # self.state = self.core.set(
1208
- # self.composition,
1209
- # self.state,
1210
- # projection)
1211
-
1212
1287
  self.run(interval)
1213
1288
 
1214
1289
  updates = self.bridge_updates
@@ -0,0 +1,207 @@
1
+ import pytest
2
+ from process_bigraph import Step, Process, Composite, ProcessTypes, interval_time_precision, deep_merge
3
+
4
+
5
+ class Grow(Process):
6
+ config_schema = {
7
+ 'rate': 'float'}
8
+
9
+
10
+ def __init__(self, config, core=None):
11
+ super().__init__(config, core)
12
+
13
+
14
+ def inputs(self):
15
+ return {
16
+ 'mass': 'float'}
17
+
18
+
19
+ def outputs(self):
20
+ return {
21
+ 'mass': 'float'}
22
+
23
+
24
+ def update(self, state, interval):
25
+ # this calculates a delta
26
+
27
+ return {
28
+ 'mass': state['mass'] * self.config['rate'] * interval}
29
+
30
+
31
+ # TODO: build composite and divide within it
32
+
33
+ class Divide(Step):
34
+ # assume the agent_schema has the right divide methods present
35
+ config_schema = {
36
+ 'agent_id': 'string',
37
+ 'agent_schema': 'schema',
38
+ 'threshold': 'float',
39
+ 'divisions': {
40
+ '_type': 'integer',
41
+ '_default': 2}}
42
+
43
+
44
+ def __init__(self, config, core=None):
45
+ super().__init__(config, core)
46
+
47
+
48
+ def inputs(self):
49
+ return {
50
+ 'trigger': 'float'}
51
+
52
+
53
+ def outputs(self):
54
+ return {
55
+ 'environment': {
56
+ '_type': 'map',
57
+ '_value': self.config['agent_schema']}}
58
+
59
+
60
+ # this should be generalized to some function that depends on
61
+ # state from the self.config['agent_schema'] (instead of trigger > threshold)
62
+ def update(self, state):
63
+ if state['trigger'] > self.config['threshold']:
64
+ mother = self.config['agent_id']
65
+ daughters = [(
66
+ f'{mother}_{i}', {
67
+ 'state': {
68
+ 'divide': {
69
+ 'config': {
70
+ 'agent_id': f'{mother}_{i}'}}}})
71
+ for i in range(self.config['divisions'])]
72
+
73
+ # return divide reaction
74
+ return {
75
+ 'environment': {
76
+ '_react': {
77
+ 'divide': {
78
+ 'mother': mother,
79
+ 'daughters': daughters}}}}
80
+
81
+
82
+ def generate_bridge_wires(schema):
83
+ return {
84
+ key: [key]
85
+ for key in schema
86
+ if not key.startswith('_')}
87
+
88
+
89
+ def generate_bridge(schema, state, interval=1.0):
90
+ bridge = {
91
+ port: generate_bridge_wires(schema[port])
92
+ for port in ['inputs', 'outputs']}
93
+
94
+ config = {
95
+ 'state': state,
96
+ 'bridge': bridge}
97
+
98
+ composite = {
99
+ '_type': 'process',
100
+ 'address': 'local:composite',
101
+ 'interval': interval,
102
+ 'config': config,
103
+ 'inputs': generate_bridge_wires(schema['inputs']),
104
+ 'outputs': generate_bridge_wires(schema['outputs'])}
105
+
106
+ return composite
107
+
108
+
109
+ def grow_divide_agent(config=None, state=None, path=None):
110
+ agent_id = path[-1]
111
+
112
+ config = config or {}
113
+ state = state or {}
114
+ path = path or []
115
+
116
+ agent_schema = config.get(
117
+ 'agent_schema',
118
+ {'mass': 'float'})
119
+
120
+ grow_config = {
121
+ 'rate': 0.1}
122
+
123
+ grow_config = deep_merge(
124
+ grow_config,
125
+ config.get(
126
+ 'grow'))
127
+
128
+ divide_config = {
129
+ 'agent_id': agent_id,
130
+ 'agent_schema': agent_schema,
131
+ 'threshold': 2.0,
132
+ 'divisions': 2}
133
+
134
+ divide_config = deep_merge(
135
+ divide_config,
136
+ config.get(
137
+ 'divide'))
138
+
139
+ grow_divide_state = {
140
+ 'grow': {
141
+ '_type': 'process',
142
+ 'address': 'local:grow',
143
+ 'config': grow_config,
144
+ 'inputs': {
145
+ 'mass': ['mass']},
146
+ 'outputs': {
147
+ 'mass': ['mass']}},
148
+
149
+ 'divide': {
150
+ '_type': 'process',
151
+ 'address': 'local:divide',
152
+ 'config': divide_config,
153
+ 'inputs': {
154
+ 'trigger': ['mass']},
155
+ 'outputs': {
156
+ 'environment': ['environment']}}}
157
+
158
+ grow_divide_state = deep_merge(
159
+ grow_divide_state,
160
+ state)
161
+
162
+ composite = generate_bridge({
163
+ 'inputs': {},
164
+ 'outputs': agent_schema},
165
+ grow_divide_state)
166
+
167
+ composite['config']['bridge']['outputs']['environment'] = ['environment']
168
+ composite['outputs']['environment'] = ['..']
169
+
170
+ return composite
171
+
172
+
173
+ def test_grow_divide(core):
174
+ initial_mass = 1.0
175
+
176
+ grow_divide = grow_divide_agent(
177
+ {'grow': {'rate': 0.03}},
178
+ {'mass': initial_mass},
179
+ ['environment', '0'])
180
+
181
+ environment = {
182
+ 'environment': {
183
+ '0': {
184
+ 'mass': initial_mass,
185
+ 'grow_divide': grow_divide}}}
186
+
187
+ composite = Composite({
188
+ 'state': environment},
189
+ core=core)
190
+
191
+ updates = composite.update({}, 100.0)
192
+
193
+
194
+ @pytest.fixture
195
+ def core():
196
+ core = ProcessTypes()
197
+ core.register_process('grow', Grow)
198
+ core.register_process('divide', Divide)
199
+ return core
200
+
201
+
202
+ if __name__ == '__main__':
203
+ core = ProcessTypes()
204
+ core.register_process('grow', Grow)
205
+ core.register_process('divide', Divide)
206
+
207
+ test_grow_divide(core)
@@ -88,7 +88,7 @@ def test_composite(core):
88
88
  'composition': {
89
89
  'increase': 'process[level:float,level:float]',
90
90
  'value': 'float'},
91
- 'schema': {
91
+ 'interface': {
92
92
  'inputs': {
93
93
  'exchange': 'float'},
94
94
  'outputs': {
@@ -1,9 +1,12 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: process-bigraph
3
- Version: 0.0.17
3
+ Version: 0.0.18
4
+ Summary: UNKNOWN
4
5
  Home-page: https://github.com/vivarium-collective/process-bigraph
5
6
  Author: Ryan Spangler, Eran Agmon
6
7
  Author-email: ryan.spangler@gmail.com, agmon.eran@gmail.com
8
+ License: UNKNOWN
9
+ Platform: UNKNOWN
7
10
  Classifier: Development Status :: 3 - Alpha
8
11
  Classifier: Intended Audience :: Developers
9
12
  Classifier: License :: OSI Approved :: MIT License
@@ -70,3 +73,5 @@ diagraph of a whole-cell E. coli model.
70
73
  ## License
71
74
 
72
75
  Bigraph-schema is open-source software released under the [Apache 2 License](https://github.com/vivarium-collective/process-bigraph/blob/main/LICENSE).
76
+
77
+
@@ -2,7 +2,7 @@ import re
2
2
  from setuptools import setup, find_packages
3
3
 
4
4
 
5
- VERSION = '0.0.17'
5
+ VERSION = '0.0.18'
6
6
 
7
7
 
8
8
  with open("README.md", "r") as readme:
@@ -1,66 +0,0 @@
1
- from process_bigraph import Step, Process, Composite, ProcessTypes, interval_time_precision, deep_merge
2
-
3
-
4
- def Growth(Process):
5
- config_schema = {
6
- 'rate': 'float'}
7
-
8
-
9
- def __init__(self, config, core=None):
10
- super().__init__(config, core)
11
-
12
-
13
- def inputs(self):
14
- return {
15
- 'mass': 'float'}
16
-
17
-
18
- def outputs(self):
19
- return {
20
- 'mass': 'float'}
21
-
22
-
23
- def update(self, state, interval):
24
- # this calculates a delta
25
-
26
- return {
27
- 'mass': state['mass'] * self.config['rate'] * interval}
28
-
29
-
30
- example_agent_schema = {
31
- 'id': 'string',
32
-
33
- }
34
-
35
-
36
- # TODO: build composite and divide within it
37
-
38
- def Divide(Step):
39
- # assume the agent_schema has the right divide methods present
40
- config_schema = {
41
- 'agent_schema': 'schema',
42
- 'threshold': 'float'}
43
-
44
-
45
- def __init__(self, config, core=None):
46
- super().__init__(config, core)
47
-
48
-
49
- def inputs(self):
50
- return {
51
- 'trigger': 'float'}
52
-
53
-
54
- def outputs(self):
55
- return {
56
- 'self': self.config['agent_schema']}
57
-
58
-
59
- def update(self, state):
60
- if state['trigger'] > self.config['threshold']:
61
- # return divide reaction
62
- return {
63
- 'self': {
64
- '_fold': {
65
- 'method': 'divide',
66
- 'divisions': 2}}}