math-spec-mapping 0.3.6__py3-none-any.whl → 0.3.8__py3-none-any.whl
Sign up to get free protection for your applications and to get access to all the features.
- math_spec_mapping/Classes/MathSpec.py +123 -3
- math_spec_mapping/Convenience/starter.py +25 -11
- {math_spec_mapping-0.3.6.dist-info → math_spec_mapping-0.3.8.dist-info}/METADATA +4 -3
- {math_spec_mapping-0.3.6.dist-info → math_spec_mapping-0.3.8.dist-info}/RECORD +7 -7
- {math_spec_mapping-0.3.6.dist-info → math_spec_mapping-0.3.8.dist-info}/WHEEL +1 -1
- {math_spec_mapping-0.3.6.dist-info → math_spec_mapping-0.3.8.dist-info}/LICENSE +0 -0
- {math_spec_mapping-0.3.6.dist-info → math_spec_mapping-0.3.8.dist-info}/top_level.txt +0 -0
@@ -7,6 +7,7 @@ from .BoundaryAction import BoundaryAction
|
|
7
7
|
import os
|
8
8
|
from copy import deepcopy
|
9
9
|
import shutil
|
10
|
+
import pandas as pd
|
10
11
|
|
11
12
|
|
12
13
|
class MathSpec:
|
@@ -469,6 +470,83 @@ class MathSpec:
|
|
469
470
|
with open(path, "w") as f:
|
470
471
|
f.write(out)
|
471
472
|
|
473
|
+
def run_experiment(
|
474
|
+
self,
|
475
|
+
experiment,
|
476
|
+
params_base,
|
477
|
+
state_base,
|
478
|
+
post_processing_function,
|
479
|
+
state_preperation_functions=None,
|
480
|
+
parameter_preperation_functions=None,
|
481
|
+
metrics_functions=None,
|
482
|
+
):
|
483
|
+
if experiment["Param Modifications"]:
|
484
|
+
params_base = deepcopy(params_base)
|
485
|
+
for key in experiment["Param Modifications"]:
|
486
|
+
params_base[key] = experiment["Param Modifications"][key]
|
487
|
+
if experiment["State Modifications"]:
|
488
|
+
state_base = deepcopy(state_base)
|
489
|
+
for key in experiment["State Modifications"]:
|
490
|
+
state_base[key] = experiment["State Modifications"][key]
|
491
|
+
msi = self.build_implementation(params_base)
|
492
|
+
state, params = msi.prepare_state_and_params(
|
493
|
+
state_base,
|
494
|
+
params_base,
|
495
|
+
state_preperation_functions=state_preperation_functions,
|
496
|
+
parameter_preperation_functions=parameter_preperation_functions,
|
497
|
+
)
|
498
|
+
|
499
|
+
state = msi.execute_blocks(state, params, experiment["Blocks"])
|
500
|
+
df = post_processing_function(state, params)
|
501
|
+
|
502
|
+
if metrics_functions:
|
503
|
+
metrics = {}
|
504
|
+
for metrics_function in metrics_functions:
|
505
|
+
metrics_function(metrics, state, params, df)
|
506
|
+
metrics = pd.Series(metrics)
|
507
|
+
else:
|
508
|
+
metrics = None
|
509
|
+
|
510
|
+
return state, params, msi, df, metrics
|
511
|
+
|
512
|
+
def run_experiments(
|
513
|
+
self,
|
514
|
+
experiments,
|
515
|
+
params_base,
|
516
|
+
state_base,
|
517
|
+
post_processing_function,
|
518
|
+
state_preperation_functions=None,
|
519
|
+
parameter_preperation_functions=None,
|
520
|
+
metrics_functions=None,
|
521
|
+
):
|
522
|
+
state_l = []
|
523
|
+
params_l = []
|
524
|
+
df_l = []
|
525
|
+
metrics_l = []
|
526
|
+
for experiment in experiments:
|
527
|
+
for i in range(experiment["Monte Carlo Runs"]):
|
528
|
+
state, params, msi, df, metrics = self.run_experiment(
|
529
|
+
experiment,
|
530
|
+
params_base,
|
531
|
+
state_base,
|
532
|
+
post_processing_function,
|
533
|
+
state_preperation_functions=state_preperation_functions,
|
534
|
+
parameter_preperation_functions=parameter_preperation_functions,
|
535
|
+
metrics_functions=metrics_functions,
|
536
|
+
)
|
537
|
+
df["Monte Carlo Run"] = i + 1
|
538
|
+
df["Experiment"] = experiment["Name"]
|
539
|
+
metrics.loc["Monte Carlo Run"] = i + 1
|
540
|
+
metrics.loc["Experiment"] = experiment["Name"]
|
541
|
+
metrics.name = "{}-{}".format(experiment["Name"], i + 1)
|
542
|
+
state_l.append(state)
|
543
|
+
params_l.append(params)
|
544
|
+
df_l.append(df)
|
545
|
+
metrics_l.append(metrics)
|
546
|
+
df = pd.concat(df_l)
|
547
|
+
metrics = pd.concat(metrics_l, axis=1).T
|
548
|
+
return df, metrics, state_l, params_l
|
549
|
+
|
472
550
|
def metaprogramming_python_states(
|
473
551
|
self, model_directory, overwrite=False, default_values=None
|
474
552
|
):
|
@@ -698,6 +776,7 @@ class MathSpecImplementation:
|
|
698
776
|
self.mechanisms = self.load_mechanisms()
|
699
777
|
self.stateful_metrics = self.load_stateful_metrics()
|
700
778
|
self.load_wiring()
|
779
|
+
self.load_components()
|
701
780
|
|
702
781
|
def load_control_actions(self):
|
703
782
|
control_actions = {}
|
@@ -776,6 +855,9 @@ class MathSpecImplementation:
|
|
776
855
|
|
777
856
|
def load_single_wiring(self, wiring):
|
778
857
|
hold = wiring
|
858
|
+
domain_sizes = {}
|
859
|
+
for x in wiring.components:
|
860
|
+
domain_sizes[x.name] = len(x.domain)
|
779
861
|
components = [x.name for x in wiring.components]
|
780
862
|
if wiring.block_type == "Stack Block":
|
781
863
|
|
@@ -795,10 +877,17 @@ class MathSpecImplementation:
|
|
795
877
|
spaces_mapping[x].append(i)
|
796
878
|
|
797
879
|
def wiring(state, params, spaces):
|
880
|
+
spaces_mapping_temp = deepcopy(spaces_mapping)
|
798
881
|
codomain = []
|
799
882
|
for component in components:
|
800
|
-
if component in
|
801
|
-
spaces_i = [spaces[i] for i in
|
883
|
+
if component in spaces_mapping_temp:
|
884
|
+
spaces_i = [spaces[i] for i in spaces_mapping_temp[component]][
|
885
|
+
: domain_sizes[component]
|
886
|
+
]
|
887
|
+
# Fix for repeated block names
|
888
|
+
spaces_mapping_temp[component] = spaces_mapping_temp[component][
|
889
|
+
domain_sizes[component] :
|
890
|
+
]
|
802
891
|
else:
|
803
892
|
assert component in [
|
804
893
|
x.name for x in hold.domain_blocks_empty
|
@@ -926,9 +1015,40 @@ class MathSpecImplementation:
|
|
926
1015
|
len(shouldnt_be_in_params) == 0
|
927
1016
|
), "The following parameters are extra: {}".format(shouldnt_be_in_params)
|
928
1017
|
|
929
|
-
def prepare_state_and_params(
|
1018
|
+
def prepare_state_and_params(
|
1019
|
+
self,
|
1020
|
+
state,
|
1021
|
+
params,
|
1022
|
+
state_preperation_functions=None,
|
1023
|
+
parameter_preperation_functions=None,
|
1024
|
+
):
|
930
1025
|
self.validate_state_and_params(state, params)
|
931
1026
|
state = deepcopy(state)
|
932
1027
|
params = deepcopy(params)
|
933
1028
|
state["Stateful Metrics"] = self.stateful_metrics
|
1029
|
+
if state_preperation_functions:
|
1030
|
+
for f in state_preperation_functions:
|
1031
|
+
state = f(state)
|
1032
|
+
assert (
|
1033
|
+
state is not None
|
1034
|
+
), "A state must be returned from the state preperation functions"
|
1035
|
+
if parameter_preperation_functions:
|
1036
|
+
for f in parameter_preperation_functions:
|
1037
|
+
params = f(params)
|
1038
|
+
assert (
|
1039
|
+
params is not None
|
1040
|
+
), "A parameter set must be returned from the parameter preperation functions"
|
934
1041
|
return state, params
|
1042
|
+
|
1043
|
+
def load_components(self):
|
1044
|
+
self.components = {}
|
1045
|
+
self.components.update(self.control_actions)
|
1046
|
+
self.components.update(self.boundary_actions)
|
1047
|
+
self.components.update(self.policies)
|
1048
|
+
self.components.update(self.mechanisms)
|
1049
|
+
self.components.update(self.wiring)
|
1050
|
+
|
1051
|
+
def execute_blocks(self, state, params, blocks):
|
1052
|
+
for block in blocks:
|
1053
|
+
self.components[block](state, params, [])
|
1054
|
+
return state
|
@@ -39,19 +39,27 @@ def remove_dummy_repo_components(path):
|
|
39
39
|
with open(path2 + "/__init__.py", "w") as f:
|
40
40
|
f.write(contents)
|
41
41
|
|
42
|
-
|
42
|
+
if "Displays" in directory_folders:
|
43
43
|
path2 = path + "/Displays"
|
44
44
|
contents = os.listdir(path2)
|
45
|
-
if "
|
46
|
-
|
47
|
-
if "__init__.py" in contents:
|
48
|
-
with open(path2 + "/__init__.py", "r") as f:
|
45
|
+
if "wiring.py" in contents:
|
46
|
+
with open(path2 + "/wiring.py", "r") as f:
|
49
47
|
contents = f.read()
|
50
|
-
|
51
|
-
contents = contents.replace("
|
52
|
-
contents = contents.replace("
|
53
|
-
|
54
|
-
|
48
|
+
|
49
|
+
contents = contents.replace('"Dummy Boundary Wiring 2",\n', "")
|
50
|
+
contents = contents.replace('"Dummy Boundary Wiring 2",', "")
|
51
|
+
contents = contents.replace('"Dummy Boundary Wiring 2"', "")
|
52
|
+
|
53
|
+
contents = contents.replace('"Dummy Boundary Wiring",\n', "")
|
54
|
+
contents = contents.replace('"Dummy Boundary Wiring",', "")
|
55
|
+
contents = contents.replace('"Dummy Boundary Wiring"', "")
|
56
|
+
|
57
|
+
contents = contents.replace('"Dummy Control Wiring",\n', "")
|
58
|
+
contents = contents.replace('"Dummy Control Wiring",', "")
|
59
|
+
contents = contents.replace('"Dummy Control Wiring"', "")
|
60
|
+
|
61
|
+
with open(path2 + "/wiring.py", "w") as f:
|
62
|
+
f.write(contents)
|
55
63
|
|
56
64
|
if "Wiring" in directory_folders:
|
57
65
|
path2 = path + "/Wiring"
|
@@ -104,8 +112,14 @@ def remove_dummy_repo_components(path):
|
|
104
112
|
with open(path2 + "/__init__.py", "r") as f:
|
105
113
|
contents = f.read()
|
106
114
|
contents = contents.replace(
|
107
|
-
"from .Dummy import dummy_boundary_action\n",
|
115
|
+
"from .Dummy import dummy_boundary_action, dummy_boundary_action2\n",
|
116
|
+
"",
|
108
117
|
)
|
118
|
+
|
119
|
+
contents = contents.replace("dummy_boundary_action2,\n", "")
|
120
|
+
contents = contents.replace("dummy_boundary_action2,", "")
|
121
|
+
contents = contents.replace("dummy_boundary_action2", "")
|
122
|
+
|
109
123
|
contents = contents.replace("dummy_boundary_action,\n", "")
|
110
124
|
contents = contents.replace("dummy_boundary_action,", "")
|
111
125
|
contents = contents.replace("dummy_boundary_action", "")
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: math-spec-mapping
|
3
|
-
Version: 0.3.
|
3
|
+
Version: 0.3.8
|
4
4
|
Summary: A library for easy mapping of mathematical specifications.
|
5
5
|
Author-email: Sean McOwen <Sean@Block.Science>
|
6
6
|
Classifier: Programming Language :: Python :: 3
|
@@ -45,8 +45,9 @@ Writing mathematical specifications can be a difficult process, especially when
|
|
45
45
|
```mermaid
|
46
46
|
graph TD
|
47
47
|
A[JSON Object \n\n Each spec has a repo for tracking changes \n Must conform to the json specification \n Defines all aspects of the spec including blocks, spaces and actions] -->B[MSML Object \n\n JSON file is parsed, with validations and mappings along the way \n Can show different views on the fly]
|
48
|
-
B --> C[Report Outputs \n\n Automatically build reports for the full spec or subviews \n Example: all blocks with an effect on variable XYZ]
|
49
|
-
|
48
|
+
B --> C[Report Outputs & Obsidian Directory \n\n Automatically build reports for the full spec or subviews \n Example: all blocks with an effect on variable XYZ\n Also builds an entire Obsidian directory of all components as linked notes]
|
49
|
+
D[Python Function Implementations \n\n Optional enhancement to actually execute code\n Done for each referenced policy option, mechanism, etc. \n Just needs a function definition for each] --> B
|
50
|
+
B --> E[Python Wirings & Simulations \n\n MSML can be used to run blocks \n Wirings automatically work to pass between domain/codomains \n Entire simulations can be built up as composed wirings]
|
50
51
|
```
|
51
52
|
|
52
53
|
## MSML in the Engineering Lifecycle
|
@@ -6,7 +6,7 @@ math_spec_mapping/Classes/Block.py,sha256=cGtIhNgRfoDZ0O3SxeXcNzNlHcdXIB89sT2uaZ
|
|
6
6
|
math_spec_mapping/Classes/BoundaryAction.py,sha256=KuZqtvZwSHWDP7gFQXGnG-r3EuYJU_oU9wMCuqvRkzk,593
|
7
7
|
math_spec_mapping/Classes/ControlAction.py,sha256=ysqpgANwdizVdwqtgZmnxXMpCqrzmVEF_6YT0M3l4Ho,526
|
8
8
|
math_spec_mapping/Classes/Entity.py,sha256=fA0-b128_OHHxfCg4pzqyQV083EYev1HlVpy86S5igg,1226
|
9
|
-
math_spec_mapping/Classes/MathSpec.py,sha256=
|
9
|
+
math_spec_mapping/Classes/MathSpec.py,sha256=6cBpp9OHmfU-XTqPI4Qjnj91cXRxfGtcAQnczOKxt-4,39892
|
10
10
|
math_spec_mapping/Classes/Mechanism.py,sha256=2sLm3wYBIeTQaMBcsJ9btqIWsbS895Ra8NY6Y9_G_Dg,379
|
11
11
|
math_spec_mapping/Classes/Metric.py,sha256=AhPgYppOP6q49xvR8S9STxQsXUKJlTWx7wI1LfZEtww,581
|
12
12
|
math_spec_mapping/Classes/Parameter.py,sha256=ZuJ_w0sChvRElJ4sOnXZ2EV4Ell2xXFulKLjVOpgz2E,1237
|
@@ -19,7 +19,7 @@ math_spec_mapping/Classes/Type.py,sha256=2KFY8d3cv1PzJJ7SSMHJf1zcfQ3ZbqxotK2KgTa
|
|
19
19
|
math_spec_mapping/Classes/__init__.py,sha256=0zxgOqns_9JybD74HKMVh6aw8ij8WVbfQ4Q_1uWzof0,761
|
20
20
|
math_spec_mapping/Convenience/__init__.py,sha256=z2W-E5Wg1CNEkDI5UqH3qIVBqp-3A1e63f3u9fA-N7w,112
|
21
21
|
math_spec_mapping/Convenience/documentation.py,sha256=1ziWVJznbCUxeAAt03nAdEYtMlXNo5TeedHfgs0vSBU,1625
|
22
|
-
math_spec_mapping/Convenience/starter.py,sha256=
|
22
|
+
math_spec_mapping/Convenience/starter.py,sha256=vflOgTVRvM5OMBB7kHnoLR-sGeukKxOJNJmJzQm9Ick,11649
|
23
23
|
math_spec_mapping/Load/__init__.py,sha256=_ga5nHi7U5rY5lCF36_XI9Qmybq4P8R4m5I5mmjLBk8,33
|
24
24
|
math_spec_mapping/Load/action_transmission_channel.py,sha256=9Wer7g2s5SSOcUYuZ0PqSKUVVnW3EvGQJZNXJTwW__0,2561
|
25
25
|
math_spec_mapping/Load/boundary_actions.py,sha256=q-jxhu8FaKNjdOdexlK6f22GDgraGa1jnL5kEzQ7mJY,2625
|
@@ -53,8 +53,8 @@ math_spec_mapping/Reports/spaces.py,sha256=-76hR5wQBv4lsG000ypBJ-OprjsNjI-rNRMYd
|
|
53
53
|
math_spec_mapping/Reports/state.py,sha256=RkqfSonar74KVC8PpA9GgI2xaHX6BrkNdAuWMZlYQfI,2321
|
54
54
|
math_spec_mapping/Reports/tables.py,sha256=O0CNuqh3LMECq5uLjBOoxMUk5hUvkUK660FNnwWUxDY,1505
|
55
55
|
math_spec_mapping/Reports/wiring.py,sha256=u9SvKWy6T-WJUEgFI6-zgZanoOaTTs_2YwmEceDLsV8,1618
|
56
|
-
math_spec_mapping-0.3.
|
57
|
-
math_spec_mapping-0.3.
|
58
|
-
math_spec_mapping-0.3.
|
59
|
-
math_spec_mapping-0.3.
|
60
|
-
math_spec_mapping-0.3.
|
56
|
+
math_spec_mapping-0.3.8.dist-info/LICENSE,sha256=ObyEzSw8kgCaFbEfpu1zP4TrcAKLA0xhqHMZZfyh7N0,1069
|
57
|
+
math_spec_mapping-0.3.8.dist-info/METADATA,sha256=Rcdfu5GQQlfA6GnvqZopFBd2zJGe2JpHKoWUXVf3yoY,6500
|
58
|
+
math_spec_mapping-0.3.8.dist-info/WHEEL,sha256=y4mX-SOX4fYIkonsAGA5N0Oy-8_gI4FXw5HNI1xqvWg,91
|
59
|
+
math_spec_mapping-0.3.8.dist-info/top_level.txt,sha256=AImhn9wgazkdV0a9vfiphtQR8uGe2nq-ZIOp-6yUk9o,18
|
60
|
+
math_spec_mapping-0.3.8.dist-info/RECORD,,
|
File without changes
|
File without changes
|