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.
@@ -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 spaces_mapping:
801
- spaces_i = [spaces[i] for i in spaces_mapping[component]]
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(self, state, 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
- """if "Displays" in directory_folders:
42
+ if "Displays" in directory_folders:
43
43
  path2 = path + "/Displays"
44
44
  contents = os.listdir(path2)
45
- if "Dummy.py" in contents:
46
- os.remove(path2 + "/Dummy.py")
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
- contents = contents.replace("from .Dummy import metrics_x\n", "")
51
- contents = contents.replace("metrics.extend(metrics_x)\n", "")
52
- contents = contents.replace("metrics.extend(metrics_x)", "")
53
- with open(path2 + "/__init__.py", "w") as f:
54
- f.write(contents)"""
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.6
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=qH0F43SjytPDmxM1Hy3-8z9HzfRqNca-5X-6Vc5Sv8M,35294
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=Pv0b5pHnv5Bxk3PkY8O9Nv62z2C_gxj5xcf8G9r4Pkw,11010
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.6.dist-info/LICENSE,sha256=ObyEzSw8kgCaFbEfpu1zP4TrcAKLA0xhqHMZZfyh7N0,1069
57
- math_spec_mapping-0.3.6.dist-info/METADATA,sha256=j1RD4vS3rk4E76cXbVAPsdYAKBjT2o6wpCNIQvKG1Ag,6012
58
- math_spec_mapping-0.3.6.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
59
- math_spec_mapping-0.3.6.dist-info/top_level.txt,sha256=AImhn9wgazkdV0a9vfiphtQR8uGe2nq-ZIOp-6yUk9o,18
60
- math_spec_mapping-0.3.6.dist-info/RECORD,,
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,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: bdist_wheel (0.43.0)
2
+ Generator: setuptools (70.2.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5