diff --git a/src/python/impactx/dashboard/Analyze/plot_PhaseSpaceProjections/phaseSpace.py b/src/python/impactx/dashboard/Analyze/plot_PhaseSpaceProjections/phaseSpace.py index ed027ca71..5421b5c14 100644 --- a/src/python/impactx/dashboard/Analyze/plot_PhaseSpaceProjections/phaseSpace.py +++ b/src/python/impactx/dashboard/Analyze/plot_PhaseSpaceProjections/phaseSpace.py @@ -53,7 +53,9 @@ def run_simulation(): # reference particle pc = sim.particle_container() ref = pc.ref_particle() - ref.set_charge_qe(-1.0).set_mass_MeV(0.510998950).set_kin_energy_MeV(kin_energy_MeV) + ref.set_charge_qe(state.charge_qe).set_mass_MeV(state.mass_MeV).set_kin_energy_MeV( + kin_energy_MeV + ) distribution = distribution_parameters() sim.add_particles(bunch_charge_C, distribution, npart) diff --git a/src/python/impactx/dashboard/Input/generalFunctions.py b/src/python/impactx/dashboard/Input/generalFunctions.py index dcb4717f0..42e7f66cd 100644 --- a/src/python/impactx/dashboard/Input/generalFunctions.py +++ b/src/python/impactx/dashboard/Input/generalFunctions.py @@ -64,38 +64,53 @@ def determine_input_type(value): return value, str @staticmethod - def validate_against(input_value, value_type): + def validate_against(input_value, value_type, additional_conditions=None): """ - Returns an error message if the input value type does not match the desired type. + Validates the input value against the desired type and additional conditions. :param input_value: The value to validate. :param value_type: The desired type ('int', 'float', 'str'). + :param conditions: A list of additional conditions to validate. :return: A list of error messages. An empty list if there are no errors. """ + errors = [] + value = None + # value_type checking if value_type == "int": if input_value is None: - return ["Must be an integer"] - try: - int(input_value) - return [] - except ValueError: - return ["Must be an integer"] - + errors.append("Must be an integer") + else: + try: + value = int(input_value) + except ValueError: + errors.append("Must be an integer") elif value_type == "float": if input_value is None: - return ["Must be a float"] - try: - float(input_value) - return [] - except ValueError: - return ["Must be a float"] - + errors.append("Must be a float") + else: + try: + value = float(input_value) + except ValueError: + errors.append("Must be a float") elif value_type == "str": if input_value is None: - return ["Must be a string"] - return [] + errors.append("Must be a string") + else: + value = str(input_value) else: - return ["Unknown type"] + errors.append("Unknown type") + + # addition_conditions checking + if errors == [] and additional_conditions: + for condition in additional_conditions: + if condition == "non_zero" and value == 0: + errors.append("Must be non-zero") + if condition == "positive" and value <= 0: + errors.append("Must be positive") + if condition == "negative" and value >= 0: + errors.append("Must be negative") + + return errors @staticmethod def update_simulation_validation_status(): @@ -128,6 +143,11 @@ def update_simulation_validation_status(): error_details.append(f"Kinetic Energy: {state.kin_energy_validation}") if state.bunch_charge_C_validation: error_details.append(f"Bunch Charge: {state.bunch_charge_C_validation}") + if state.charge_qe_validation: + error_details.append(f"Ref. Particle Charge: {state.charge_qe_validation}") + if state.mass_MeV_validation: + error_details.append(f"Ref. Particle Mass: {state.mass_MeV}") + if state.selectedLatticeList == []: error_details.append("LatticeListIsEmpty") diff --git a/src/python/impactx/dashboard/Input/inputParameters/inputMain.py b/src/python/impactx/dashboard/Input/inputParameters/inputMain.py index 52e7e63ba..1f9699564 100644 --- a/src/python/impactx/dashboard/Input/inputParameters/inputMain.py +++ b/src/python/impactx/dashboard/Input/inputParameters/inputMain.py @@ -21,9 +21,11 @@ @ctrl.add("on_input_change") def validate_and_convert_to_correct_type( - value, desired_type, state_name, validation_name + value, desired_type, state_name, validation_name, conditions=None ): - validation_result = generalFunctions.validate_against(value, desired_type) + validation_result = generalFunctions.validate_against( + value, desired_type, conditions + ) setattr(state, validation_name, validation_result) generalFunctions.update_simulation_validation_status() @@ -70,17 +72,21 @@ def __init__(self): state.bunch_charge_C = 1.0e-9 state.kin_energy_unit = "MeV" state.old_kin_energy_unit = "MeV" + state.charge_qe = -1 + state.mass_MeV = 0.510998950 state.npart_validation = [] state.kin_energy_validation = [] state.bunch_charge_C_validation = [] + state.mass_MeV_validation = [] + state.charge_qe_validation = [] def card(self): """ Creates UI content for beam properties. """ - with vuetify.VCard(style="width: 340px; height: 300px"): + with vuetify.VCard(style="width: 340px; height: 350px"): with vuetify.VCardTitle("Input Parameters"): vuetify.VSpacer() vuetify.VIcon( @@ -96,6 +102,33 @@ def card(self): items=([1, 2, 3],), dense=True, ) + 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.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.VRow(classes="my-0"): with vuetify.VCol(cols=12, classes="py-0"): vuetify.VTextField( diff --git a/src/python/impactx/dashboard/Toolbar/exportTemplate.py b/src/python/impactx/dashboard/Toolbar/exportTemplate.py index 005663b8c..e58e6e02a 100644 --- a/src/python/impactx/dashboard/Toolbar/exportTemplate.py +++ b/src/python/impactx/dashboard/Toolbar/exportTemplate.py @@ -74,7 +74,7 @@ def input_file(): # Reference particle ref = sim.particle_container().ref_particle() -ref.set_charge_qe(-1.0).set_mass_MeV(0.510998950).set_kin_energy_MeV(kin_energy_MeV) +ref.set_charge_qe({state.charge_qe}).set_mass_MeV({state.mass_MeV}).set_kin_energy_MeV(kin_energy_MeV) {build_distribution_list()} sim.add_particles(bunch_charge_C, distr, npart)