diff --git a/src/python/impactx/dashboard/Input/csrConfiguration/csrMain.py b/src/python/impactx/dashboard/Input/csrConfiguration/csrMain.py index a9f664155..178154206 100644 --- a/src/python/impactx/dashboard/Input/csrConfiguration/csrMain.py +++ b/src/python/impactx/dashboard/Input/csrConfiguration/csrMain.py @@ -1,4 +1,4 @@ -from trame.widgets import vuetify +from trame.widgets import html, vuetify from ...trame_setup import setup_server from ..generalFunctions import generalFunctions @@ -47,20 +47,28 @@ def card(): ) vuetify.VDivider() with vuetify.VCardText(): - with vuetify.VRow(classes="my-0"): - with vuetify.VCol(classes="py-0"): + with vuetify.VTooltip(bottom=True, nudge_top="10"): + with vuetify.Template(v_slot_activator="{ on, attrs }"): vuetify.VSelect( label="Particle Shape", v_model=("particle_shape",), items=([1, 2, 3],), dense=True, + v_on="on", + v_bind="attrs", ) + html.Span("{{ parameter_tooltips.particle_shape }}") with vuetify.VRow(classes="my-0"): with vuetify.VCol(classes="py-0"): - vuetify.VTextField( - label="CSR Bins", - v_model=("csr_bins",), - error_messages=("csr_bins_error_message",), - type="number", - dense=True, - ) + with vuetify.VTooltip(bottom=True, nudge_top="10"): + with vuetify.Template(v_slot_activator="{ on, attrs }"): + vuetify.VTextField( + label="CSR Bins", + v_model=("csr_bins",), + error_messages=("csr_bins_error_message",), + type="number", + dense=True, + v_on="on", + v_bind="attrs", + ) + html.Span("{{ parameter_tooltips.csr_bins }}") diff --git a/src/python/impactx/dashboard/Input/distributionParameters/distributionMain.py b/src/python/impactx/dashboard/Input/distributionParameters/distributionMain.py index a1f9d6c2b..3f21c5c62 100644 --- a/src/python/impactx/dashboard/Input/distributionParameters/distributionMain.py +++ b/src/python/impactx/dashboard/Input/distributionParameters/distributionMain.py @@ -9,7 +9,7 @@ import inspect from distribution_input_helpers import twiss -from trame.widgets import vuetify +from trame.widgets import html, vuetify from impactx import distribution @@ -39,6 +39,7 @@ state.selectedDistributionParameters = [] state.distributionTypeDisabled = False + # ----------------------------------------------------------------------------- # Main Functions # ----------------------------------------------------------------------------- @@ -50,7 +51,6 @@ def populate_distribution_parameters(selectedDistribution): :param selectedDistribution (str): The name of the selected distribution whose parameters need to be populated. """ - if state.selectedDistributionType == "Twiss": sig = inspect.signature(twiss) state.selectedDistributionParameters = [ @@ -63,6 +63,9 @@ def populate_distribution_parameters(selectedDistribution): "parameter_error_message": generalFunctions.validate_against( param.default if param.default != param.empty else None, "float" ), + "parameter_tooltip": generalFunctions.parameter_tooltips.get( + param.name, "N/A" + ), "parameter_units": "m" if "beta" in param.name or "emitt" in param.name else "", @@ -85,6 +88,9 @@ def populate_distribution_parameters(selectedDistribution): "parameter_error_message": generalFunctions.validate_against( parameter[1], parameter[2] ), + "parameter_tooltip": generalFunctions.parameter_tooltips.get( + parameter[0], "N/A" + ), "parameter_units": "m" if "beta" in parameter[0] or "emitt" in parameter[0] else "", @@ -219,17 +225,26 @@ def card(): with vuetify.VCol( v_if=f"index % 3 == {i}", classes="py-1" ): - vuetify.VTextField( - label=("parameter.parameter_name",), - v_model=("parameter.parameter_default_value",), - suffix=("parameter.parameter_units",), - change=( - ctrl.updateDistributionParameters, - "[parameter.parameter_name, $event, parameter.parameter_type]", - ), - error_messages=( - "parameter.parameter_error_message", - ), - type="number", - dense=True, - ) + with vuetify.VTooltip(bottom=True, nudge_top="10"): + with vuetify.Template( + v_slot_activator="{ on, attrs }" + ): + vuetify.VTextField( + label=("parameter.parameter_name",), + v_model=( + "parameter.parameter_default_value", + ), + suffix=("parameter.parameter_units",), + change=( + ctrl.updateDistributionParameters, + "[parameter.parameter_name, $event, parameter.parameter_type]", + ), + error_messages=( + "parameter.parameter_error_message", + ), + type="number", + dense=True, + v_on="on", + v_bind="attrs", + ) + html.Span("{{ parameter.parameter_tooltip }}") diff --git a/src/python/impactx/dashboard/Input/generalFunctions.py b/src/python/impactx/dashboard/Input/generalFunctions.py index 94eabcbc7..32100c408 100644 --- a/src/python/impactx/dashboard/Input/generalFunctions.py +++ b/src/python/impactx/dashboard/Input/generalFunctions.py @@ -311,3 +311,29 @@ def convert_to_correct_type(value, desired_type): return str(value) else: raise ValueError("Unknown type") + + # ----------------------------------------------------------------------------- + # Tooltip Comments + # ----------------------------------------------------------------------------- + + parameter_tooltips = { + # Input Parameters + "particle_shape": "Whether to calculate space charge effects.", + "kin_energy": "Get reference particle energy (MeV).", + "charge_qe": "Get reference particle charge (positive elementary charge).", + "npart": "Number of particles to simulate.", + "mass_MeV": "Get reference particle rest mass (MeV/c^2).", + "bunch_charge_C": "Total charge of the particle bunch (Coulombs).", + # Distribution Parameters + "beta_x": "Beta function value (unit: meter) in the x dimension, must be a non-zero positive value.", + "beta_y": "Beta function value (unit: meter) in the y dimension, must be a non-zero positive value.", + "beta_t": "Beta function value (unit: meter) in the t dimension (arrival time differences multiplied by light speed), must be a non-zero positive value.", + "emitt_x": "Emittance value (unit: meter times radian) in the x dimension, must be a non-zero positive value.", + "emitt_y": "Emittance value (unit: meter times radian) in the y dimension, must be a non-zero positive value.", + "emitt_t": "Emittance value (unit: meter times radian) in the t dimension (arrival time differences multiplied by light speed), must be a non-zero positive value.", + "alpha_x": "Alpha function value () in the x dimension, default is 0.0.", + "alpha_y": "Alpha function value in the y dimension, default is 0.0.", + "alpha_t": "Alpha function value in the t dimension, default is 0.0.", + # Lattice Parameters + "nslice": "testing", + } diff --git a/src/python/impactx/dashboard/Input/inputParameters/inputMain.py b/src/python/impactx/dashboard/Input/inputParameters/inputMain.py index baa5a6386..382d4f10c 100644 --- a/src/python/impactx/dashboard/Input/inputParameters/inputMain.py +++ b/src/python/impactx/dashboard/Input/inputParameters/inputMain.py @@ -6,7 +6,7 @@ License: BSD-3-Clause-LBNL """ -from trame.widgets import vuetify +from trame.widgets import html, vuetify from ...trame_setup import setup_server from ..generalFunctions import generalFunctions @@ -80,6 +80,7 @@ def __init__(self): state.bunch_charge_C_validation = [] state.mass_MeV_validation = [] state.charge_qe_validation = [] + state.parameter_tooltips = generalFunctions.parameter_tooltips def card(self): """ @@ -111,58 +112,77 @@ def card(self): ) with vuetify.VRow(classes="my-2"): with vuetify.VCol(cols=6, classes="py-0"): - vuetify.VTextField( - label="Ref. Particle Charge", - v_model=("charge_qe",), - suffix="qe", - type="number", - dense=True, - error_messages=("charge_qe_validation",), - change=( - ctrl.on_input_change, - "[$event, 'int','charge_qe','charge_qe_validation', ['non_zero']]", - ), - ) + with vuetify.VTooltip(bottom=True, nudge_top="10"): + with vuetify.Template(v_slot_activator="{ on, attrs }"): + vuetify.VTextField( + label="Ref. Particle Charge", + v_model=("charge_qe",), + suffix="qe", + type="number", + dense=True, + error_messages=("charge_qe_validation",), + change=( + ctrl.on_input_change, + "[$event, 'int','charge_qe','charge_qe_validation', ['non_zero']]", + ), + v_on="on", + v_bind="attrs", + ) + html.Span("{{ parameter_tooltips.charge_qe }}") with vuetify.VCol(cols=6, classes="py-0"): - vuetify.VTextField( - label="Ref. Particle Mass", - v_model=("mass_MeV",), - suffix="MeV", - type="number", - dense=True, - error_messages=("mass_MeV_validation",), - change=( - ctrl.on_input_change, - "[$event, 'float','mass_MeV','mass_MeV_validation', ['positive']]", - ), - ) + with vuetify.VTooltip(bottom=True, nudge_top="10"): + with vuetify.Template(v_slot_activator="{ on, attrs }"): + vuetify.VTextField( + label="Ref. Particle Mass", + v_model=("mass_MeV",), + suffix="MeV", + type="number", + dense=True, + error_messages=("mass_MeV_validation",), + change=( + ctrl.on_input_change, + "[$event, 'float','mass_MeV','mass_MeV_validation', ['positive']]", + ), + v_on="on", + v_bind="attrs", + ) + html.Span("{{ parameter_tooltips.mass_MeV }}") with vuetify.VRow(classes="my-0"): with vuetify.VCol(cols=12, classes="py-0"): - vuetify.VTextField( - v_model=("npart",), - label="Number of Particles", - error_messages=("npart_validation",), - change=( - ctrl.on_input_change, - "[$event, 'int','npart','npart_validation']", - ), - type="number", - dense=True, - ) + with vuetify.VTooltip(bottom=True, nudge_top="10"): + with vuetify.Template(v_slot_activator="{ on, attrs }"): + vuetify.VTextField( + v_model=("npart",), + label="Number of Particles", + error_messages=("npart_validation",), + change=( + ctrl.on_input_change, + "[$event, 'int','npart','npart_validation']", + ), + type="number", + dense=True, + v_on="on", + v_bind="attrs", + ) + html.Span("{{ parameter_tooltips.npart }}") with vuetify.VRow(classes="my-2"): with vuetify.VCol(cols=8, classes="py-0"): - vuetify.VTextField( - v_model=("kin_energy",), - label="Kinetic Energy", - error_messages=("kin_energy_validation",), - change=( - ctrl.on_input_change, - "[$event, 'float','kin_energy','kin_energy_validation']", - ), - type="number", - dense=True, - classes="mr-2", - ) + with vuetify.VTooltip(bottom=True, nudge_top="10"): + with vuetify.Template(v_slot_activator="{ on, attrs }"): + vuetify.VTextField( + v_model=("kin_energy",), + label="Kinetic Energy", + error_messages=("kin_energy_validation",), + change=( + ctrl.on_input_change, + "[$event, 'float','kin_energy','kin_energy_validation']", + ), + type="number", + dense=True, + v_on="on", + v_bind="attrs", + ) + html.Span("{{ parameter_tooltips.kin_energy }}") with vuetify.VCol(cols=4, classes="py-0"): vuetify.VSelect( v_model=("kin_energy_unit",), @@ -173,17 +193,22 @@ def card(self): ) with vuetify.VRow(classes="my-2"): with vuetify.VCol(cols=8, classes="py-0"): - vuetify.VTextField( - label="Bunch Charge", - v_model=("bunch_charge_C",), - error_messages=("bunch_charge_C_validation",), - change=( - ctrl.on_input_change, - "[$event, 'float','bunch_charge_C','bunch_charge_C_validation']", - ), - type="number", - dense=True, - ) + with vuetify.VTooltip(bottom=True, nudge_top="10"): + with vuetify.Template(v_slot_activator="{ on, attrs }"): + vuetify.VTextField( + label="Bunch Charge", + v_model=("bunch_charge_C",), + error_messages=("bunch_charge_C_validation",), + change=( + ctrl.on_input_change, + "[$event, 'float','bunch_charge_C','bunch_charge_C_validation']", + ), + type="number", + dense=True, + v_on="on", + v_bind="attrs", + ) + html.Span("{{ parameter_tooltips.bunch_charge_C }}") with vuetify.VCol(cols=4, classes="py-0"): vuetify.VTextField( label="Unit", diff --git a/src/python/impactx/dashboard/Input/latticeConfiguration/latticeMain.py b/src/python/impactx/dashboard/Input/latticeConfiguration/latticeMain.py index 5371042c2..15a4f6131 100644 --- a/src/python/impactx/dashboard/Input/latticeConfiguration/latticeMain.py +++ b/src/python/impactx/dashboard/Input/latticeConfiguration/latticeMain.py @@ -6,7 +6,7 @@ License: BSD-3-Clause-LBNL """ -from trame.widgets import vuetify +from trame.widgets import html, vuetify from impactx import elements @@ -36,6 +36,7 @@ state.selectedLatticeList = [] state.nsliceDefaultValue = None + # ----------------------------------------------------------------------------- # Main Functions # ----------------------------------------------------------------------------- @@ -63,6 +64,9 @@ def add_lattice_element(): "parameter_error_message": generalFunctions.validate_against( parameter[1], parameter[2] ), + "parameter_tooltip": generalFunctions.parameter_tooltips.get( + parameter[0], "N/A" + ), } for parameter in selectedLatticeParameters ], @@ -335,21 +339,32 @@ def card(): cols="auto", classes="pa-2", ): - vuetify.VTextField( - label=("parameter.parameter_name",), - v_model=( - "parameter.parameter_default_value", - ), - change=( - ctrl.updateLatticeElementParameters, - "[index, parameter.parameter_name, $event, parameter.parameter_type]", - ), - error_messages=( - "parameter.parameter_error_message", - ), - dense=True, - style="width: 100px;", - ) + with vuetify.VTooltip( + bottom=True, nudge_top="10" + ): + with vuetify.Template( + v_slot_activator="{ on, attrs }" + ): + vuetify.VTextField( + label=("parameter.parameter_name",), + v_model=( + "parameter.parameter_default_value", + ), + change=( + ctrl.updateLatticeElementParameters, + "[index, parameter.parameter_name, $event, parameter.parameter_type]", + ), + error_messages=( + "parameter.parameter_error_message", + ), + dense=True, + style="width: 100px;", + v_on="on", + v_bind="attrs", + ) + html.Span( + "{{ parameter.parameter_tooltip }}" + ) @staticmethod def dialog_lattice_elementList(): @@ -385,17 +400,24 @@ def dialog_lattice_elementList(): cols="auto", classes="pa-2", ): - vuetify.VTextField( - label=("parameter.parameter_name",), - v_model=("parameter.parameter_default_value",), - change=( - ctrl.updateLatticeElementParameters, - "[index, parameter.parameter_name, $event, parameter.parameter_type]", - ), - error_messages=("parameter.parameter_error_message",), - dense=True, - style="width: 100px;", - ) + with vuetify.VTooltip(bottom=True, nudge_top="10"): + with vuetify.Template(v_slot_activator="{ on, attrs }"): + vuetify.VTextField( + label=("parameter.parameter_name",), + v_model=("parameter.parameter_default_value",), + change=( + ctrl.updateLatticeElementParameters, + "[index, parameter.parameter_name, $event, parameter.parameter_type]", + ), + error_messages=( + "parameter.parameter_error_message", + ), + dense=True, + style="width: 100px;", + v_on="on", + v_bind="attrs", + ) + html.Span("{{ parameter.parameter_tooltip }}") @staticmethod def dialog_lattice_settings(): @@ -418,16 +440,23 @@ def dialog_lattice_settings(): "nslice", classes="ma-0 pl-0 font-weight-bold" ) with vuetify.VCol(no_gutters=True): - vuetify.VTextField( - v_model=("nsliceDefaultValue",), - change=( - ctrl.nsliceDefaultChange, - "['nslice', $event]", - ), - placeholder="Value", - dense=True, - outlined=True, - hide_details=True, - style="max-width: 75px", - classes="ma-0 pa-0", - ) + with vuetify.VTooltip(bottom=True, nudge_top="10"): + with vuetify.Template( + v_slot_activator="{ on, attrs }" + ): + vuetify.VTextField( + v_model=("nsliceDefaultValue",), + change=( + ctrl.nsliceDefaultChange, + "['nslice', $event]", + ), + placeholder="Value", + dense=True, + outlined=True, + hide_details=True, + style="max-width: 75px", + classes="ma-0 pa-0", + v_on="on", + v_bind="attrs", + ) + html.Span("testing") ## changing later diff --git a/src/python/impactx/dashboard/Input/space_charge_configuration/spaceChargeMain.py b/src/python/impactx/dashboard/Input/space_charge_configuration/spaceChargeMain.py index 1f0d1f4f3..07b813ca4 100644 --- a/src/python/impactx/dashboard/Input/space_charge_configuration/spaceChargeMain.py +++ b/src/python/impactx/dashboard/Input/space_charge_configuration/spaceChargeMain.py @@ -1,4 +1,4 @@ -from trame.widgets import vuetify +from trame.widgets import html, vuetify from ...trame_setup import setup_server from ..generalFunctions import generalFunctions @@ -202,24 +202,39 @@ def card(): hide_details=True, ) with vuetify.VCol(cols=4, classes="py-0"): - vuetify.VSelect( - label="Particle Shape", - v_model=("particle_shape",), - items=([1, 2, 3],), - dense=True, - ) + with vuetify.VTooltip(bottom=True, nudge_top="10"): + with vuetify.Template(v_slot_activator="{ on, attrs }"): + vuetify.VSelect( + label="Particle Shape", + v_model=("particle_shape",), + items=([1, 2, 3],), + dense=True, + v_on="on", + v_bind="attrs", + ) + html.Span("{{ parameter_tooltips.particle_shape }}") with vuetify.VCol(cols=3, classes="py-0"): - vuetify.VSelect( - label="Max Level", - v_model=("max_level",), - items=([0, 1, 2, 3, 4],), - dense=True, - ) + with vuetify.VTooltip(bottom=True, nudge_top="10"): + with vuetify.Template(v_slot_activator="{ on, attrs }"): + vuetify.VSelect( + label="Max Level", + v_model=("max_level",), + items=([0, 1, 2, 3, 4],), + dense=True, + v_on="on", + v_bind="attrs", + ) + html.Span("{{ parameter_tooltips.max_level }}") with vuetify.VCol(classes="pa-0"): - vuetify.VListItemSubtitle( - "nCell", - classes="font-weight-bold black--text", - ) + with vuetify.VTooltip(bottom=True, nudge_top="10"): + with vuetify.Template(v_slot_activator="{ on, attrs }"): + vuetify.VListItemSubtitle( + "nCell", + classes="font-weight-bold black--text", + v_on="on", + v_bind="attrs", + ) + html.Span("{{ parameter_tooltips.nCell }}") with vuetify.VRow(classes="my-0"): for direction in ["x", "y", "z"]: with vuetify.VCol(cols=4, classes="py-0"): @@ -232,10 +247,15 @@ def card(): style="margin-top: -5px", ) with vuetify.VCol(classes="pa-0"): - vuetify.VListItemSubtitle( - "Blocking Factor", - classes="font-weight-bold black--text mt-2", - ) + with vuetify.VTooltip(bottom=True, nudge_top="10"): + with vuetify.Template(v_slot_activator="{ on, attrs }"): + vuetify.VListItemSubtitle( + "Blocking Factor", + classes="font-weight-bold black--text mt-2", + v_on="on", + v_bind="attrs", + ) + html.Span("{{ parameter_tooltips.blocking_factor }}") with vuetify.VRow(classes="my-0"): for direction in ["x", "y", "z"]: with vuetify.VCol(cols=4, classes="py-0"): @@ -250,10 +270,15 @@ def card(): style="margin-top: -5px", ) with vuetify.VCol(classes="pa-0"): - vuetify.VListItemSubtitle( - "prob_relative", - classes="font-weight-bold black--text mt-2", - ) + with vuetify.VTooltip(bottom=True, nudge_top="10"): + with vuetify.Template(v_slot_activator="{ on, attrs }"): + vuetify.VListItemSubtitle( + "prob_relative", + classes="font-weight-bold black--text mt-2", + v_on="on", + v_bind="attrs", + ) + html.Span("{{ parameter_tooltips.prob_relative }}") with vuetify.VRow(classes="my-0"): with vuetify.VCol( v_for=("(field, index) in prob_relative_fields",), @@ -288,41 +313,77 @@ def dialog_space_charge_settings(): classes="my-2", v_if="poisson_solver == 'multigrid'" ): with vuetify.VCol(cols=6, classes="py-0"): - vuetify.VTextField( - label="MLMG Relative Tolerance", - v_model=("mlmg_relative_tolerance",), - error_messages=( - "error_message_mlmg_relative_tolerance", - ), - type="number", - dense=True, - ) + with vuetify.VTooltip(bottom=True, nudge_top="10"): + with vuetify.Template( + v_slot_activator="{ on, attrs }" + ): + vuetify.VTextField( + label="MLMG Relative Tolerance", + v_model=("mlmg_relative_tolerance",), + error_messages=( + "error_message_mlmg_relative_tolerance", + ), + type="number", + dense=True, + v_on="on", + v_bind="attrs", + ) + html.Span( + "{{ parameter_tooltips.mlmg_relative_tolerance }}" + ) with vuetify.VCol(cols=6, classes="py-0"): - vuetify.VTextField( - label="MLMG Absolute Tolerance", - v_model=("mlmg_absolute_tolerance",), - error_messages=( - "error_message_mlmg_absolute_tolerance", - ), - type="number", - dense=True, - ) + with vuetify.VTooltip(bottom=True, nudge_top="10"): + with vuetify.Template( + v_slot_activator="{ on, attrs }" + ): + vuetify.VTextField( + label="MLMG Absolute Tolerance", + v_model=("mlmg_absolute_tolerance",), + error_messages=( + "error_message_mlmg_absolute_tolerance", + ), + type="number", + dense=True, + v_on="on", + v_bind="attrs", + ) + html.Span( + "{{ parameter_tooltips.mlmg_absolute_tolerance }}" + ) with vuetify.VRow( classes="my-0", v_if="poisson_solver == 'multigrid'" ): with vuetify.VCol(cols=6, classes="py-0"): - vuetify.VTextField( - label="MLMG Max Iterations", - v_model=("mlmg_max_iters",), - error_messages=("error_message_mlmg_max_iters",), - type="number", - dense=True, - ) + with vuetify.VTooltip(bottom=True, nudge_top="10"): + with vuetify.Template( + v_slot_activator="{ on, attrs }" + ): + vuetify.VTextField( + label="MLMG Max Iterations", + v_model=("mlmg_max_iters",), + error_messages=( + "error_message_mlmg_max_iters", + ), + type="number", + dense=True, + v_on="on", + v_bind="attrs", + ) + html.Span("{{ parameter_tooltips.mlmg_max_iters }}") with vuetify.VCol(cols=6, classes="py-0"): - vuetify.VTextField( - label="MLMG Verbosity", - v_model=("mlmg_verbosity",), - error_messages=("error_message_mlmg_verbosity",), - type="number", - dense=True, - ) + with vuetify.VTooltip(bottom=True, nudge_top="10"): + with vuetify.Template( + v_slot_activator="{ on, attrs }" + ): + vuetify.VTextField( + label="MLMG Verbosity", + v_model=("mlmg_verbosity",), + error_messages=( + "error_message_mlmg_verbosity", + ), + type="number", + dense=True, + v_on="on", + v_bind="attrs", + ) + html.Span("{{ parameter_tooltips.mlmg_verbosity }}")