Skip to content

Commit 7239c74

Browse files
committed
add @tymekaxai's code
1 parent 7d40c09 commit 7239c74

File tree

2 files changed

+294
-0
lines changed

2 files changed

+294
-0
lines changed

.fernignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
# Specify files that shouldn't be modified by Fern
2+
src/axiomatic/axtract.py
23
src/axiomatic/magic.py

src/axiomatic/axtract.py

Lines changed: 293 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,293 @@
1+
import ipywidgets as widgets # type: ignore
2+
from IPython.display import display # type: ignore
3+
from dataclasses import dataclass, field
4+
5+
OPTION_LIST = {
6+
"IMAGING TELESCOPE": [
7+
"Resolution (panchromatic)",
8+
"Ground sampling distance (panchromatic)",
9+
"Resolution (multispectral)",
10+
"Ground sampling distance (multispectral)",
11+
"Altitude",
12+
"Half field of view",
13+
"Mirror aperture",
14+
"F-number",
15+
"Focal length",
16+
"Pixel size (panchromatic)",
17+
"Pixel size (multispectral)",
18+
"Swath width",
19+
],
20+
"MITRE_Template": [
21+
"Object height",
22+
"Image height",
23+
"Wavelength",
24+
],
25+
}
26+
27+
IMAGING_TELESCOPE = {
28+
"Resolution (panchromatic)": 1.8,
29+
"Ground sampling distance (panchromatic)": 0.6,
30+
"Resolution (multispectral)": 1.8,
31+
"Ground sampling distance (multispectral)": 0.9,
32+
"Altitude": 460000,
33+
"Half field of view": 0.02003638,
34+
"Mirror aperture": 0.60,
35+
"F-number": 5.53,
36+
"Focal length": 3.32,
37+
"Pixel size (panchromatic)": 8.75e-6,
38+
"Pixel size (multispectral)": 13e-6,
39+
"Swath width": 18400,
40+
}
41+
42+
MITRE_Template = {
43+
"Object height": 1.8,
44+
"Image height": 1.8,
45+
"Wavelength": 1.8,
46+
}
47+
48+
49+
@dataclass
50+
class Requirement:
51+
requirement_name: str
52+
latex_symbol: str
53+
value: int
54+
units: str
55+
tolerance: float
56+
sympy_symbol: str = field(init=False)
57+
58+
def __post_init__(self):
59+
self.sympy_symbol = self.latex_symbol.replace("{", "").replace("}", "")
60+
61+
# def getSympySymbol(self):
62+
# return latex2sympy(self.latex_symbol)
63+
64+
@property
65+
def is_fixed(self):
66+
return self.tolerance == 0.0
67+
68+
# @property
69+
# def equations(self, strict=False):
70+
# if self.is_fixed:
71+
# return [sympy.Eq(self.getSympySymbol(), self.value)]
72+
# else:
73+
# signs = [">=", "<="] if not strict else [">", "<"]
74+
# bounds = [self.value - self.tolerance, self.value + self.tolerance]
75+
# return [
76+
# sympy.Rel(self.getSympySymbol(), bound, sign)
77+
# for bound, sign in zip(bounds, signs)
78+
# ]
79+
80+
81+
def _find_symbol(name, variable_dict):
82+
83+
matching_keys = [
84+
key for key, value in variable_dict.items() if name in value["name"]
85+
]
86+
87+
if not matching_keys:
88+
matching_keys.append("unknown")
89+
90+
return matching_keys[0]
91+
92+
93+
def requirements_from_table(results, variable_dict):
94+
requirements = []
95+
96+
for key, value in results["values"].items():
97+
98+
latex_symbol = _find_symbol(key, variable_dict)
99+
100+
name = key
101+
numerical_value = value["Value"]
102+
unit = value["Units"]
103+
tolerance = value["Tolerance"]
104+
105+
requirements.append(
106+
Requirement(
107+
requirement_name=name,
108+
latex_symbol=latex_symbol,
109+
value=numerical_value,
110+
units=unit,
111+
tolerance=tolerance,
112+
)
113+
)
114+
115+
return requirements
116+
117+
118+
def interactive_table(preset_options_dict, variable_dict):
119+
"""
120+
Creates an interactive table with a dropdown for selecting options.
121+
122+
Parameters:
123+
options_dict (dict): A dictionary where keys are dropdown options and
124+
values are lists of row names.
125+
126+
Returns:
127+
dict: A dictionary containing user inputs for the selected rows.
128+
"""
129+
130+
variable_names = [details["name"] for details in variable_dict.values()]
131+
132+
# Placeholder for result dictionary
133+
result = {}
134+
135+
# Create dropdown for options
136+
dropdown = widgets.Dropdown(
137+
options=list(preset_options_dict.keys()),
138+
description="Select Option:",
139+
style={"description_width": "initial"},
140+
)
141+
142+
# Dictionary to hold widgets for user input
143+
value_widgets = {}
144+
145+
# VBox to stack rows vertically
146+
rows_output = widgets.VBox()
147+
148+
# Output widget for confirmation messages
149+
message_output = widgets.Output()
150+
151+
# Mutable container to store the current name label width
152+
name_label_width = ["150px"] # Default width
153+
154+
# Function to display the table based on the dropdown selection
155+
def display_table(change):
156+
selected_option = change["new"]
157+
158+
# Clear existing rows
159+
rows_output.children = []
160+
value_widgets.clear()
161+
162+
if selected_option in preset_options_dict:
163+
rows = preset_options_dict[selected_option]
164+
max_name_length = max(len(name) for name in rows)
165+
# Update the name_label_width based on the longest row name
166+
name_label_width[0] = f"{max_name_length + 2}ch"
167+
168+
for row_name in rows:
169+
# Create name label with dynamic width
170+
name_label = widgets.Label(
171+
value=row_name,
172+
layout=widgets.Layout(width=name_label_width[0]),
173+
)
174+
175+
# Depending on the selected option, set default values
176+
if selected_option == "IMAGING TELESCOPE":
177+
default_value = IMAGING_TELESCOPE.get(row_name, 0.0)
178+
# elif selected_option == "LIDAR":
179+
# default_value = LIDAR.get(row_name, 0.0)
180+
elif selected_option == "MITRE_Template":
181+
default_value = MITRE_Template.get(row_name, 0.0)
182+
183+
# Create input widgets
184+
value_text = widgets.FloatText(
185+
placeholder="Value",
186+
value=default_value,
187+
layout=widgets.Layout(width="150px"),
188+
)
189+
tolerance_text = widgets.FloatText(
190+
placeholder="Tolerance", layout=widgets.Layout(width="150px")
191+
)
192+
accuracy_text = widgets.FloatText(
193+
placeholder="Accuracy", layout=widgets.Layout(width="150px")
194+
)
195+
units_text = widgets.Text(
196+
placeholder="Units", layout=widgets.Layout(width="150px")
197+
)
198+
199+
# Combine widgets into a horizontal box
200+
row = widgets.HBox(
201+
[
202+
name_label,
203+
value_text,
204+
tolerance_text,
205+
accuracy_text,
206+
units_text,
207+
]
208+
)
209+
210+
# Store the row widgets
211+
value_widgets[row_name] = row
212+
213+
# Add the row to the rows_output VBox
214+
rows_output.children += (row,)
215+
216+
# Attach handler to dropdown
217+
dropdown.observe(display_table, names="value")
218+
display(dropdown)
219+
display(rows_output)
220+
display(message_output)
221+
222+
# Function to collect and store user inputs
223+
def submit_values(_):
224+
updated_values = {}
225+
226+
for key, widget in value_widgets.items():
227+
variable = widget.children[0].value
228+
if key.startswith("req_"):
229+
updated_values[variable] = {
230+
"Value": widget.children[1].value,
231+
"Tolerance": widget.children[2].value,
232+
"Accuracy": widget.children[3].value,
233+
"Units": widget.children[4].value,
234+
}
235+
else:
236+
updated_values[key] = {
237+
"Value": widget.children[1].value,
238+
"Tolerance": widget.children[2].value,
239+
"Accuracy": widget.children[3].value,
240+
"Units": widget.children[4].value,
241+
}
242+
243+
result["values"] = updated_values
244+
245+
# Display confirmation message
246+
with message_output:
247+
message_output.clear_output()
248+
249+
# Function to add a new requirement row
250+
def add_req(_):
251+
252+
unique_key = (
253+
f"req_{len([k for k in value_widgets if k.startswith('req_')]) + 1}"
254+
)
255+
256+
# Create a dropdown for variable selection with dynamic width
257+
variable_dropdown = widgets.Dropdown(
258+
options=variable_names,
259+
description="Variable:",
260+
style={"description_width": "initial"},
261+
layout=widgets.Layout(width=2 * name_label_width[0]),
262+
)
263+
value_text = widgets.FloatText(
264+
placeholder="Value",
265+
layout=widgets.Layout(width="150px"),
266+
)
267+
tolerance_text = widgets.FloatText(
268+
placeholder="Tolerance", layout=widgets.Layout(width="150px")
269+
)
270+
accuracy_text = widgets.FloatText(
271+
placeholder="Accuracy", layout=widgets.Layout(width="150px")
272+
)
273+
units_text = widgets.Text(
274+
placeholder="Units", layout=widgets.Layout(width="150px")
275+
)
276+
277+
new_row = widgets.HBox(
278+
[variable_dropdown, value_text, tolerance_text, accuracy_text, units_text]
279+
)
280+
281+
rows_output.children += (new_row,)
282+
value_widgets[unique_key] = new_row
283+
284+
submit_button = widgets.Button(description="Submit")
285+
submit_button.on_click(submit_values)
286+
287+
add_req_button = widgets.Button(description="Add Requirement")
288+
add_req_button.on_click(add_req)
289+
290+
buttons_box = widgets.HBox([submit_button, add_req_button])
291+
display(buttons_box)
292+
293+
return result

0 commit comments

Comments
 (0)