Skip to content

Actions - #15

Merged
roussel-ryan merged 9 commits into
mainfrom
actions
Jun 19, 2026
Merged

Actions#15
roussel-ryan merged 9 commits into
mainfrom
actions

Conversation

@roussel-ryan

Copy link
Copy Markdown
Contributor

This pull request introduces a major refactor of the LUMEBmadModel in lume_bmad/model.py to adopt the new ActionModel and ActionVariable abstractions, replacing the legacy control/output variable and transformer system. It also adds a comprehensive set of action variable classes in lume_bmad/actions.py to encapsulate Bmad model interactions. The refactor streamlines variable registration, improves extensibility, and clarifies the model's dynamic output handling, especially for beam tracking modes.

Key changes include:

Adoption of ActionModel and ActionVariables:

  • Refactored LUMEBmadModel to inherit from ActionModel and use ActionVariable instances for all variable interactions, removing the old control/output variable dictionaries and transformer logic. Variable registration and state management now use the new action-based interface. [1] [2] [3]

Dynamic Variable Registration and Output Handling:

  • Implemented _refresh_dynamic_action_variables to synchronize model outputs (such as comb statistics and dumped beam distributions) with the current tracking mode (track_type). This ensures that only relevant variables are registered and available depending on whether the model is in single or beam tracking mode.

Introduction of Action Variable Classes:

  • Added new classes in lume_bmad/actions.py for scalar, ND, enum, and particle group variables, as well as specialized screen and beam variables. These classes encapsulate the logic for getting and setting values in the Tao simulator, providing a modular and extensible interface for model actions.

Simplification and Cleanup:

  • Removed the legacy transformer, control/output variable dictionaries, and related property methods. All variable access now goes through the action variable registration and retrieval system. [1] [2]

Improved State Update and Setting Logic:

  • Rewrote _get, _set, and update_state methods to delegate variable access to the registered action variables, ensuring consistent handling and reducing duplicated logic. Also improved handling of simulator modes and eager/lazy evaluation for performance. [1] [2]

These changes modernize the model interface, improve maintainability, and lay the groundwork for further extensibility.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR refactors LUMEBmadModel to use LUME’s action-based API (ActionModel + ActionVariable) and introduces a new lume_bmad.actions module that encapsulates Tao/Bmad interactions as action variables, replacing the legacy transformer + control/output variable dictionaries.

Changes:

  • Migrated LUMEBmadModel to ActionModel, registering Tao lattice/comb outputs and track-mode-dependent variables as action variables.
  • Added new action variable implementations (element scalars, lattice stats, comb stats, beam-at-element, and screen-related variables).
  • Updated tests to use the new action-variable interface and new track type enum values ("single" / "beam"), and removed the legacy transformer.

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 6 comments.

Show a summary per file
File Description
lume_bmad/actions.py Adds new action variable classes for Tao/Bmad interaction, including screen-related abstractions.
lume_bmad/model.py Refactors the model to ActionModel, registers action variables, and adds dynamic variable refresh based on track_type.
lume_bmad/utils.py Reworks Tao output-variable construction to return StatVariable/CombStatVariable instances.
tests/test_basic.py Updates tests to construct the model with action variables and validate dynamic outputs under beam/single modes.
lume_bmad/transformer.py Removes the legacy transformer abstraction.
Comments suppressed due to low confidence (2)

lume_bmad/actions.py:221

  • tests/test_basic.py imports and uses ScreenVariable, but lume_bmad/actions.py currently does not define it, so the import will fail and the screen test cannot run. Add ScreenVariable (e.g., as a backward-compatible alias/subclass of ScreenImageVariable).
    def _get(self, simulator: Tao) -> Any:
        _ = simulator
        return self.screen_spec.shape[self.index]

lume_bmad/model.py:255

  • reset() calls self.set(self._initial_state), but _initial_state is captured from update_state() and therefore includes many read-only outputs (e.g., mat6, vec0, name). If ActionModel.set() attempts to write all provided keys, this will fail for read-only action variables. Consider resetting only writable variables (or only the originally supplied control/action variables).
    def reset(self):
        """Reset the model to its initial state."""
        logger.info("Resetting model to initial state")
        self.set(self._initial_state)


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread lume_bmad/actions.py
Comment thread lume_bmad/model.py Outdated
Comment on lines +158 to +165
# turn tao eager mode off to speed up setting multiple variables
self.simulator.cmd("set global lattice_calc_on = F")

# remove particle group variables
for var in [f"{ele}_beam" for ele in self._dump_locations]:
if var in self._variables.keys():
self._variables.pop(var)

if len(output) > 0:
logger.warning("Warning while setting track_type: %s", "".join(output))
warnings.warn(f"Warning while setting track_type: {''.join(output)}")
values.pop("track_type")

# handle setting the input beam separately
if "input_beam" in values.keys():
input_beam = values.pop("input_beam")
fname = getcwd() + "/input_beam.h5"
logger.debug("Writing input beam to %s", fname)
input_beam.write(fname)
self.tao.cmd(f"set beam_init position_file = {fname}")
# set control variables using their respective set methods
super()._set(values)

# reset comb length for tracking outputs
self.tao.cmd(f"set beam comb_ds_save = {self.comb_ds_save}")
tao_model_output_variables = get_tao_output_variables(self.tao)
self._variables.update(tao_model_output_variables)
# after setting all variables, turn eager mode back on
self.simulator.cmd("set global lattice_calc_on = T")
Comment thread lume_bmad/model.py Outdated
Comment on lines +182 to +186
try:
self._state[name] = self.supported_variables[name]._get(self.simulator)
except Exception as e:
logger.error("Error getting variable %s: %s", name, str(e))
raise e
Comment thread tests/test_basic.py
Comment thread tests/test_basic.py Outdated
Comment on lines +69 to +71
control_variables = [
EleScalarVariable(name="qf:B1_GRADIENT", units="1/m^2"),
EleScalarVariable(name="qd:B1_GRADIENT", units="1/m^2"),
Comment thread tests/test_basic.py Outdated
roussel-ryan and others added 3 commits June 19, 2026 15:06
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
@roussel-ryan
roussel-ryan merged commit 737aea3 into main Jun 19, 2026
1 check passed
@roussel-ryan
roussel-ryan deleted the actions branch June 19, 2026 20:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants