process-bigraph 0.0.39__tar.gz → 0.0.41__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.
- {process-bigraph-0.0.39/process_bigraph.egg-info → process-bigraph-0.0.41}/PKG-INFO +1 -1
- {process-bigraph-0.0.39 → process-bigraph-0.0.41}/process_bigraph/__init__.py +6 -4
- {process-bigraph-0.0.39 → process-bigraph-0.0.41}/process_bigraph/composite.py +368 -1
- {process-bigraph-0.0.39 → process-bigraph-0.0.41}/process_bigraph/process_types.py +26 -0
- {process-bigraph-0.0.39 → process-bigraph-0.0.41}/process_bigraph/processes/__init__.py +5 -0
- {process-bigraph-0.0.39 → process-bigraph-0.0.41}/process_bigraph/tests.py +51 -4
- {process-bigraph-0.0.39 → process-bigraph-0.0.41/process_bigraph.egg-info}/PKG-INFO +1 -1
- {process-bigraph-0.0.39 → process-bigraph-0.0.41}/pyproject.toml +1 -1
- {process-bigraph-0.0.39 → process-bigraph-0.0.41}/setup.py +1 -1
- {process-bigraph-0.0.39 → process-bigraph-0.0.41}/.github/workflows/notebook_to_html.yml +0 -0
- {process-bigraph-0.0.39 → process-bigraph-0.0.41}/.github/workflows/pytest.yml +0 -0
- {process-bigraph-0.0.39 → process-bigraph-0.0.41}/.gitignore +0 -0
- {process-bigraph-0.0.39 → process-bigraph-0.0.41}/AUTHORS.md +0 -0
- {process-bigraph-0.0.39 → process-bigraph-0.0.41}/CLA.md +0 -0
- {process-bigraph-0.0.39 → process-bigraph-0.0.41}/CODE_OF_CONDUCT.md +0 -0
- {process-bigraph-0.0.39 → process-bigraph-0.0.41}/CONTRIBUTING.md +0 -0
- {process-bigraph-0.0.39 → process-bigraph-0.0.41}/LICENSE +0 -0
- {process-bigraph-0.0.39 → process-bigraph-0.0.41}/README.md +0 -0
- {process-bigraph-0.0.39 → process-bigraph-0.0.41}/doc/_static/process-bigraph.png +0 -0
- {process-bigraph-0.0.39 → process-bigraph-0.0.41}/notebooks/process-bigraphs.ipynb +0 -0
- {process-bigraph-0.0.39 → process-bigraph-0.0.41}/notebooks/visualize_processes.ipynb +0 -0
- {process-bigraph-0.0.39 → process-bigraph-0.0.41}/process_bigraph/emitter.py +0 -0
- {process-bigraph-0.0.39 → process-bigraph-0.0.41}/process_bigraph/experiments/__init__.py +0 -0
- {process-bigraph-0.0.39 → process-bigraph-0.0.41}/process_bigraph/experiments/minimal_gillespie.py +0 -0
- {process-bigraph-0.0.39 → process-bigraph-0.0.41}/process_bigraph/processes/growth_division.py +0 -0
- {process-bigraph-0.0.39 → process-bigraph-0.0.41}/process_bigraph/processes/parameter_scan.py +0 -0
- {process-bigraph-0.0.39 → process-bigraph-0.0.41}/process_bigraph/protocols.py +0 -0
- {process-bigraph-0.0.39 → process-bigraph-0.0.41}/process_bigraph.egg-info/SOURCES.txt +0 -0
- {process-bigraph-0.0.39 → process-bigraph-0.0.41}/process_bigraph.egg-info/dependency_links.txt +0 -0
- {process-bigraph-0.0.39 → process-bigraph-0.0.41}/process_bigraph.egg-info/requires.txt +0 -0
- {process-bigraph-0.0.39 → process-bigraph-0.0.41}/process_bigraph.egg-info/top_level.txt +0 -0
- {process-bigraph-0.0.39 → process-bigraph-0.0.41}/pytest.ini +0 -0
- {process-bigraph-0.0.39 → process-bigraph-0.0.41}/release.sh +0 -0
- {process-bigraph-0.0.39 → process-bigraph-0.0.41}/setup.cfg +0 -0
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
import pprint
|
|
2
2
|
from bigraph_schema.registry import deep_merge, default
|
|
3
3
|
from process_bigraph.processes import register_processes
|
|
4
|
-
from process_bigraph.composite import Process, Step, Composite, interval_time_precision
|
|
5
|
-
from process_bigraph.
|
|
6
|
-
from process_bigraph.emitter import Emitter, gather_emitter_results, generate_emitter_state
|
|
4
|
+
from process_bigraph.composite import Process, Step, Composite, interval_time_precision, ProcessTypes
|
|
5
|
+
from process_bigraph.emitter import Emitter, gather_emitter_results, generate_emitter_state, BASE_EMITTERS
|
|
7
6
|
|
|
8
7
|
|
|
9
8
|
pretty = pprint.PrettyPrinter(indent=2)
|
|
@@ -42,9 +41,12 @@ def register_types(core):
|
|
|
42
41
|
'rates': 'map[float]',
|
|
43
42
|
'species': 'map[float]'})
|
|
44
43
|
|
|
45
|
-
|
|
44
|
+
register_processes(
|
|
46
45
|
core)
|
|
47
46
|
|
|
48
47
|
return core
|
|
49
48
|
|
|
50
49
|
|
|
50
|
+
def allocate_core():
|
|
51
|
+
core = ProcessTypes()
|
|
52
|
+
return register_types(core)
|
|
@@ -11,7 +11,7 @@ import collections
|
|
|
11
11
|
from typing import Dict
|
|
12
12
|
|
|
13
13
|
from bigraph_schema import (
|
|
14
|
-
Edge, Registry,
|
|
14
|
+
Edge, Registry, TypeSystem, visit_method,
|
|
15
15
|
get_path, set_path, resolve_path, hierarchy_depth, deep_merge,
|
|
16
16
|
is_schema_key, strip_schema_keys)
|
|
17
17
|
|
|
@@ -22,6 +22,7 @@ from process_bigraph.protocols import local_lookup, local_lookup_module
|
|
|
22
22
|
# Process Utility Functions
|
|
23
23
|
# =========================
|
|
24
24
|
|
|
25
|
+
|
|
25
26
|
def assert_interface(interface: Dict):
|
|
26
27
|
"""Ensure that an interface dict has the required keys"""
|
|
27
28
|
required_keys = ['inputs', 'outputs']
|
|
@@ -951,3 +952,369 @@ class Composite(Process):
|
|
|
951
952
|
self.bridge_updates = []
|
|
952
953
|
|
|
953
954
|
return updates
|
|
955
|
+
|
|
956
|
+
|
|
957
|
+
# ======================
|
|
958
|
+
# Process Type Functions
|
|
959
|
+
# ======================
|
|
960
|
+
|
|
961
|
+
|
|
962
|
+
def apply_process(schema, current, update, top_schema, top_state, path, core):
|
|
963
|
+
"""Apply an update to a process."""
|
|
964
|
+
process_schema = schema.copy()
|
|
965
|
+
process_schema.pop('_apply')
|
|
966
|
+
return core.apply_update(
|
|
967
|
+
process_schema,
|
|
968
|
+
current,
|
|
969
|
+
update,
|
|
970
|
+
top_schema=top_schema,
|
|
971
|
+
top_state=top_state,
|
|
972
|
+
path=path)
|
|
973
|
+
|
|
974
|
+
|
|
975
|
+
def check_process(schema, state, core):
|
|
976
|
+
"""Check if this is a process."""
|
|
977
|
+
return 'instance' in state and isinstance(
|
|
978
|
+
state['instance'],
|
|
979
|
+
Edge)
|
|
980
|
+
|
|
981
|
+
|
|
982
|
+
def fold_visit(schema, state, method, values, core):
|
|
983
|
+
visit = visit_method(
|
|
984
|
+
schema,
|
|
985
|
+
state,
|
|
986
|
+
method,
|
|
987
|
+
values,
|
|
988
|
+
core)
|
|
989
|
+
|
|
990
|
+
return visit
|
|
991
|
+
|
|
992
|
+
|
|
993
|
+
def divide_process(schema, state, values, core):
|
|
994
|
+
# daughter_configs must have a config per daughter
|
|
995
|
+
|
|
996
|
+
daughter_configs = values.get(
|
|
997
|
+
'daughter_configs',
|
|
998
|
+
[{} for index in range(values['divisions'])])
|
|
999
|
+
|
|
1000
|
+
if 'config' not in state:
|
|
1001
|
+
return daughter_configs
|
|
1002
|
+
|
|
1003
|
+
existing_config = state['config']
|
|
1004
|
+
|
|
1005
|
+
divisions = []
|
|
1006
|
+
for index in range(values['divisions']):
|
|
1007
|
+
daughter_config = copy.deepcopy(
|
|
1008
|
+
existing_config)
|
|
1009
|
+
daughter_config = deep_merge(
|
|
1010
|
+
daughter_config,
|
|
1011
|
+
daughter_configs[index])
|
|
1012
|
+
|
|
1013
|
+
# TODO: provide a way to override inputs and outputs
|
|
1014
|
+
daughter_state = {
|
|
1015
|
+
'address': state['address'],
|
|
1016
|
+
'config': daughter_config,
|
|
1017
|
+
'inputs': copy.deepcopy(state['inputs']),
|
|
1018
|
+
'outputs': copy.deepcopy(state['outputs'])}
|
|
1019
|
+
|
|
1020
|
+
if 'interval' in state:
|
|
1021
|
+
daughter_state['interval'] = state['interval']
|
|
1022
|
+
|
|
1023
|
+
divisions.append(daughter_state)
|
|
1024
|
+
|
|
1025
|
+
return divisions
|
|
1026
|
+
|
|
1027
|
+
|
|
1028
|
+
def serialize_process(schema, value, core):
|
|
1029
|
+
"""Serialize a process to a JSON-safe representation."""
|
|
1030
|
+
# TODO -- need to get back the protocol: address and the config
|
|
1031
|
+
process = value.copy()
|
|
1032
|
+
process['config'] = core.serialize(
|
|
1033
|
+
process['instance'].config_schema,
|
|
1034
|
+
process['config'])
|
|
1035
|
+
del process['instance']
|
|
1036
|
+
return process
|
|
1037
|
+
|
|
1038
|
+
|
|
1039
|
+
def deserialize_process(schema, encoded, core):
|
|
1040
|
+
"""Deserialize a process from a serialized state.
|
|
1041
|
+
|
|
1042
|
+
This function is used by the type system to deserialize a process.
|
|
1043
|
+
|
|
1044
|
+
:param encoded: A JSON-safe representation of the process.
|
|
1045
|
+
:param bindings: The bindings to use for deserialization.
|
|
1046
|
+
:param core: The type system to use for deserialization.
|
|
1047
|
+
|
|
1048
|
+
:returns: The deserialized state with an instantiated process.
|
|
1049
|
+
"""
|
|
1050
|
+
encoded = encoded or {}
|
|
1051
|
+
schema = schema or {}
|
|
1052
|
+
|
|
1053
|
+
default = core.default(schema)
|
|
1054
|
+
deserialized = deep_merge(default, encoded)
|
|
1055
|
+
|
|
1056
|
+
if not deserialized.get('address'):
|
|
1057
|
+
return deserialized
|
|
1058
|
+
|
|
1059
|
+
protocol, address = deserialized['address'].split(':', 1)
|
|
1060
|
+
|
|
1061
|
+
existing_instance = 'instance' in deserialized and deserialized['instance']
|
|
1062
|
+
if existing_instance:
|
|
1063
|
+
instantiate = type(deserialized['instance'])
|
|
1064
|
+
else:
|
|
1065
|
+
process_lookup = core.protocol_registry.access(protocol)
|
|
1066
|
+
if not process_lookup:
|
|
1067
|
+
raise Exception(f'protocol "{protocol}" not implemented')
|
|
1068
|
+
|
|
1069
|
+
instantiate = process_lookup(core, address)
|
|
1070
|
+
if not instantiate:
|
|
1071
|
+
raise Exception(f'process "{address}" not found')
|
|
1072
|
+
|
|
1073
|
+
config = core.deserialize(
|
|
1074
|
+
instantiate.config_schema,
|
|
1075
|
+
deserialized.get('config', {}))
|
|
1076
|
+
|
|
1077
|
+
interval = core.deserialize(
|
|
1078
|
+
'interval',
|
|
1079
|
+
deserialized.get('interval'))
|
|
1080
|
+
|
|
1081
|
+
if interval is None:
|
|
1082
|
+
interval = core.default(
|
|
1083
|
+
schema.get(
|
|
1084
|
+
'interval',
|
|
1085
|
+
'interval'))
|
|
1086
|
+
|
|
1087
|
+
if existing_instance:
|
|
1088
|
+
process = deserialized['instance']
|
|
1089
|
+
else:
|
|
1090
|
+
process = instantiate(
|
|
1091
|
+
config,
|
|
1092
|
+
core=core)
|
|
1093
|
+
|
|
1094
|
+
deserialized['instance'] = process
|
|
1095
|
+
|
|
1096
|
+
# TODO: this mutating the original value directly into
|
|
1097
|
+
# the return value is weird (?)
|
|
1098
|
+
shared = deserialized.get('shared', {})
|
|
1099
|
+
deserialized['shared'] = {}
|
|
1100
|
+
if shared:
|
|
1101
|
+
for step_id, step_config in shared.items():
|
|
1102
|
+
step = deserialize_step(
|
|
1103
|
+
'step',
|
|
1104
|
+
step_config,
|
|
1105
|
+
core)
|
|
1106
|
+
|
|
1107
|
+
step['instance'].register_shared(
|
|
1108
|
+
process)
|
|
1109
|
+
|
|
1110
|
+
deserialized['shared'][step_id] = step
|
|
1111
|
+
|
|
1112
|
+
deserialized['config'] = config
|
|
1113
|
+
deserialized['interval'] = interval
|
|
1114
|
+
deserialized['_inputs'] = copy.deepcopy(
|
|
1115
|
+
deserialized['instance'].inputs())
|
|
1116
|
+
deserialized['_outputs'] = copy.deepcopy(
|
|
1117
|
+
deserialized['instance'].outputs())
|
|
1118
|
+
|
|
1119
|
+
return deserialized
|
|
1120
|
+
|
|
1121
|
+
|
|
1122
|
+
def deserialize_step(schema, encoded, core):
|
|
1123
|
+
default = core.default(schema)
|
|
1124
|
+
deserialized = deep_merge(default, encoded)
|
|
1125
|
+
|
|
1126
|
+
if not deserialized['address']:
|
|
1127
|
+
return deserialized
|
|
1128
|
+
|
|
1129
|
+
protocol, address = deserialized['address'].split(':', 1)
|
|
1130
|
+
|
|
1131
|
+
existing_instance = 'instance' in deserialized and deserialized['instance']
|
|
1132
|
+
if existing_instance:
|
|
1133
|
+
instantiate = type(deserialized['instance'])
|
|
1134
|
+
else:
|
|
1135
|
+
process_lookup = core.protocol_registry.access(protocol)
|
|
1136
|
+
if not process_lookup:
|
|
1137
|
+
raise Exception(f'protocol "{protocol}" not implemented')
|
|
1138
|
+
|
|
1139
|
+
instantiate = process_lookup(core, address)
|
|
1140
|
+
if not instantiate:
|
|
1141
|
+
raise Exception(f'process "{address}" not found')
|
|
1142
|
+
|
|
1143
|
+
config = core.deserialize(
|
|
1144
|
+
instantiate.config_schema,
|
|
1145
|
+
deserialized.get('config', {}))
|
|
1146
|
+
|
|
1147
|
+
if not existing_instance:
|
|
1148
|
+
process = instantiate(config, core=core)
|
|
1149
|
+
deserialized['instance'] = process
|
|
1150
|
+
|
|
1151
|
+
deserialized['config'] = config
|
|
1152
|
+
deserialized['_inputs'] = copy.deepcopy(
|
|
1153
|
+
deserialized['instance'].inputs())
|
|
1154
|
+
deserialized['_outputs'] = copy.deepcopy(
|
|
1155
|
+
deserialized['instance'].outputs())
|
|
1156
|
+
|
|
1157
|
+
return deserialized
|
|
1158
|
+
|
|
1159
|
+
|
|
1160
|
+
# ===================
|
|
1161
|
+
# Process Type System
|
|
1162
|
+
# ===================
|
|
1163
|
+
|
|
1164
|
+
class ProcessTypes(TypeSystem):
|
|
1165
|
+
"""
|
|
1166
|
+
ProcessTypes class extends the TypeSystem class to include process types.
|
|
1167
|
+
It maintains a registry of process types and provides methods to register
|
|
1168
|
+
new process types, protocols, and emitters.
|
|
1169
|
+
"""
|
|
1170
|
+
|
|
1171
|
+
def __init__(self):
|
|
1172
|
+
super().__init__()
|
|
1173
|
+
self.process_registry = Registry()
|
|
1174
|
+
self.protocol_registry = Registry()
|
|
1175
|
+
|
|
1176
|
+
self.update_types(PROCESS_TYPES)
|
|
1177
|
+
self.register_protocols(BASE_PROTOCOLS)
|
|
1178
|
+
|
|
1179
|
+
self.register_process('composite', Composite)
|
|
1180
|
+
|
|
1181
|
+
|
|
1182
|
+
def register_protocols(self, protocols):
|
|
1183
|
+
"""Register protocols with the core"""
|
|
1184
|
+
self.protocol_registry.register_multiple(protocols)
|
|
1185
|
+
|
|
1186
|
+
|
|
1187
|
+
def register_process(
|
|
1188
|
+
self,
|
|
1189
|
+
name,
|
|
1190
|
+
process_data
|
|
1191
|
+
):
|
|
1192
|
+
"""
|
|
1193
|
+
Registers a new process type in the process registry.
|
|
1194
|
+
|
|
1195
|
+
Args:
|
|
1196
|
+
name (str): The name of the process type.
|
|
1197
|
+
process_data: The data associated with the process type.
|
|
1198
|
+
"""
|
|
1199
|
+
self.process_registry.register(name, process_data)
|
|
1200
|
+
|
|
1201
|
+
|
|
1202
|
+
def register_processes(self, processes):
|
|
1203
|
+
for process_key, process_data in processes.items():
|
|
1204
|
+
self.register_process(
|
|
1205
|
+
process_key,
|
|
1206
|
+
process_data)
|
|
1207
|
+
|
|
1208
|
+
|
|
1209
|
+
def initialize_edge_state(self, schema, path, edge):
|
|
1210
|
+
"""
|
|
1211
|
+
Initialize the state for an edge based on the schema and the edge.
|
|
1212
|
+
"""
|
|
1213
|
+
initial_state = edge['instance'].initial_state()
|
|
1214
|
+
if not initial_state:
|
|
1215
|
+
return initial_state
|
|
1216
|
+
|
|
1217
|
+
input_ports = copy.deepcopy(get_path(schema, path + ('_inputs',)))
|
|
1218
|
+
output_ports = copy.deepcopy(get_path(schema, path + ('_outputs',)))
|
|
1219
|
+
ports = {
|
|
1220
|
+
'_inputs': input_ports,
|
|
1221
|
+
'_outputs': output_ports}
|
|
1222
|
+
|
|
1223
|
+
input_state = {}
|
|
1224
|
+
if input_ports:
|
|
1225
|
+
input_state = self.project_edge(
|
|
1226
|
+
ports,
|
|
1227
|
+
edge,
|
|
1228
|
+
path[:-1],
|
|
1229
|
+
initial_state,
|
|
1230
|
+
ports_key='inputs')
|
|
1231
|
+
|
|
1232
|
+
output_state = {}
|
|
1233
|
+
if output_ports:
|
|
1234
|
+
output_state = self.project_edge(
|
|
1235
|
+
ports,
|
|
1236
|
+
edge,
|
|
1237
|
+
path[:-1],
|
|
1238
|
+
initial_state,
|
|
1239
|
+
ports_key='outputs')
|
|
1240
|
+
|
|
1241
|
+
state = deep_merge(input_state, output_state)
|
|
1242
|
+
|
|
1243
|
+
return state
|
|
1244
|
+
|
|
1245
|
+
|
|
1246
|
+
def default_state(self, process_class, initial_state=None):
|
|
1247
|
+
default_config = self.default(
|
|
1248
|
+
process_class.config_schema)
|
|
1249
|
+
|
|
1250
|
+
instance = process_class(
|
|
1251
|
+
default_config,
|
|
1252
|
+
core=self)
|
|
1253
|
+
|
|
1254
|
+
state = {
|
|
1255
|
+
'_type': 'process',
|
|
1256
|
+
'address': f'local:!{process_class.__module__}.{process_class.__name__}',
|
|
1257
|
+
'config': default_config,
|
|
1258
|
+
'inputs': instance.default_inputs(),
|
|
1259
|
+
'outputs': instance.default_outputs()}
|
|
1260
|
+
|
|
1261
|
+
if issubclass(process_class, Process):
|
|
1262
|
+
state['interval'] = 1.0
|
|
1263
|
+
|
|
1264
|
+
if initial_state:
|
|
1265
|
+
state = deep_merge(
|
|
1266
|
+
state,
|
|
1267
|
+
initial_state)
|
|
1268
|
+
|
|
1269
|
+
return state
|
|
1270
|
+
|
|
1271
|
+
|
|
1272
|
+
PROCESS_TYPES = {
|
|
1273
|
+
'protocol': {
|
|
1274
|
+
'_type': 'protocol',
|
|
1275
|
+
'_inherit': 'string'},
|
|
1276
|
+
|
|
1277
|
+
'emitter_mode': 'enum[none,all,stores,bridge,paths,ports]',
|
|
1278
|
+
|
|
1279
|
+
'interval': {
|
|
1280
|
+
'_type': 'interval',
|
|
1281
|
+
'_inherit': 'float',
|
|
1282
|
+
'_apply': 'set',
|
|
1283
|
+
'_default': '1.0'},
|
|
1284
|
+
|
|
1285
|
+
'step': {
|
|
1286
|
+
'_type': 'step',
|
|
1287
|
+
'_inherit': 'edge',
|
|
1288
|
+
'_apply': apply_process,
|
|
1289
|
+
'_serialize': serialize_process,
|
|
1290
|
+
'_deserialize': deserialize_step,
|
|
1291
|
+
'_check': check_process,
|
|
1292
|
+
'_fold': fold_visit,
|
|
1293
|
+
'_divide': divide_process,
|
|
1294
|
+
'_description': '',
|
|
1295
|
+
# TODO: support reference to type parameters from other states
|
|
1296
|
+
'address': 'protocol',
|
|
1297
|
+
'config': 'quote'},
|
|
1298
|
+
|
|
1299
|
+
# TODO: slice process to allow for navigating through a port
|
|
1300
|
+
'process': {
|
|
1301
|
+
'_type': 'process',
|
|
1302
|
+
'_inherit': 'edge',
|
|
1303
|
+
'_apply': apply_process,
|
|
1304
|
+
'_serialize': serialize_process,
|
|
1305
|
+
'_deserialize': deserialize_process,
|
|
1306
|
+
'_check': check_process,
|
|
1307
|
+
'_fold': fold_visit,
|
|
1308
|
+
'_divide': divide_process,
|
|
1309
|
+
'_description': '',
|
|
1310
|
+
# TODO: support reference to type parameters from other states
|
|
1311
|
+
'interval': 'interval',
|
|
1312
|
+
'address': 'protocol',
|
|
1313
|
+
'config': 'quote',
|
|
1314
|
+
'shared': 'map[step]'},
|
|
1315
|
+
}
|
|
1316
|
+
|
|
1317
|
+
|
|
1318
|
+
BASE_PROTOCOLS = {
|
|
1319
|
+
'local': local_lookup}
|
|
1320
|
+
|
|
@@ -306,6 +306,32 @@ class ProcessTypes(TypeSystem):
|
|
|
306
306
|
return state
|
|
307
307
|
|
|
308
308
|
|
|
309
|
+
def default_state(self, process_class, initial_state=None):
|
|
310
|
+
default_config = self.default(
|
|
311
|
+
process_class.config_schema)
|
|
312
|
+
|
|
313
|
+
instance = process_class(
|
|
314
|
+
default_config,
|
|
315
|
+
core=self)
|
|
316
|
+
|
|
317
|
+
state = {
|
|
318
|
+
'_type': 'process',
|
|
319
|
+
'address': f'local:!{process_class.__module__}.{process_class.__name__}',
|
|
320
|
+
'config': default_config,
|
|
321
|
+
'inputs': instance.default_inputs(),
|
|
322
|
+
'outputs': instance.default_outputs()}
|
|
323
|
+
|
|
324
|
+
if issubclass(process_class, Process):
|
|
325
|
+
state['interval'] = 1.0
|
|
326
|
+
|
|
327
|
+
if initial_state:
|
|
328
|
+
state = deep_merge(
|
|
329
|
+
state,
|
|
330
|
+
initial_state)
|
|
331
|
+
|
|
332
|
+
return state
|
|
333
|
+
|
|
334
|
+
|
|
309
335
|
PROCESS_TYPES = {
|
|
310
336
|
'protocol': {
|
|
311
337
|
'_type': 'protocol',
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
from process_bigraph.processes.parameter_scan import ToySystem, ODE, RunProcess, ParameterScan
|
|
2
2
|
from process_bigraph.processes.growth_division import Grow, Divide
|
|
3
|
+
from process_bigraph.emitter import BASE_EMITTERS
|
|
3
4
|
# from process_bigraph.experiments.minimal_gillespie import GillespieInterval, GillespieEvent
|
|
4
5
|
|
|
5
6
|
|
|
@@ -18,4 +19,8 @@ TOY_PROCESSES = {
|
|
|
18
19
|
def register_processes(core):
|
|
19
20
|
for name, process in TOY_PROCESSES.items():
|
|
20
21
|
core.register_process(name, process)
|
|
22
|
+
|
|
23
|
+
core = core.register_processes(
|
|
24
|
+
BASE_EMITTERS)
|
|
25
|
+
|
|
21
26
|
return core
|
|
@@ -7,10 +7,9 @@ import random
|
|
|
7
7
|
from bigraph_schema import default
|
|
8
8
|
from process_bigraph import register_types
|
|
9
9
|
|
|
10
|
-
from process_bigraph.composite import Process, Step, Composite, merge_collections, match_star_path
|
|
10
|
+
from process_bigraph.composite import Process, Step, Composite, merge_collections, match_star_path, ProcessTypes
|
|
11
11
|
|
|
12
|
-
from process_bigraph.processes.growth_division import grow_divide_agent
|
|
13
|
-
from process_bigraph.process_types import ProcessTypes
|
|
12
|
+
from process_bigraph.processes.growth_division import grow_divide_agent, Grow, Divide
|
|
14
13
|
from process_bigraph.emitter import emitter_from_wires, gather_emitter_results
|
|
15
14
|
|
|
16
15
|
|
|
@@ -871,20 +870,68 @@ def test_star_update(core):
|
|
|
871
870
|
assert star.state['Compartments']['2']['Shared Environment']['counts']['biomass'] == 2899
|
|
872
871
|
|
|
873
872
|
|
|
873
|
+
class GlobalProcess(Process):
|
|
874
|
+
config_schema = {}
|
|
875
|
+
|
|
876
|
+
|
|
877
|
+
def initialize(self, config):
|
|
878
|
+
pass
|
|
879
|
+
|
|
880
|
+
|
|
881
|
+
|
|
882
|
+
|
|
883
|
+
|
|
884
|
+
def test_default_process_state(core):
|
|
885
|
+
# provide some initial values
|
|
886
|
+
default_rate = {
|
|
887
|
+
'config': {
|
|
888
|
+
'rate': 0.001}}
|
|
889
|
+
|
|
890
|
+
# generate a default state for the Grow process
|
|
891
|
+
default_grow = core.default_state(
|
|
892
|
+
Grow,
|
|
893
|
+
default_rate)
|
|
894
|
+
|
|
895
|
+
# create a composite from the default process state
|
|
896
|
+
composite = Composite({
|
|
897
|
+
'state': {
|
|
898
|
+
'grow': default_grow,
|
|
899
|
+
'mass': 1.0}},
|
|
900
|
+
core=core)
|
|
901
|
+
|
|
902
|
+
# run the composite
|
|
903
|
+
composite.run(10.0)
|
|
904
|
+
|
|
905
|
+
# assert the process ran and the mass increased
|
|
906
|
+
assert composite.state['mass'] > 1.0
|
|
907
|
+
|
|
908
|
+
default_divide = core.default_state(
|
|
909
|
+
Divide)
|
|
910
|
+
|
|
911
|
+
assert 'interval' not in default_divide
|
|
912
|
+
|
|
913
|
+
|
|
914
|
+
def test_update_removal(core):
|
|
915
|
+
return {}
|
|
916
|
+
|
|
917
|
+
|
|
874
918
|
def test_stochastic_deterministic_composite(core):
|
|
875
919
|
# TODO make the demo for a hybrid stochastic/deterministic simulator
|
|
876
920
|
pass
|
|
877
921
|
|
|
922
|
+
|
|
878
923
|
def test_match_star_path(core):
|
|
879
924
|
assert match_star_path(["first", "list", "test"], ["first", "*", "test"])
|
|
880
925
|
assert not match_star_path(["first", "list", "tent"], ["first", "*", "test"])
|
|
881
926
|
assert match_star_path(["first", "list", "test"], ["first", "list", "test"])
|
|
882
927
|
|
|
928
|
+
|
|
883
929
|
if __name__ == '__main__':
|
|
884
930
|
core = ProcessTypes()
|
|
885
931
|
core = register_types(core)
|
|
886
932
|
|
|
887
933
|
test_default_config(core)
|
|
934
|
+
test_default_process_state(core)
|
|
888
935
|
test_merge_collections(core)
|
|
889
936
|
test_process(core)
|
|
890
937
|
test_composite(core)
|
|
@@ -904,4 +951,4 @@ if __name__ == '__main__':
|
|
|
904
951
|
test_merge_schema(core)
|
|
905
952
|
test_grow_divide(core)
|
|
906
953
|
test_star_update(core)
|
|
907
|
-
test_match_star_path(core)
|
|
954
|
+
test_match_star_path(core)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{process-bigraph-0.0.39 → process-bigraph-0.0.41}/process_bigraph/experiments/minimal_gillespie.py
RENAMED
|
File without changes
|
{process-bigraph-0.0.39 → process-bigraph-0.0.41}/process_bigraph/processes/growth_division.py
RENAMED
|
File without changes
|
{process-bigraph-0.0.39 → process-bigraph-0.0.41}/process_bigraph/processes/parameter_scan.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{process-bigraph-0.0.39 → process-bigraph-0.0.41}/process_bigraph.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|