Skip to content

Commit 9b09ad1

Browse files
[pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
1 parent 8569ccb commit 9b09ad1

File tree

6 files changed

+63
-45
lines changed

6 files changed

+63
-45
lines changed

src/python/impactx/dashboard/Input/visualization/lattice/statistics.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,9 @@ def update_element_counts() -> dict[str, int]:
8282

8383
state.lattice_is_empty = len(counts) == 0
8484
# sort from desc. so we see top elements left to right
85-
sorted_counts = dict(sorted(counts.items(), key=lambda item: item[1], reverse=True))
85+
sorted_counts = dict(
86+
sorted(counts.items(), key=lambda item: item[1], reverse=True)
87+
)
8688

8789
state.element_counts = sorted_counts
8890
return sorted_counts

src/python/impactx/dashboard/Toolbar/file_imports/python/lattice_helper.py

Lines changed: 37 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import re
2-
from typing import Dict, List, Set, Any
2+
from typing import Any, Dict, List
3+
34

45
class DashboardLatticeParser:
56
"""
@@ -15,7 +16,7 @@ def __init__(self, content: str):
1516
def parse(self) -> Dict[str, Any]:
1617
"""
1718
Extracts the lattice configuration from provided ImpactX simulation file.
18-
19+
1920
Example return:
2021
{
2122
"lattice_elements": [
@@ -44,21 +45,21 @@ def parse(self) -> Dict[str, Any]:
4445
print(f"Warning: Unsupported operation type: {operation_type}")
4546

4647
clean_lattice_list = self.replace_variables(expanded_elements)
47-
clean_lattice_list_str = '\n'.join(clean_lattice_list)
48+
clean_lattice_list_str = "\n".join(clean_lattice_list)
4849
result = self.parse_cleaned_lattice(clean_lattice_list_str)
4950

5051
return result
5152

5253
def parse_cleaned_lattice(self, content: str) -> Dict[str, List[Dict[str, Any]]]:
5354
"""
5455
Parses the lattice elements from the ImpactX simulation file content.
55-
56+
5657
Extracts element names and their parameters from constructor calls in the format:
5758
elements.ElementName(param1=value1, param2=value2, ...)
58-
59+
5960
EX:
6061
elements.Drift(ds=1.0)
61-
62+
6263
Results in:
6364
{
6465
"lattice_elements": [
@@ -68,7 +69,7 @@ def parse_cleaned_lattice(self, content: str) -> Dict[str, List[Dict[str, Any]]]
6869
}
6970
]
7071
}
71-
72+
7273
:param content: The content of the ImpactX simulation file.
7374
:return: A dictionary containing the parsed lattice elements.
7475
"""
@@ -79,10 +80,7 @@ def parse_cleaned_lattice(self, content: str) -> Dict[str, List[Dict[str, Any]]]
7980
lattice_elements = re.findall(element_pattern, content, re.DOTALL)
8081

8182
for element_name, parameter in lattice_elements:
82-
element = {
83-
"name": element_name,
84-
"parameters": {}
85-
}
83+
element = {"name": element_name, "parameters": {}}
8684

8785
# CHANGE: Updated parameter pattern to handle multiline and whitespace around =
8886
# OLD: r"(\w+)=([^,\)]+)"
@@ -97,11 +95,10 @@ def parse_cleaned_lattice(self, content: str) -> Dict[str, List[Dict[str, Any]]]
9795

9896
return dictionary
9997

100-
10198
def collect_lattice_operations(self, debug: bool = False) -> List[Dict[str, str]]:
10299
"""
103100
Collects lattice operations (sim.lattice.append(), sim.lattice.extend(), and variable.reverse() calls)
104-
in the order they appear in the content.
101+
in the order they appear in the content.
105102
106103
EX:
107104
sim.lattice.append(monitor) ; sim.lattice.extend([drift1, quad1]) ; lattice_half.reverse()
@@ -125,12 +122,16 @@ def collect_lattice_operations(self, debug: bool = False) -> List[Dict[str, str]
125122
# Store sim.lattice.append and sim.lattice.extend calls
126123
for match in re.finditer(lattice_call_pattern, self._content):
127124
operation, arg = match.groups()
128-
operations.append((match.start(), {"type": operation, "argument": arg.strip()}))
125+
operations.append(
126+
(match.start(), {"type": operation, "argument": arg.strip()})
127+
)
129128

130129
# Store .reverse() calls
131130
reverse_pattern = r"(\w+)\.reverse\(\)"
132131
for match in re.finditer(reverse_pattern, self._content):
133-
operations.append((match.start(), {"type": "reverse", "argument": match.group(1)}))
132+
operations.append(
133+
(match.start(), {"type": "reverse", "argument": match.group(1)})
134+
)
134135

135136
# important: sort operations by their position in the content
136137
# since the for loops can be executed in any order
@@ -145,33 +146,33 @@ def _get_variable_assignments(self) -> Dict[str, str]:
145146
"""
146147
Helper function to extract all variable list assignments from content.
147148
Caches the result to avoid re-parsing the same content.
148-
149+
149150
EX:
150151
content = '''
151152
drift1 = elements.Drift(ds=1.0)
152153
cell = [drift1, quad1]
153154
line = [cell, monitor]
154155
'''
155156
_get_variable_assignments()
156-
157+
157158
Results in:
158159
{
159160
"cell": "drift1, quad1",
160161
"line": "cell, monitor"
161162
}
162-
163+
163164
"""
164165
if self._content_hash in self._variable_assignments_cache:
165166
return self._variable_assignments_cache[self._content_hash]
166-
167+
167168
variable_assignments = {}
168169
var_assignment_pattern = r"(\w+)\s*=\s*\[(.*?)\]"
169-
170+
170171
for match in re.finditer(var_assignment_pattern, self._content, re.DOTALL):
171172
var_name = match.group(1)
172173
list_content = match.group(2)
173174
variable_assignments[var_name] = list_content
174-
175+
175176
self._variable_assignments_cache[self._content_hash] = variable_assignments
176177
return variable_assignments
177178

@@ -187,7 +188,7 @@ def _flatten(self, variable_name: str, debug: bool = False) -> List[str]:
187188
sim.lattice.extend(line)
188189
'''
189190
_flatten(content, "line")
190-
191+
191192
Results in:
192193
["drift1", "quad1", "drift1", "quad1"]
193194
@@ -199,22 +200,28 @@ def _flatten(self, variable_name: str, debug: bool = False) -> List[str]:
199200
cache_key = f"{self._content_hash}:{variable_name}"
200201
if cache_key in self._flatten_cache:
201202
return self._flatten_cache[cache_key]
202-
203+
203204
# Get variable assignments (cached)
204205
variable_assignments = self._get_variable_assignments()
205-
206+
206207
# Check if the input is an inline list like "[monitor, elements.Drift(...)]"
207208
if variable_name.startswith("[") and variable_name.endswith("]"):
208209
list_contents = variable_name[1:-1]
209210
# split on commas that are NOT inside parentheses
210-
list_to_flatten = [element.strip() for element in re.split(r",\s*(?![^()]*\))", list_contents) if element.strip()]
211+
list_to_flatten = [
212+
element.strip()
213+
for element in re.split(r",\s*(?![^()]*\))", list_contents)
214+
if element.strip()
215+
]
211216
else:
212217
if variable_name not in variable_assignments:
213218
self._flatten_cache[cache_key] = [variable_name]
214219
return [variable_name] # It's not a list, it's a single element
215220

216221
list_content = variable_assignments[variable_name]
217-
list_to_flatten = [item.strip() for item in list_content.split(",") if item.strip()]
222+
list_to_flatten = [
223+
item.strip() for item in list_content.split(",") if item.strip()
224+
]
218225

219226
expanded = []
220227
for item in list_to_flatten:
@@ -224,9 +231,8 @@ def _flatten(self, variable_name: str, debug: bool = False) -> List[str]:
224231

225232
# Cache the result
226233
self._flatten_cache[cache_key] = expanded
227-
228-
return expanded
229234

235+
return expanded
230236

231237
def replace_variables(self, raw_lattice: List[str]) -> List[str]:
232238
"""
@@ -237,7 +243,7 @@ def replace_variables(self, raw_lattice: List[str]) -> List[str]:
237243
drift1 = elements.Drift(ds=1.0)
238244
quad1 = elements.Quad(k=0.5)
239245
raw_lattice = ["drift1", "quad1"]
240-
(output)
246+
(output)
241247
raw_lattice = ["elements.Drift(ds=1.0)", "elements.Quad(k=0.5)"]
242248
243249
:param raw_lattice: List of lattice element variable names or constructor calls, e.g. ["drift1", "quad1"].
@@ -259,7 +265,7 @@ def replace_variables(self, raw_lattice: List[str]) -> List[str]:
259265
# Replace each item in the list
260266
# later can be optimized by not iterating over the whole raw_lattice list
261267
return [element_mapping.get(item, item) for item in raw_lattice]
262-
268+
263269
def extract_lattice_inputs(self, parsed_lattice: Dict[str, Any]) -> List[str]:
264270
"""
265271
Extracts all parameter values from parsed lattice data.
@@ -303,8 +309,7 @@ def _apply_reverse(self, var_name: str) -> None:
303309
# Clear the flatten cache so future lookups rebuild the list using the new reversed order.
304310
self._flatten_cache.clear()
305311

306-
307-
#-----------------------------------------------------------------------------
312+
# -----------------------------------------------------------------------------
308313
# Debug methods
309314
# -----------------------------------------------------------------------------
310315

src/python/impactx/dashboard/Toolbar/file_imports/python/parser.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -71,8 +71,10 @@ def parse_impactx_simulation_file(file) -> None:
7171
lattice_contents = lattice_parser.parse()
7272

7373
used_inputs = lattice_parser.extract_lattice_inputs(lattice_contents)
74-
variable_contents = DashboardParserHelper.parse_variables(file_content, used_inputs)
75-
74+
variable_contents = DashboardParserHelper.parse_variables(
75+
file_content, used_inputs
76+
)
77+
7678
parsed_values_dictionary = {
7779
**single_input_contents,
7880
**list_input_contents,

src/python/impactx/dashboard/Toolbar/file_imports/ui_populator.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
License: BSD-3-Clause-LBNL
77
"""
88

9-
from copy import error
109
from ... import ctrl, state
1110
from ...Input.lattice.ui import add_lattice_element
1211
from ...Input.lattice.variable_handler import LatticeVariableHandler
@@ -22,7 +21,9 @@ def on_import_file_change(import_file, **kwargs):
2221
populate_impactx_simulation_file_to_ui(import_file)
2322
except Exception as error:
2423
state.import_file_error = True
25-
state.import_file_error_message = f"Unable to parse because of the following error: {error}"
24+
state.import_file_error_message = (
25+
f"Unable to parse because of the following error: {error}"
26+
)
2627
finally:
2728
state.importing_file = False
2829

tests/python/dashboard/test_impactx_examples_import.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,10 @@
77
"""
88

99
from pathlib import Path
10+
1011
from .utils import DashboardTester, get_impactx_root_dir
1112

13+
1214
class DashboardExamples:
1315
def __init__(self, dashboard: DashboardTester):
1416
self.dashboard = dashboard
@@ -83,7 +85,6 @@ def dogleg_lattice(self):
8385
]
8486
self._run_example("dogleg", "dogleg/run_dogleg.py", LATTICE_CONFIGURATION)
8587

86-
8788
def chicane_lattice(self):
8889
"""
8990
Utilizes lattice_half.reverse()
@@ -106,6 +107,7 @@ def chicane_lattice(self):
106107

107108
self._run_example("chicane", "chicane/run_chicane.py", LATTICE_CONFIGURATION)
108109

110+
109111
def test_examples(dashboard):
110112
"""
111113
Exercise a subset of example imports against the running dashboard.

tests/python/dashboard/test_lattice_stats.py

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
License: BSD-3-Clause-LBNL
77
"""
88

9+
910
def test_lattice_stats(dashboard):
1011
"""
1112
Tests the lattice statistics to ensure accuracy and indirectly
@@ -17,35 +18,35 @@ def test_lattice_stats(dashboard):
1718
"total_elements": 11,
1819
"total_length": "3.0m",
1920
"max_length": "1.0m",
20-
"avg_length" : "0.6m",
21+
"avg_length": "0.6m",
2122
"min_length": "0.25m",
2223
"total_steps": 125,
2324
"periods": 1,
24-
"element_counts": {'beammonitor': 6, 'drift': 3, 'quad': 2}
25+
"element_counts": {"beammonitor": 6, "drift": 3, "quad": 2},
2526
}
2627

2728
APOCHROMATIC_EXPECTED_RESULTS = {
2829
"total_elements": 14,
2930
"total_length": "32.5m",
3031
"total_steps": 300,
3132
"periods": 1,
32-
"element_counts": {'chrquad': 8, 'chrdrift': 4, 'beammonitor': 2}
33+
"element_counts": {"chrquad": 8, "chrdrift": 4, "beammonitor": 2},
3334
}
3435

3536
CHICANE_CSR_EXPECTED_RESULTS = {
3637
"total_elements": 14,
3738
"total_length": "15.01m",
3839
"total_steps": 200,
3940
"periods": 1,
40-
"element_counts": {'drift': 4, 'dipedge': 4, 'sbend': 4, 'beammonitor': 2}
41+
"element_counts": {"drift": 4, "dipedge": 4, "sbend": 4, "beammonitor": 2},
4142
}
4243

4344
DOGLEG_REVERSE_EXPECTED_RESULTS = {
4445
"total_elements": 8,
4546
"total_length": "6.51m",
4647
"total_steps": 100,
4748
"periods": 1,
48-
"element_counts": {'beammonitor': 2, 'drift': 2, 'sbend': 2, 'dipedge': 2}
49+
"element_counts": {"beammonitor": 2, "drift": 2, "sbend": 2, "dipedge": 2},
4950
}
5051

5152
IOLATTICE_EXPECTED_RESULTS = {
@@ -54,7 +55,13 @@ def test_lattice_stats(dashboard):
5455
# locally gives 919, pytest gives 2283 when all 5 examples are tested, passes if ran alone
5556
# "total_steps": 918,
5657
"periods": 5,
57-
"element_counts": {"drift": 52, "quad": 39, "dipedge": 16, "sbend": 8, "beammonitor": 2},
58+
"element_counts": {
59+
"drift": 52,
60+
"quad": 39,
61+
"dipedge": 16,
62+
"sbend": 8,
63+
"beammonitor": 2,
64+
},
5865
}
5966

6067
# Begin Testing
@@ -70,4 +77,3 @@ def test_lattice_stats(dashboard):
7077
dashboard.load_example(example)
7178
for state_name, expected_value in expected.items():
7279
dashboard.assert_state(state_name, expected_value)
73-

0 commit comments

Comments
 (0)