Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
bf5ddea
add initial visualization
proy30 May 30, 2025
2f846fc
add colors based off of element name
proy30 May 30, 2025
ee49d10
add settings and dialogs
proy30 May 30, 2025
b39b58e
fix __main__.py
proy30 May 30, 2025
e6b69b7
add: statistics
proy30 May 30, 2025
62e8455
statistics: modify
proy30 May 31, 2025
79a7000
update state.periods
proy30 May 31, 2025
e4d0ac2
rename classes
proy30 Jun 4, 2025
8fa965f
rename utils -> statistic_utils.py
proy30 Jun 4, 2025
6b09e8c
move statistic updates to own helper function
proy30 Jun 4, 2025
17c61a5
change colors
proy30 Jun 5, 2025
2b0eff9
draft - lattice visualizer
proy30 Jun 4, 2025
f658acd
add legend for each unique element
proy30 Jun 6, 2025
b7a82ef
group up indexes in legend
proy30 Jun 6, 2025
7f963c5
get element parameters name
proy30 Jun 6, 2025
a2eec42
do not display labels past 20 elements
proy30 Jun 6, 2025
90d5a72
fix hover annotations
proy30 Jun 6, 2025
5e24953
refactor: element hover text
proy30 Jun 10, 2025
0987884
display the element index on hover
proy30 Jun 10, 2025
e055af2
simplify: remove call to 'classify_elements'
proy30 Jun 10, 2025
027f443
add back removed annotation method
proy30 Jun 10, 2025
d712fca
fix unique elements showing on legend
proy30 Jun 10, 2025
1fce53c
add more defaults to _add_trace
proy30 Jun 10, 2025
2bab9aa
move visualization files to own folder
proy30 Jun 10, 2025
d1a9b27
create utilities file for the visualizer
proy30 Jun 10, 2025
c2045eb
update: dialogs.py
proy30 Jun 10, 2025
db34eb4
update ui.py
proy30 Jun 10, 2025
88b789e
rename statistics_utils -> statistics
proy30 Jun 10, 2025
b186001
update ui.py
proy30 Jun 10, 2025
af5dd22
use helper function to retrieve lattice values
proy30 Jun 10, 2025
4ffcf1f
add: calculation.py for the visualizer
proy30 Jun 10, 2025
44fc940
store quad colors in global dict
proy30 Jun 10, 2025
473e348
create elements folder inside of lattice/visualization
proy30 Jun 10, 2025
d69d664
fix import and state.periods for stats
proy30 Jun 10, 2025
68d9ea2
Merge branch 'development' into dashboard/rebase_lattice_visualizer
proy30 Aug 15, 2025
d35d9f4
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Aug 15, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
from .dialogs import LatticeVisualizerDialogs as Dialogs
from .statistics import LatticeVisualizerStatisticComponents as StatComponents
from .statistics import LatticeVisualizerStatisticUtils as StatUtils

__all__ = [
"Dialogs",
"StatComponents",
"StatUtils",
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
"""
This file is part of ImpactX

Copyright 2025 ImpactX contributors
Authors: Parthib Roy
License: BSD-3-Clause-LBNL
"""

from .... import vuetify
from ....Input.components.card import CardComponents


class LatticeVisualizerDialogs:
@staticmethod
def settings():
"""
A button to open the settings dialog for the lattice visualizer.
"""
CardComponents.card_button(
"mdi-cog",
color="white",
click="lattice_visualizer_dialog_settings = true",
description="Settings",
)

@staticmethod
def element_colors_tab():
"""
A tab inside of the settings dialog to manage element colors.
"""

with vuetify.VCardText():
with vuetify.VRow():
with vuetify.VCol(cols=12):
vuetify.VCardSubtitle(
"Element Color Mapping",
)

@staticmethod
def general_settings_tab():
"""
A tab inside of the settings dialog for general settings.
"""

with vuetify.VCardText():
with vuetify.VRow():
with vuetify.VCol(cols=12):
vuetify.VCardSubtitle(
"Settings",
)
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
"""
Helper function to extract parameter values from the lattice list.
:param parameter_name: Name of the parameter to extract (case-insensitive)
:param value_type: Type to convert values to (float, int, etc.)
:return: List of extracted values
Expand All @@ -42,6 +43,8 @@

return values

return values

Check warning

Code scanning / CodeQL

Unreachable code Warning

This statement is unreachable.

@staticmethod
def update_length_statistics() -> None:
"""
Expand All @@ -67,11 +70,11 @@
state.length_stats_content = []

@staticmethod
def update_element_counts() -> dict[str, int]:
def update_element_counts() -> list[tuple[str, int]]:
"""
Computes the element counts in the lattice list.
:return: Dictionary of element names and their counts, sorted by count descending.
:return: List of (element name, count) tuples, sorted by count descending.
"""
counts = {}
for element in state.selected_lattice_list:
Expand Down
42 changes: 39 additions & 3 deletions src/python/impactx/dashboard/Input/visualization/lattice/ui.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,13 @@
License: BSD-3-Clause-LBNL
"""

from .... import html, state, vuetify
from ....Input.components import CardBase
from . import StatComponents, StatUtils
from trame.widgets import plotly

from .... import ctrl, html, state, vuetify
from ....Input.components.card import CardBase
from ....Input.components.navigation import NavigationComponents
from . import Dialogs, StatComponents, StatUtils
from .visualization.plot import lattice_visualizer


def _update_statistics() -> None:
Expand All @@ -21,9 +25,17 @@ def _update_statistics() -> None:
StatUtils.update_length_statistics()


def _update_lattice_visualization() -> None:
"""
Updates the plotly figure with an updated lattice visualization.
"""
ctrl.lattice_figure_update(lattice_visualizer())


@state.change("selected_lattice_list")
def on_lattice_list_change(**kwargs):
_update_statistics()
_update_lattice_visualization()


class LatticeVisualizer(CardBase):
Expand All @@ -38,6 +50,10 @@ def card_content(self):
"""
The content of the lattice visualizer.
"""
with vuetify.VDialog(
v_model=("lattice_visualizer_dialog_settings", False), max_width="33.33vw"
):
self.dialog_settings()

with vuetify.VCard():
with vuetify.VCard(
Expand All @@ -50,4 +66,24 @@ def card_content(self):
with vuetify.VCardTitle(classes="d-flex align-center"):
html.Div("Lattice Statistics")
vuetify.VSpacer()
Dialogs.settings()
StatComponents.statistics()

with vuetify.VCard(color="#002949"):
with vuetify.VCardText():
ctrl.lattice_figure_update = plotly.Figure(
display_mode_bar="true", style="width: 100%; height: 50vh"
).update

@staticmethod
def dialog_settings():
dialog_name = "lattice_visualizer_dialog_tab_settings"

with NavigationComponents.create_dialog_tabs(
dialog_name, 2, ["Element Colors", "General Settings"]
):
with vuetify.VTabsWindow(v_model=(dialog_name, 0)):
with vuetify.VTabsWindowItem():
Dialogs.element_colors_tab()
with vuetify.VTabsWindowItem():
Dialogs.general_settings_tab()
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
from .elements.elements import LatticeVisualizerElements
from .utils import LatticeVisualizerUtils

__all__ = [
"LatticeVisualizerElements",
"LatticeVisualizerUtils",
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
"""
This file is part of ImpactX

Copyright 2025 ImpactX contributors
Authors: Parthib Roy
License: BSD-3-Clause-LBNL

Mathematical calculations for lattice element positioning and transformations.
"""

import numpy as np


def transform(x, y, rotation_deg, dx):
"""
Transform coordinates based on angle and displacement.
"""
rotation_rad = np.radians(rotation_deg)
x_new = x + dx * np.cos(rotation_rad)
y_new = y + dx * np.sin(rotation_rad)
return x_new, y_new


def rotate_corners(
x: float, y: float, rotation_deg: float, ds: float = 1.0, width: float = 0.1
) -> np.ndarray:
"""
Generates rectangle's corners after applying rotation matrix.
This is utilized to properly visualize a rotated lattice element in Plotly.

:param x: starting x-coordinate before the rotation
:param y: starting y-coordinate before the rotation
:param rotation_deg: Rotation angle in degrees, counterclockwise.
:param ds: Length of the rectangle along the local X-axis (default is 1.0).
:param width: Half of the rectangle's height (default is 0.1).
:return: A NumPy array of shape (5, 2) with rotated (x, y) corner coordinates, closed for polygon plotting.
"""
rotation_rad = np.radians(rotation_deg)

corners = np.array(
[
[0, -width],
[ds, -width],
[ds, width],
[0, width],
[0, -width], # close polygon
]
)

R = np.array(
[
[np.cos(rotation_rad), -np.sin(rotation_rad)],
[np.sin(rotation_rad), np.cos(rotation_rad)],
]
)

rotated = corners @ R.T + [x, y]
return rotated
Loading
Loading