Skip to content

Commit

Permalink
Utilize shared state in dashboard (#834)
Browse files Browse the repository at this point in the history
* Use shared state for input parameters section

* Only call state change when input is string

Since the state change converts the input value from a string to a numeric, we do not want the input value to be read in numerous times.

* Update docstring for custom text_field

* include csr to shared state

can't include others (distribution parameters/lattice config/space charge because either their states are nested by dictionary use or they use different validation errors. In the future, it would be good to have a single validation function than multiple separate ones.

* move shared state logic to new shared.py

* remove print statement

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
  • Loading branch information
proy30 and pre-commit-ci[bot] authored Feb 10, 2025
1 parent b7a99e7 commit d8a963c
Show file tree
Hide file tree
Showing 5 changed files with 58 additions and 49 deletions.
10 changes: 8 additions & 2 deletions src/python/impactx/dashboard/Input/components.py
Original file line number Diff line number Diff line change
Expand Up @@ -104,8 +104,14 @@ def text_field(
label: str, v_model_name: Optional[str] = None, **kwargs
) -> vuetify.VTextField:
"""
Creates a Vuetify VTextField component with
pre-filled components.
Creates a Vuetify VTextField component with the following default components:
- error_message state: It's init value is an empty list.
- step: The step value of the input (either set in defaults.py), or
by default is set to 1.
- suffix: The unit of the input (either set in defauts.py), or
by default is empty.
- type: set to 'number' to only allow a numeric input.
- dense: set to 'true' to minimize space usage.
:param label: Display label
:param v_model_name: v_model binding name. Optional, as default name
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,5 +23,4 @@ def card():
with vuetify.VCol(classes="py-0"):
InputComponents.text_field(
label="CSR Bins",
input=(ctrl.input_change, "['csr_bins']"),
)
49 changes: 6 additions & 43 deletions src/python/impactx/dashboard/Input/inputParameters/inputMain.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,54 +7,22 @@
"""

from ... import setup_server, vuetify
from .. import CardComponents, DashboardDefaults, InputComponents, generalFunctions
from .. import CardComponents, InputComponents
from . import InputFunctions

server, state, ctrl = setup_server()

# -----------------------------------------------------------------------------
# Callbacks
# -----------------------------------------------------------------------------


@ctrl.add("input_change")
def validate_and_convert_to_correct_type(state_name):
value = getattr(state, state_name)
desired_type = DashboardDefaults.TYPES[state_name]
validation_name = f"{state_name}_error_message"
conditions = DashboardDefaults.VALIDATION_CONDITION.get(state_name, None)

validation_result = generalFunctions.validate_against(
value, desired_type, conditions
)
setattr(state, validation_name, validation_result)
generalFunctions.update_simulation_validation_status()

if validation_result == []:
converted_value = generalFunctions.convert_to_correct_type(value, desired_type)

if getattr(state, state_name) != converted_value:
setattr(state, state_name, converted_value)
if state_name == "kin_energy_on_ui":
on_kin_energy_unit_change()


@state.change("kin_energy_unit")
def on_kin_energy_unit_change(**kwargs) -> None:
if state.kin_energy_on_ui != 0:
InputFunctions.update_kin_energy_sim_value()


# -----------------------------------------------------------------------------
# Content
# -----------------------------------------------------------------------------


class InputParameters:
"""
User-Input section for beam properties.
"""

@state.change("kin_energy_unit")
def on_kin_energy_unit_change(**kwargs) -> None:
if state.kin_energy_on_ui != 0:
InputFunctions.update_kin_energy_sim_value()

def card(self):
"""
Creates UI content for beam properties.
Expand All @@ -81,27 +49,23 @@ def card(self):
InputComponents.text_field(
label="Ref. Particle Charge",
v_model_name="charge_qe",
input=(ctrl.input_change, "['charge_qe']"),
)
with vuetify.VCol(cols=6, classes="py-0"):
InputComponents.text_field(
label="Ref. Particle Mass",
v_model_name="mass_MeV",
input=(ctrl.input_change, "['mass_MeV']"),
)
with vuetify.VRow(classes="my-0"):
with vuetify.VCol(cols=12, classes="py-0"):
InputComponents.text_field(
label="Number of Particles",
v_model_name="npart",
input=(ctrl.input_change, "['npart']"),
)
with vuetify.VRow(classes="my-2"):
with vuetify.VCol(cols=8, classes="py-0"):
InputComponents.text_field(
label="Kinetic Energy",
v_model_name="kin_energy_on_ui",
input=(ctrl.input_change, "['kin_energy_on_ui']"),
classes="mr-2",
)
with vuetify.VCol(cols=4, classes="py-0"):
Expand All @@ -114,5 +78,4 @@ def card(self):
InputComponents.text_field(
label="Bunch Charge",
v_model_name="bunch_charge_C",
input=(ctrl.input_change, "['bunch_charge_C']"),
)
41 changes: 41 additions & 0 deletions src/python/impactx/dashboard/Input/shared.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
from .. import setup_server
from ..Input.inputParameters.inputMain import InputParameters
from . import DashboardDefaults, generalFunctions

server, state, ctrl = setup_server()


input_parameters_defaults = list(DashboardDefaults.INPUT_PARAMETERS.keys())
space_charge_defaults = list(DashboardDefaults.CSR.keys())
INPUT_DEFAULTS = input_parameters_defaults + space_charge_defaults


class SharedUtilities:
@staticmethod
@state.change(*INPUT_DEFAULTS)
def on_input_state_change(**_):
state_changes = state.modified_keys & set(INPUT_DEFAULTS)
for state_name in state_changes:
if type(state[state_name]) is str:
value = getattr(state, state_name)
desired_type = DashboardDefaults.TYPES.get(state_name, None)
validation_name = f"{state_name}_error_message"
conditions = DashboardDefaults.VALIDATION_CONDITION.get(
state_name, None
)

validation_result = generalFunctions.validate_against(
value, desired_type, conditions
)
setattr(state, validation_name, validation_result)
generalFunctions.update_simulation_validation_status()

if validation_result == []:
converted_value = generalFunctions.convert_to_correct_type(
value, desired_type
)

if getattr(state, state_name) != converted_value:
setattr(state, state_name, converted_value)
if state_name == "kin_energy_on_ui":
InputParameters.on_kin_energy_unit_change()
6 changes: 3 additions & 3 deletions src/python/impactx/dashboard/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,9 @@

server, state, ctrl = setup_server()

# -----------------------------------------------------------------------------
# Router Views
# -----------------------------------------------------------------------------
from .Input.shared import SharedUtilities

shared_utilities = SharedUtilities()

inputParameters = InputParameters()

Expand Down

0 comments on commit d8a963c

Please sign in to comment.