ivoryos 1.3.6__tar.gz → 1.3.8__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.

Potentially problematic release.


This version of ivoryos might be problematic. Click here for more details.

Files changed (110) hide show
  1. {ivoryos-1.3.6 → ivoryos-1.3.8}/PKG-INFO +1 -1
  2. ivoryos-1.3.8/ivoryos/optimizer/nimo_optimizer.py +162 -0
  3. {ivoryos-1.3.6 → ivoryos-1.3.8}/ivoryos/routes/execute/execute.py +1 -1
  4. ivoryos-1.3.8/ivoryos/version.py +1 -0
  5. {ivoryos-1.3.6 → ivoryos-1.3.8}/ivoryos.egg-info/PKG-INFO +1 -1
  6. {ivoryos-1.3.6 → ivoryos-1.3.8}/ivoryos.egg-info/SOURCES.txt +1 -0
  7. ivoryos-1.3.6/ivoryos/version.py +0 -1
  8. {ivoryos-1.3.6 → ivoryos-1.3.8}/LICENSE +0 -0
  9. {ivoryos-1.3.6 → ivoryos-1.3.8}/README.md +0 -0
  10. {ivoryos-1.3.6 → ivoryos-1.3.8}/ivoryos/__init__.py +0 -0
  11. {ivoryos-1.3.6 → ivoryos-1.3.8}/ivoryos/app.py +0 -0
  12. {ivoryos-1.3.6 → ivoryos-1.3.8}/ivoryos/config.py +0 -0
  13. {ivoryos-1.3.6 → ivoryos-1.3.8}/ivoryos/optimizer/ax_optimizer.py +0 -0
  14. {ivoryos-1.3.6 → ivoryos-1.3.8}/ivoryos/optimizer/base_optimizer.py +0 -0
  15. {ivoryos-1.3.6 → ivoryos-1.3.8}/ivoryos/optimizer/baybe_optimizer.py +0 -0
  16. {ivoryos-1.3.6 → ivoryos-1.3.8}/ivoryos/optimizer/registry.py +0 -0
  17. {ivoryos-1.3.6 → ivoryos-1.3.8}/ivoryos/routes/__init__.py +0 -0
  18. {ivoryos-1.3.6 → ivoryos-1.3.8}/ivoryos/routes/api/api.py +0 -0
  19. {ivoryos-1.3.6 → ivoryos-1.3.8}/ivoryos/routes/auth/__init__.py +0 -0
  20. {ivoryos-1.3.6 → ivoryos-1.3.8}/ivoryos/routes/auth/auth.py +0 -0
  21. {ivoryos-1.3.6 → ivoryos-1.3.8}/ivoryos/routes/auth/templates/login.html +0 -0
  22. {ivoryos-1.3.6 → ivoryos-1.3.8}/ivoryos/routes/auth/templates/signup.html +0 -0
  23. {ivoryos-1.3.6 → ivoryos-1.3.8}/ivoryos/routes/control/__init__.py +0 -0
  24. {ivoryos-1.3.6 → ivoryos-1.3.8}/ivoryos/routes/control/control.py +0 -0
  25. {ivoryos-1.3.6 → ivoryos-1.3.8}/ivoryos/routes/control/control_file.py +0 -0
  26. {ivoryos-1.3.6 → ivoryos-1.3.8}/ivoryos/routes/control/control_new_device.py +0 -0
  27. {ivoryos-1.3.6 → ivoryos-1.3.8}/ivoryos/routes/control/templates/controllers.html +0 -0
  28. {ivoryos-1.3.6 → ivoryos-1.3.8}/ivoryos/routes/control/templates/controllers_new.html +0 -0
  29. {ivoryos-1.3.6 → ivoryos-1.3.8}/ivoryos/routes/control/utils.py +0 -0
  30. {ivoryos-1.3.6 → ivoryos-1.3.8}/ivoryos/routes/data/__init__.py +0 -0
  31. {ivoryos-1.3.6 → ivoryos-1.3.8}/ivoryos/routes/data/data.py +0 -0
  32. {ivoryos-1.3.6 → ivoryos-1.3.8}/ivoryos/routes/data/templates/components/step_card.html +0 -0
  33. {ivoryos-1.3.6 → ivoryos-1.3.8}/ivoryos/routes/data/templates/workflow_database.html +0 -0
  34. {ivoryos-1.3.6 → ivoryos-1.3.8}/ivoryos/routes/data/templates/workflow_view.html +0 -0
  35. {ivoryos-1.3.6 → ivoryos-1.3.8}/ivoryos/routes/design/__init__.py +0 -0
  36. {ivoryos-1.3.6 → ivoryos-1.3.8}/ivoryos/routes/design/design.py +0 -0
  37. {ivoryos-1.3.6 → ivoryos-1.3.8}/ivoryos/routes/design/design_file.py +0 -0
  38. {ivoryos-1.3.6 → ivoryos-1.3.8}/ivoryos/routes/design/design_step.py +0 -0
  39. {ivoryos-1.3.6 → ivoryos-1.3.8}/ivoryos/routes/design/templates/components/action_form.html +0 -0
  40. {ivoryos-1.3.6 → ivoryos-1.3.8}/ivoryos/routes/design/templates/components/actions_panel.html +0 -0
  41. {ivoryos-1.3.6 → ivoryos-1.3.8}/ivoryos/routes/design/templates/components/autofill_toggle.html +0 -0
  42. {ivoryos-1.3.6 → ivoryos-1.3.8}/ivoryos/routes/design/templates/components/canvas.html +0 -0
  43. {ivoryos-1.3.6 → ivoryos-1.3.8}/ivoryos/routes/design/templates/components/canvas_footer.html +0 -0
  44. {ivoryos-1.3.6 → ivoryos-1.3.8}/ivoryos/routes/design/templates/components/canvas_header.html +0 -0
  45. {ivoryos-1.3.6 → ivoryos-1.3.8}/ivoryos/routes/design/templates/components/canvas_main.html +0 -0
  46. {ivoryos-1.3.6 → ivoryos-1.3.8}/ivoryos/routes/design/templates/components/deck_selector.html +0 -0
  47. {ivoryos-1.3.6 → ivoryos-1.3.8}/ivoryos/routes/design/templates/components/edit_action_form.html +0 -0
  48. {ivoryos-1.3.6 → ivoryos-1.3.8}/ivoryos/routes/design/templates/components/instruments_panel.html +0 -0
  49. {ivoryos-1.3.6 → ivoryos-1.3.8}/ivoryos/routes/design/templates/components/modals/drop_modal.html +0 -0
  50. {ivoryos-1.3.6 → ivoryos-1.3.8}/ivoryos/routes/design/templates/components/modals/json_modal.html +0 -0
  51. {ivoryos-1.3.6 → ivoryos-1.3.8}/ivoryos/routes/design/templates/components/modals/new_script_modal.html +0 -0
  52. {ivoryos-1.3.6 → ivoryos-1.3.8}/ivoryos/routes/design/templates/components/modals/rename_modal.html +0 -0
  53. {ivoryos-1.3.6 → ivoryos-1.3.8}/ivoryos/routes/design/templates/components/modals/saveas_modal.html +0 -0
  54. {ivoryos-1.3.6 → ivoryos-1.3.8}/ivoryos/routes/design/templates/components/modals.html +0 -0
  55. {ivoryos-1.3.6 → ivoryos-1.3.8}/ivoryos/routes/design/templates/components/python_code_overlay.html +0 -0
  56. {ivoryos-1.3.6 → ivoryos-1.3.8}/ivoryos/routes/design/templates/components/sidebar.html +0 -0
  57. {ivoryos-1.3.6 → ivoryos-1.3.8}/ivoryos/routes/design/templates/components/text_to_code_panel.html +0 -0
  58. {ivoryos-1.3.6 → ivoryos-1.3.8}/ivoryos/routes/design/templates/experiment_builder.html +0 -0
  59. {ivoryos-1.3.6 → ivoryos-1.3.8}/ivoryos/routes/execute/__init__.py +0 -0
  60. {ivoryos-1.3.6 → ivoryos-1.3.8}/ivoryos/routes/execute/execute_file.py +0 -0
  61. {ivoryos-1.3.6 → ivoryos-1.3.8}/ivoryos/routes/execute/templates/components/error_modal.html +0 -0
  62. {ivoryos-1.3.6 → ivoryos-1.3.8}/ivoryos/routes/execute/templates/components/logging_panel.html +0 -0
  63. {ivoryos-1.3.6 → ivoryos-1.3.8}/ivoryos/routes/execute/templates/components/progress_panel.html +0 -0
  64. {ivoryos-1.3.6 → ivoryos-1.3.8}/ivoryos/routes/execute/templates/components/run_panel.html +0 -0
  65. {ivoryos-1.3.6 → ivoryos-1.3.8}/ivoryos/routes/execute/templates/components/run_tabs.html +0 -0
  66. {ivoryos-1.3.6 → ivoryos-1.3.8}/ivoryos/routes/execute/templates/components/tab_bayesian.html +0 -0
  67. {ivoryos-1.3.6 → ivoryos-1.3.8}/ivoryos/routes/execute/templates/components/tab_configuration.html +0 -0
  68. {ivoryos-1.3.6 → ivoryos-1.3.8}/ivoryos/routes/execute/templates/components/tab_repeat.html +0 -0
  69. {ivoryos-1.3.6 → ivoryos-1.3.8}/ivoryos/routes/execute/templates/experiment_run.html +0 -0
  70. {ivoryos-1.3.6 → ivoryos-1.3.8}/ivoryos/routes/library/__init__.py +0 -0
  71. {ivoryos-1.3.6 → ivoryos-1.3.8}/ivoryos/routes/library/library.py +0 -0
  72. {ivoryos-1.3.6 → ivoryos-1.3.8}/ivoryos/routes/library/templates/library.html +0 -0
  73. {ivoryos-1.3.6 → ivoryos-1.3.8}/ivoryos/routes/main/__init__.py +0 -0
  74. {ivoryos-1.3.6 → ivoryos-1.3.8}/ivoryos/routes/main/main.py +0 -0
  75. {ivoryos-1.3.6 → ivoryos-1.3.8}/ivoryos/routes/main/templates/help.html +0 -0
  76. {ivoryos-1.3.6 → ivoryos-1.3.8}/ivoryos/routes/main/templates/home.html +0 -0
  77. {ivoryos-1.3.6 → ivoryos-1.3.8}/ivoryos/server.py +0 -0
  78. {ivoryos-1.3.6 → ivoryos-1.3.8}/ivoryos/socket_handlers.py +0 -0
  79. {ivoryos-1.3.6 → ivoryos-1.3.8}/ivoryos/static/favicon.ico +0 -0
  80. {ivoryos-1.3.6 → ivoryos-1.3.8}/ivoryos/static/gui_annotation/Slide1.png +0 -0
  81. {ivoryos-1.3.6 → ivoryos-1.3.8}/ivoryos/static/gui_annotation/Slide2.PNG +0 -0
  82. {ivoryos-1.3.6 → ivoryos-1.3.8}/ivoryos/static/js/action_handlers.js +0 -0
  83. {ivoryos-1.3.6 → ivoryos-1.3.8}/ivoryos/static/js/db_delete.js +0 -0
  84. {ivoryos-1.3.6 → ivoryos-1.3.8}/ivoryos/static/js/overlay.js +0 -0
  85. {ivoryos-1.3.6 → ivoryos-1.3.8}/ivoryos/static/js/script_metadata.js +0 -0
  86. {ivoryos-1.3.6 → ivoryos-1.3.8}/ivoryos/static/js/socket_handler.js +0 -0
  87. {ivoryos-1.3.6 → ivoryos-1.3.8}/ivoryos/static/js/sortable_card.js +0 -0
  88. {ivoryos-1.3.6 → ivoryos-1.3.8}/ivoryos/static/js/sortable_design.js +0 -0
  89. {ivoryos-1.3.6 → ivoryos-1.3.8}/ivoryos/static/js/ui_state.js +0 -0
  90. {ivoryos-1.3.6 → ivoryos-1.3.8}/ivoryos/static/logo.webp +0 -0
  91. {ivoryos-1.3.6 → ivoryos-1.3.8}/ivoryos/static/style.css +0 -0
  92. {ivoryos-1.3.6 → ivoryos-1.3.8}/ivoryos/templates/base.html +0 -0
  93. {ivoryos-1.3.6 → ivoryos-1.3.8}/ivoryos/utils/__init__.py +0 -0
  94. {ivoryos-1.3.6 → ivoryos-1.3.8}/ivoryos/utils/bo_campaign.py +0 -0
  95. {ivoryos-1.3.6 → ivoryos-1.3.8}/ivoryos/utils/client_proxy.py +0 -0
  96. {ivoryos-1.3.6 → ivoryos-1.3.8}/ivoryos/utils/db_models.py +0 -0
  97. {ivoryos-1.3.6 → ivoryos-1.3.8}/ivoryos/utils/decorators.py +0 -0
  98. {ivoryos-1.3.6 → ivoryos-1.3.8}/ivoryos/utils/form.py +0 -0
  99. {ivoryos-1.3.6 → ivoryos-1.3.8}/ivoryos/utils/global_config.py +0 -0
  100. {ivoryos-1.3.6 → ivoryos-1.3.8}/ivoryos/utils/llm_agent.py +0 -0
  101. {ivoryos-1.3.6 → ivoryos-1.3.8}/ivoryos/utils/py_to_json.py +0 -0
  102. {ivoryos-1.3.6 → ivoryos-1.3.8}/ivoryos/utils/script_runner.py +0 -0
  103. {ivoryos-1.3.6 → ivoryos-1.3.8}/ivoryos/utils/serilize.py +0 -0
  104. {ivoryos-1.3.6 → ivoryos-1.3.8}/ivoryos/utils/task_runner.py +0 -0
  105. {ivoryos-1.3.6 → ivoryos-1.3.8}/ivoryos/utils/utils.py +0 -0
  106. {ivoryos-1.3.6 → ivoryos-1.3.8}/ivoryos.egg-info/dependency_links.txt +0 -0
  107. {ivoryos-1.3.6 → ivoryos-1.3.8}/ivoryos.egg-info/requires.txt +0 -0
  108. {ivoryos-1.3.6 → ivoryos-1.3.8}/ivoryos.egg-info/top_level.txt +0 -0
  109. {ivoryos-1.3.6 → ivoryos-1.3.8}/pyproject.toml +0 -0
  110. {ivoryos-1.3.6 → ivoryos-1.3.8}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ivoryos
3
- Version: 1.3.6
3
+ Version: 1.3.8
4
4
  Summary: an open-source Python package enabling Self-Driving Labs (SDLs) interoperability
5
5
  Author-email: Ivory Zhang <ivoryzhang@chem.ubc.ca>
6
6
  License: MIT
@@ -0,0 +1,162 @@
1
+ ### ivoryos/optimizers/nimo_optimizer.py
2
+ import itertools
3
+ import os
4
+
5
+
6
+ from ivoryos.optimizer.base_optimizer import OptimizerBase
7
+
8
+
9
+ class NIMOOptimizer(OptimizerBase):
10
+ def __init__(self, experiment_name:str, parameter_space: list, objective_config: list, optimizer_config: dict, datapath:str):
11
+ """
12
+ :param experiment_name: arbitrary name
13
+ :param parameter_space: list of parameter names
14
+ [
15
+ {"name": "param_1", "type": "range", "bounds": [1.0, 2.0], "value_type": "float"},
16
+ {"name": "param_2", "type": "choice", "bounds": ["a", "b", "c"], "value_type": "str"},
17
+ {"name": "param_3", "type": "range", "bounds": [0 10], "value_type": "int"},
18
+ ]
19
+ :param objective_config: objective configuration
20
+ [
21
+ {"name": "obj_1", "minimize": True, "weight": 1},
22
+ {"name": "obj_2", "minimize": False, "weight": 1}
23
+ ]
24
+ :param optimizer_config: optimizer configuration
25
+ optimizer_config={
26
+ "step_1": {"model": "Random", "num_samples": 10},
27
+ "step_2": {"model": "BOTorch"}
28
+ }
29
+ """
30
+ self.current_step = 0
31
+ self.experiment_name = experiment_name
32
+ self.parameter_space = parameter_space
33
+ self.objective_config = objective_config
34
+ self.optimizer_config = optimizer_config
35
+
36
+ super().__init__(experiment_name, parameter_space, objective_config, optimizer_config, datapath)
37
+
38
+ step_1 = optimizer_config.get("step_1", {})
39
+ step_2 = optimizer_config.get("step_2", {})
40
+ self.step_1_generator = step_1.get("model", "RE")
41
+ self.step_1_batch_num = step_1.get("num_samples", 1)
42
+ self.step_2_generator = step_2.get("model", "PDC")
43
+ self.candidates = os.path.join(self.datapath, f"{self.experiment_name}_candidates.csv")
44
+ self.proposals = os.path.join(self.datapath, f"{self.experiment_name}_proposals.csv")
45
+ self.n_objectives = len(self.objective_config)
46
+ self._create_candidates_csv()
47
+
48
+
49
+ def _create_candidates_csv(self):
50
+ # Extract parameter names and their possible values
51
+ import pandas as pd
52
+ import nimo
53
+ if os.path.exists(self.candidates) and nimo.history(self.candidates, self.n_objectives):
54
+ return
55
+ param_names = [p["name"] for p in self.parameter_space]
56
+
57
+ param_values = []
58
+ for p in self.parameter_space:
59
+ if p["type"] == "choice" and isinstance(p["bounds"], list):
60
+ param_values.append(p["bounds"])
61
+ elif p["type"] == "range" and len(p["bounds"]) == 2:
62
+ low, high = p["bounds"]
63
+ num_points = 10 # you can customize this granularity
64
+ step = (high - low) / (num_points - 1)
65
+ param_values.append([round(low + i * step, 4) for i in range(num_points)])
66
+ else:
67
+ raise ValueError(f"Unsupported parameter format: {p}")
68
+
69
+ # Generate all possible combinations
70
+ combos = list(itertools.product(*param_values))
71
+
72
+ # Create a DataFrame with parameter columns
73
+ df = pd.DataFrame(combos, columns=param_names)
74
+
75
+ # Add empty objective columns
76
+ for obj in self.objective_config:
77
+ df[obj["name"]] = ""
78
+
79
+ # Save to CSV
80
+ df.to_csv(self.candidates, index=False)
81
+
82
+
83
+ def suggest(self, n=1):
84
+ import pandas as pd
85
+ import nimo
86
+ method = self.step_1_generator if self.current_step <= self.step_1_batch_num else self.step_2_generator
87
+ nimo.selection(method = method,
88
+ input_file = self.candidates,
89
+ output_file = self.proposals,
90
+ num_objectives = self.n_objectives,
91
+ num_proposals = n)
92
+ self.current_step += 1
93
+ # Read proposals from CSV file
94
+ proposals_df = pd.read_csv(self.proposals)
95
+ # Get parameter names
96
+ param_names = [p["name"] for p in self.parameter_space]
97
+ # Convert proposals to list of parameter dictionaries
98
+ proposals = []
99
+ for _, row in proposals_df.iterrows():
100
+ proposal = {name: row[name] for name in param_names}
101
+ proposals.append(proposal)
102
+ return proposals[0] if n == 1 else proposals
103
+
104
+ def _convert_observation_to_list(self, obs: dict) -> list:
105
+ obj_names = [o["name"] for o in self.objective_config]
106
+ return [obs.get(name, None) for name in obj_names]
107
+
108
+ def observe(self, results: dict):
109
+ """
110
+ observe single output, nimo obj input is [1,2,3] or [[1, 2], [1, 2], [1, 2]] for MO
111
+ :param results: {"objective_name": "value"}
112
+ """
113
+ import nimo
114
+ nimo_objective_values = [self._convert_observation_to_list(results)]
115
+
116
+ nimo.output_update(input_file=self.proposals,
117
+ output_file=self.candidates,
118
+ num_objectives=self.n_objectives,
119
+ objective_values=nimo_objective_values)
120
+
121
+ def append_existing_data(self, existing_data):
122
+ # TODO, history is part of the candidate file, we probably won't need this
123
+ pass
124
+
125
+
126
+ @staticmethod
127
+ def get_schema():
128
+ return {
129
+ "parameter_types": ["choice"],
130
+ "multiple_objectives": True,
131
+ "optimizer_config": {
132
+ "step_1": {"model": ["RE", "ES", "PDC"], "num_samples": 5},
133
+ "step_2": {"model": ["PHYSBO", "BLOX", "PTR", "SLESA", "BOMP", "COMBI"]}
134
+ },
135
+ }
136
+
137
+
138
+
139
+
140
+ if __name__ == "__main__":
141
+ parameter_space = [
142
+ {"name": "silica", "type": "choice", "bounds": [100], "value_type": "float"},
143
+ {"name": "water", "type": "choice", "bounds": [900, 800, 750, 700, 650, 600, 550, 500], "value_type": "float"},
144
+ {"name": "PVA", "type": "choice", "bounds": [0, 0.005, 0.0075, 0.01, 0.05, 0.075, 0.1], "value_type": "float"},
145
+ {"name": "SDS", "type": "choice", "bounds": [0], "value_type": "float"},
146
+ {"name": "DTAB", "type": "choice", "bounds": [0, 0.005, 0.0075, 0.01, 0.05, 0.075, 0.1], "value_type": "float"},
147
+ {"name": "PVP", "type": "choice", "bounds": [0], "value_type": "float"},
148
+ ]
149
+ objective_config = [
150
+ {"name": "objective", "minimize": False, "weight": 1},
151
+
152
+ ]
153
+ optimizer_config = {
154
+ "step_1": {"model": "RE", "num_samples": 10},
155
+ "step_2": {"model": "PDC"}
156
+ }
157
+
158
+ nimo_optimizer = NIMOOptimizer(experiment_name="example_experiment", optimizer_config=optimizer_config, parameter_space=parameter_space, objective_config=objective_config)
159
+ nimo_optimizer.suggest(n=1)
160
+ nimo_optimizer.observe(
161
+ results={"objective": 1.0}
162
+ )
@@ -184,7 +184,7 @@ def run_bo():
184
184
  if not Optimizer:
185
185
  raise ValueError(f"Optimizer {optimizer_type} is not supported or not found.")
186
186
  optimizer = Optimizer(experiment_name=run_name, parameter_space=parameters, objective_config=objectives,
187
- optimizer_config=steps)
187
+ optimizer_config=steps, datapath=datapath)
188
188
  runner.run_script(script=script, run_name=run_name, optimizer=optimizer,
189
189
  logger=g.logger, socketio=g.socketio, repeat_count=repeat,
190
190
  output_path=datapath, compiled=False, history=existing_data,
@@ -0,0 +1 @@
1
+ __version__ = "1.3.8"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ivoryos
3
- Version: 1.3.6
3
+ Version: 1.3.8
4
4
  Summary: an open-source Python package enabling Self-Driving Labs (SDLs) interoperability
5
5
  Author-email: Ivory Zhang <ivoryzhang@chem.ubc.ca>
6
6
  License: MIT
@@ -15,6 +15,7 @@ ivoryos.egg-info/top_level.txt
15
15
  ivoryos/optimizer/ax_optimizer.py
16
16
  ivoryos/optimizer/base_optimizer.py
17
17
  ivoryos/optimizer/baybe_optimizer.py
18
+ ivoryos/optimizer/nimo_optimizer.py
18
19
  ivoryos/optimizer/registry.py
19
20
  ivoryos/routes/__init__.py
20
21
  ivoryos/routes/api/api.py
@@ -1 +0,0 @@
1
- __version__ = "1.3.6"
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