-
Notifications
You must be signed in to change notification settings - Fork 30
Bmad conversion bugfixes -- take 2 for #663 #683
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
jank324
wants to merge
16
commits into
master
Choose a base branch
from
redo-663-bmad-conversion-fixes
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from 12 commits
Commits
Show all changes
16 commits
Select commit
Hold shift + click to select a range
3b8c654
Reapply "Bmad conversion bugfixes (#663)"
jank324 9ee159c
Clean up and refine Bmad conversion fixes
jank324 ff85447
Separate namelist expression evaluation tests for context and string …
jank324 a924652
Improve changelog entry
jank324 9ba4ade
Merge branch 'master' into redo-663-bmad-conversion-fixes
jank324 8aa9b23
FIx format
jank324 e720cef
Merge branch 'redo-663-bmad-conversion-fixes' of https://github.com/d…
jank324 5ca2a1f
Formatting
jank324 66530b3
Clean up and refactor `resolve_object_name_wildcard`
jank324 cc1fceb
Apply suggestions from code review
jank324 7bc5be7
Move `crab_cavity` to near `lcavity`, which is a kind of similar element
jank324 3e9e383
Merge branch 'redo-663-bmad-conversion-fixes' of https://github.com/d…
jank324 dd94a6a
Apply suggestions from code review
jank324 bf19de1
Minor cleaner code format fix
jank324 bbb9edd
Merge branch 'redo-663-bmad-conversion-fixes' of https://github.com/d…
jank324 faca7a5
Fix precedence
jank324 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -28,13 +28,7 @@ | |
| ) | ||
| LINE_DEFINITION_PATTERN = f"({ELEMENT_NAME_PATTERN})" + r"\s*\:\s*line\s*=\s*\((.*)\)" | ||
| USE_LINE_PATTERN = r'use\s*\,\s*([a-z0-9_]+|"[a-z0-9_\-\.\:]+")' | ||
| OVERLAY_DEFINITION_PATTERN = ( | ||
| f"({ELEMENT_NAME_PATTERN})" r"\s*\:\s*overlay\s*=\s*\{(.*)\}\s*\,\s*var\s*=\s*" | ||
| ) | ||
| OVERLAY_KNOT_BASED_PATTERN = ( | ||
| OVERLAY_DEFINITION_PATTERN + r"\{\s*([a-z0-9_]+)\s*\}\s*\,\s*x_knot\s*=\s*\{(.*)\}" | ||
| ) | ||
| OVERLAY_EXPRESSION_BASED_PATTERN = OVERLAY_DEFINITION_PATTERN + r"\{(.*)\}\s*(\,.*)*" | ||
| CONTROL_DEFINITION_PATTERN = rf"({ELEMENT_NAME_PATTERN})\s*:\s*(?:overlay|group)\b.*" | ||
|
|
||
|
|
||
| def read_clean_lines(lattice_file_path: Path) -> list[str]: | ||
|
|
@@ -143,6 +137,12 @@ def evaluate_expression(expression: str, context: dict) -> Any: | |
| except ValueError: | ||
| pass | ||
|
|
||
| # Check against string literals enclosed in quotes | ||
| if (expression.startswith('"') and expression.endswith('"')) or ( | ||
| expression.startswith("'") and expression.endswith("'") | ||
| ): | ||
| return expression[1:-1] | ||
|
|
||
| # Check against allowed keywords | ||
| if expression in ["open", "electron", "t", "f", "traveling_wave", "full"]: | ||
| return expression | ||
|
|
@@ -168,28 +168,26 @@ def evaluate_expression(expression: str, context: dict) -> Any: | |
| return expression | ||
|
|
||
|
|
||
| def resolve_object_name_wildcard(wildcard_pattern: str, context: dict) -> list: | ||
| def resolve_object_name_wildcard(wildcard_pattern: str, context: dict) -> list[str]: | ||
| """ | ||
| Return a list of object names that match the given wildcard pattern. | ||
|
|
||
| :param wildcard_pattern: Wildcard pattern to match. | ||
| :param context: Dictionary of variables among which to search for matching object. | ||
| :return: List of object names that match the given wildcard pattern, both in terms | ||
| of name and element type. | ||
| Return a list of element names in context matching a name pattern and/or type | ||
| prefix. | ||
| """ | ||
| object_type, object_name = wildcard_pattern.split("::") | ||
| if "::" in wildcard_pattern: | ||
| object_type, object_name = wildcard_pattern.split("::", maxsplit=1) | ||
| else: | ||
| object_type, object_name = None, wildcard_pattern | ||
|
|
||
| pattern = object_name.replace("*", ".*").replace("%", ".") | ||
| name_matching_keys = [key for key in context.keys() if re.fullmatch(pattern, key)] | ||
| type_matching_keys = [ | ||
| key | ||
| for key in name_matching_keys | ||
| if isinstance(context[key], dict) | ||
| and "element_type" in context[key] | ||
| and context[key]["element_type"] == object_type | ||
| ] | ||
|
|
||
| return type_matching_keys | ||
| return [ | ||
| name | ||
| for name, element in context.items() | ||
| if isinstance(element, dict) | ||
| and "element_type" in element | ||
| and (object_type is None or element["element_type"] == object_type) | ||
| and re.fullmatch(pattern, name) | ||
| ] | ||
|
|
||
|
|
||
| def assign_property(line: str, context: dict) -> dict: | ||
|
|
@@ -207,7 +205,7 @@ def assign_property(line: str, context: dict) -> dict: | |
| property_name = match.group(2).strip() | ||
| property_expression = match.group(3).strip() # TODO: Evaluate expression first | ||
|
|
||
| if "*" in object_name or "%" in object_name: | ||
| if "*" in object_name or "%" in object_name or "::" in object_name: | ||
| object_names = resolve_object_name_wildcard(object_name, context) | ||
| else: | ||
| object_names = [object_name] | ||
|
|
@@ -271,7 +269,7 @@ def define_element(line: str, context: dict) -> dict: | |
| for property_string in property_matches: | ||
| property_string = property_string.strip() | ||
|
|
||
| property_name, property_expression = property_string.split("=") | ||
| property_name, property_expression = property_string.split("=", maxsplit=1) | ||
| property_name = property_name.strip() | ||
| property_expression = property_expression.strip() | ||
|
|
||
|
|
@@ -310,50 +308,6 @@ def define_line(line: str, context: dict) -> dict: | |
| return context | ||
|
|
||
|
|
||
| def define_overlay(line: str, context: dict) -> dict: | ||
| """ | ||
| Define an overlay in the context. | ||
|
|
||
| :param line: Line of an overlay definition to be parsed. | ||
| :param context: Dictionary of variables to define the overlay in and from which to | ||
| read variables. | ||
| :return: Updated context. | ||
| """ | ||
|
|
||
| expression_match = re.fullmatch(OVERLAY_EXPRESSION_BASED_PATTERN, line) | ||
| knot_match = re.fullmatch(OVERLAY_KNOT_BASED_PATTERN, line) | ||
|
|
||
| if knot_match: | ||
| overlay_name = knot_match.group(1).strip() | ||
| overlay_definition = knot_match.group(2).strip() | ||
| overlay_variable = knot_match.group(3).strip() | ||
| overlay_x_knot = knot_match.group(4).strip() | ||
|
|
||
| context[overlay_name] = { | ||
| "overlay_definition": overlay_definition, | ||
| "overlay_variable": overlay_variable, | ||
| "overlay_x_knot": overlay_x_knot, | ||
| } | ||
| elif expression_match: | ||
| overlay_name = expression_match.group(1).strip() | ||
| overlay_definition = expression_match.group(2).strip() | ||
| overlay_variables = expression_match.group(3).strip() | ||
| if expression_match.group(4) is not None: | ||
| overlay_parameters = expression_match.group(4).strip()[1:].strip() | ||
| else: | ||
| overlay_parameters = None | ||
|
|
||
| context[overlay_name] = { | ||
| "overlay_definition": overlay_definition, | ||
| "overlay_variables": overlay_variables, | ||
| "overlay_parameters": overlay_parameters, | ||
| } | ||
| else: | ||
| raise ValueError(f"Overlay definition {line} not understood.") | ||
|
|
||
| return context | ||
|
Comment on lines
-313
to
-354
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm not sure how good of an idea it is to remove this now, but it seems like currently this is dead code ... and who knows if it actually works. I don't remember. |
||
|
|
||
|
|
||
| def parse_use_line(line: str, context: dict) -> dict: | ||
| """ | ||
| Parse a use line. | ||
|
|
@@ -410,8 +364,9 @@ def parse_lines(lines: str) -> dict: | |
| context = assign_variable(line, context) | ||
| elif re.fullmatch(LINE_DEFINITION_PATTERN, line): | ||
| context = define_line(line, context) | ||
| elif re.fullmatch(OVERLAY_DEFINITION_PATTERN, line): | ||
| context = define_overlay(line, context) | ||
| elif re.fullmatch(CONTROL_DEFINITION_PATTERN, line): | ||
| # Overlay and group definitions are control entries; skip for simplicity. | ||
| continue | ||
| elif re.fullmatch(ELEMENT_DEFINITION_PATTERN, line): | ||
| context = define_element(line, context) | ||
| elif re.fullmatch(USE_LINE_PATTERN, line): | ||
|
|
||
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.