From ef2ca21f3e8d3e73e3bedd027bbebf15d788c2c0 Mon Sep 17 00:00:00 2001 From: T-Nicholls Date: Wed, 23 Jul 2025 17:48:45 +0100 Subject: [PATCH 1/8] Add Energy to Wiggler build attributes --- pyat/at/lattice/elements/magnet_elements.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyat/at/lattice/elements/magnet_elements.py b/pyat/at/lattice/elements/magnet_elements.py index ac767d2e2..0f63892f3 100644 --- a/pyat/at/lattice/elements/magnet_elements.py +++ b/pyat/at/lattice/elements/magnet_elements.py @@ -471,7 +471,7 @@ class Wiggler(Radiative, LongElement): See atwiggler.m """ - _BUILD_ATTRIBUTES = LongElement._BUILD_ATTRIBUTES + ["Lw", "Bmax"] + _BUILD_ATTRIBUTES = LongElement._BUILD_ATTRIBUTES + ["Lw", "Bmax", "Energy"] _conversions = dict( Element._conversions, Lw=_float, From a9f5819b92ed414ad8909f5b26c42d1d6846f61b Mon Sep 17 00:00:00 2001 From: T-Nicholls Date: Wed, 23 Jul 2025 18:16:17 +0100 Subject: [PATCH 2/8] Ensure wiggler Energy attribute is always present and consitent with the lattice --- pyat/at/lattice/lattice_object.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/pyat/at/lattice/lattice_object.py b/pyat/at/lattice/lattice_object.py index 77ca383b2..2ee321ab5 100644 --- a/pyat/at/lattice/lattice_object.py +++ b/pyat/at/lattice/lattice_object.py @@ -305,7 +305,7 @@ def _addition_filter(self, elems: Iterable[Element], copy_elements=False): params = {} for elem in type_filter(params, elems): - if isinstance(elem, elt.RFCavity): + if isinstance(elem, elt.RFCavity) or isinstance(elem, elt.Wiggler): cavities.append(elem) elem.Energy = self._energy elif elem.PassMethod.endswith("RadPass"): @@ -1534,7 +1534,8 @@ def params_filter(params, elem_filter: Filter, *args) -> Generator[Element, None cavities.append(elem) elif hasattr(elem, "Energy"): el_energies.append(elem.Energy) - del elem.Energy + if not isinstance(elem, elt.Wiggler): + del elem.Energy if isinstance(elem, elt.Dipole): thetas.append(elem.BendingAngle) cell_length += getattr(elem, "Length", 0.0) From d12902cbcb3aaa741a94425bbe69a83609c0a163 Mon Sep 17 00:00:00 2001 From: T-Nicholls Date: Fri, 1 Aug 2025 18:35:55 +0100 Subject: [PATCH 3/8] Revert "Ensure wiggler Energy attribute is always present and consitent with the lattice" This reverts commit a9f5819b92ed414ad8909f5b26c42d1d6846f61b. --- pyat/at/lattice/lattice_object.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/pyat/at/lattice/lattice_object.py b/pyat/at/lattice/lattice_object.py index 2ee321ab5..77ca383b2 100644 --- a/pyat/at/lattice/lattice_object.py +++ b/pyat/at/lattice/lattice_object.py @@ -305,7 +305,7 @@ def _addition_filter(self, elems: Iterable[Element], copy_elements=False): params = {} for elem in type_filter(params, elems): - if isinstance(elem, elt.RFCavity) or isinstance(elem, elt.Wiggler): + if isinstance(elem, elt.RFCavity): cavities.append(elem) elem.Energy = self._energy elif elem.PassMethod.endswith("RadPass"): @@ -1534,8 +1534,7 @@ def params_filter(params, elem_filter: Filter, *args) -> Generator[Element, None cavities.append(elem) elif hasattr(elem, "Energy"): el_energies.append(elem.Energy) - if not isinstance(elem, elt.Wiggler): - del elem.Energy + del elem.Energy if isinstance(elem, elt.Dipole): thetas.append(elem.BendingAngle) cell_length += getattr(elem, "Length", 0.0) From 79fd8aee319d4f715dbb9cea88eda7684e0f1919 Mon Sep 17 00:00:00 2001 From: T-Nicholls Date: Fri, 1 Aug 2025 18:37:12 +0100 Subject: [PATCH 4/8] Revert "Add Energy to Wiggler build attributes" This reverts commit ef2ca21f3e8d3e73e3bedd027bbebf15d788c2c0. --- pyat/at/lattice/elements/magnet_elements.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyat/at/lattice/elements/magnet_elements.py b/pyat/at/lattice/elements/magnet_elements.py index 0f63892f3..ac767d2e2 100644 --- a/pyat/at/lattice/elements/magnet_elements.py +++ b/pyat/at/lattice/elements/magnet_elements.py @@ -471,7 +471,7 @@ class Wiggler(Radiative, LongElement): See atwiggler.m """ - _BUILD_ATTRIBUTES = LongElement._BUILD_ATTRIBUTES + ["Lw", "Bmax", "Energy"] + _BUILD_ATTRIBUTES = LongElement._BUILD_ATTRIBUTES + ["Lw", "Bmax"] _conversions = dict( Element._conversions, Lw=_float, From c5fd65f85da3534b07665c5750a9ebaef323cab6 Mon Sep 17 00:00:00 2001 From: T-Nicholls Date: Fri, 1 Aug 2025 19:06:41 +0100 Subject: [PATCH 5/8] No longer pass through positional argument energy --- pyat/at/lattice/elements/magnet_elements.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/pyat/at/lattice/elements/magnet_elements.py b/pyat/at/lattice/elements/magnet_elements.py index ac767d2e2..2ceeccd56 100644 --- a/pyat/at/lattice/elements/magnet_elements.py +++ b/pyat/at/lattice/elements/magnet_elements.py @@ -522,6 +522,13 @@ def __init__( "Wiggler: length / wiggle_period is not an " f"integer. ({length}/{wiggle_period}={n_wiggles})" ) + if energy: + warnings.warn( + AtWarning( + f"Wiggler: positional argument energy={energy} has been ignored as " + "lattice.Energy is always used instead." + ) + ) super().__init__( family_name, length, @@ -531,7 +538,6 @@ def __init__( Nmeth=Nmeth, By=By, Bx=Bx, - Energy=energy, **kwargs, ) From 2cbcf80d9e5f3fae8493bed3f7e700fbaab45fb4 Mon Sep 17 00:00:00 2001 From: T-Nicholls Date: Fri, 1 Aug 2025 19:07:54 +0100 Subject: [PATCH 6/8] Fix test warnings --- pyat/test/test_basic_elements.py | 2 +- pyat/test/test_integrators.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pyat/test/test_basic_elements.py b/pyat/test/test_basic_elements.py index 1f9ec13d1..5cab9dbbb 100644 --- a/pyat/test/test_basic_elements.py +++ b/pyat/test/test_basic_elements.py @@ -552,7 +552,7 @@ def test_wiggler(rin, func): periods = 23 bmax = 1 by = numpy.array([1, 1, 0, 1, 1, 0], dtype=numpy.float64) - c = elements.Wiggler('wiggler', period * periods, period, bmax, 3e9, By=by) + c = elements.Wiggler('wiggler', period * periods, period, bmax, By=by) assert abs(c.Length - 1.15) < 1e-10 # Expected value from Matlab AT. expected = numpy.array(rin, copy=True) diff --git a/pyat/test/test_integrators.py b/pyat/test/test_integrators.py index 5a94bc178..2a896cd99 100644 --- a/pyat/test/test_integrators.py +++ b/pyat/test/test_integrators.py @@ -43,7 +43,7 @@ def test_exact_hamiltonian_pass_with_dls_dipole(rin, func): ('GWigSymplecticPass', 'GWigSymplecticRadPass')) def test_gwig_symplectic_pass(rin, passmethod, func): # Parameters copied from one of the Diamond wigglers. - wiggler = elements.Wiggler('w', 1.15, 0.05, 0.8, 3e9) + wiggler = elements.Wiggler('w', 1.15, 0.05, 0.8) wiggler.PassMethod = passmethod func(wiggler, rin) From c28c514c09a87a1da3eed7ab06531c708880e8af Mon Sep 17 00:00:00 2001 From: T-Nicholls Date: Fri, 1 Aug 2025 19:09:25 +0100 Subject: [PATCH 7/8] No longer create Energy attribute for wigglers in lattice object energy setter --- pyat/at/lattice/lattice_object.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/pyat/at/lattice/lattice_object.py b/pyat/at/lattice/lattice_object.py index 77ca383b2..82157c426 100644 --- a/pyat/at/lattice/lattice_object.py +++ b/pyat/at/lattice/lattice_object.py @@ -677,9 +677,7 @@ def energy(self) -> float: def energy(self, energy: float): # Set the Energy attribute of radiating elements for elem in self: - if isinstance( - elem, (elt.RFCavity, elt.Wiggler) - ) or elem.PassMethod.endswith("RadPass"): + if isinstance(elem, elt.RFCavity) or elem.PassMethod.endswith("RadPass"): elem.Energy = energy # Set the energy attribute of the Lattice # Use a numpy scalar to allow division by zero From 4bdf6ef818f85ea367ed53a641668549e3810846 Mon Sep 17 00:00:00 2001 From: T-Nicholls Date: Tue, 12 Aug 2025 16:56:57 +0100 Subject: [PATCH 8/8] Update Wiggler docstring to indicate energy is ignored --- pyat/at/lattice/elements/magnet_elements.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyat/at/lattice/elements/magnet_elements.py b/pyat/at/lattice/elements/magnet_elements.py index 2ceeccd56..0c2e78e63 100644 --- a/pyat/at/lattice/elements/magnet_elements.py +++ b/pyat/at/lattice/elements/magnet_elements.py @@ -505,7 +505,7 @@ def __init__( length: total length of the wiggler wiggle_period: length must be a multiple of this b_max: peak wiggler field [Tesla] - energy: beam energy [eV] + energy: kept for backwards compatibility but always ignored Nstep: number of integration steps. Nmeth: symplectic integration order: 2 or 4 Bx: harmonics for horizontal wiggler: (6, nHharm)