Skip to content
Snippets Groups Projects
Commit 7e0d0dc1 authored by Alexis GAMELIN's avatar Alexis GAMELIN
Browse files

Merge branch 'bugfix_#13transverse_map_sector_generator' into 'develop'

Issue#13

See merge request !27
parents a32e6f1f 2c3026f7
Branches
Tags
2 merge requests!280.8.0,!27Issue#13
...@@ -444,6 +444,10 @@ def transverse_map_sector_generator(ring, positions): ...@@ -444,6 +444,10 @@ def transverse_map_sector_generator(ring, positions):
""" """
N_sec = len(positions) N_sec = len(positions)
sectors = [] sectors = []
if hasattr(ring, "adts") and ring.adts is not None:
adts = np.array([val / N_sec for val in ring.adts])
else:
adts = None
if ring.optics.use_local_values: if ring.optics.use_local_values:
for i in range(N_sec): for i in range(N_sec):
sectors.append( sectors.append(
...@@ -455,49 +459,47 @@ def transverse_map_sector_generator(ring, positions): ...@@ -455,49 +459,47 @@ def transverse_map_sector_generator(ring, positions):
ring.optics.local_beta, ring.optics.local_beta,
ring.optics.local_dispersion, ring.optics.local_dispersion,
2 * np.pi * ring.tune / N_sec, 2 * np.pi * ring.tune / N_sec,
ring.chro / N_sec, np.asarray(ring.chro) / N_sec,
adts=ring.adts / adts=adts))
N_sec if ring.adts else None))
else: else:
import at import at
def _compute_chro(ring, pos, dp=1e-2, order=4): def _compute_chro(ring, N_sec, dp=1e-2, order=4):
lat = deepcopy(ring.optics.lattice) lat = deepcopy(ring.optics.lattice)
lat.append(at.Marker("END")) lat.append(at.Marker("END"))
fit, dpa, tune = at.physics.nonlinear.chromaticity(lat, fit, _, _ = at.physics.nonlinear.chromaticity(lat,
method='linopt', method='linopt',
dpm=dp, dpm=dp,
n_points=100, n_points=100,
order=order) order=order)
Chrox, Chroy = fit[0, 1:], fit[1, 1:] Chrox, Chroy = fit[0, 1:], fit[1, 1:]
chrox = np.interp(pos, s, Chrox) chrox = np.array([np.linspace(0, val, N_sec) for val in Chrox])
chroy = np.interp(pos, s, Chroy) chroy = np.array([np.linspace(0, val, N_sec) for val in Chroy])
return np.array([chrox, chroy]) return np.array([chrox, chroy])
_chro = _compute_chro(ring, N_sec)
for i in range(N_sec): for i in range(N_sec):
alpha0 = ring.optics.alpha(positions[i]) alpha0 = ring.optics.alpha(positions[i])
beta0 = ring.optics.beta(positions[i]) beta0 = ring.optics.beta(positions[i])
dispersion0 = ring.optics.dispersion(positions[i]) dispersion0 = ring.optics.dispersion(positions[i])
mu0 = ring.optics.mu(positions[i]) mu0 = ring.optics.mu(positions[i])
chro0 = _compute_chro(ring, positions[i]) chro0 = _chro[:, i]
if i != (N_sec - 1): if i != (N_sec - 1):
alpha1 = ring.optics.alpha(positions[i + 1]) alpha1 = ring.optics.alpha(positions[i + 1])
beta1 = ring.optics.beta(positions[i + 1]) beta1 = ring.optics.beta(positions[i + 1])
dispersion1 = ring.optics.dispersion(positions[i + 1]) dispersion1 = ring.optics.dispersion(positions[i + 1])
mu1 = ring.optics.mu(positions[i + 1]) mu1 = ring.optics.mu(positions[i + 1])
chro1 = _compute_chro(ring, positions[i + 1]) chro1 = _chro[:, i + 1]
else: else:
alpha1 = ring.optics.alpha(positions[0]) alpha1 = ring.optics.alpha(positions[0])
beta1 = ring.optics.beta(positions[0]) beta1 = ring.optics.beta(positions[0])
dispersion1 = ring.optics.dispersion(positions[0]) dispersion1 = ring.optics.dispersion(positions[0])
mu1 = ring.optics.mu(ring.L) mu1 = ring.optics.mu(ring.L)
chro1 = _compute_chro(ring, ring.L) chro1 = _chro[:, -1]
phase_diff = mu1 - mu0 phase_diff = mu1 - mu0
chro_diff = chro1 - chro0 chro_diff = chro1 - chro0
sectors.append( sectors.append(
TransverseMapSector( TransverseMapSector(ring,
ring,
alpha0, alpha0,
beta0, beta0,
dispersion0, dispersion0,
...@@ -506,5 +508,5 @@ def transverse_map_sector_generator(ring, positions): ...@@ -506,5 +508,5 @@ def transverse_map_sector_generator(ring, positions):
dispersion1, dispersion1,
phase_diff, phase_diff,
chro_diff, chro_diff,
)) adts=adts))
return sectors return sectors
...@@ -374,3 +374,54 @@ class TestTransverseMap: ...@@ -374,3 +374,54 @@ class TestTransverseMap:
assert not np.array_equal(initial_values[attr], current[attr]) assert not np.array_equal(initial_values[attr], current[attr])
assert not np.array_equal(initial_values[attr], old[attr]) assert not np.array_equal(initial_values[attr], old[attr])
np.testing.assert_allclose(current[attr], old[attr]) np.testing.assert_allclose(current[attr], old[attr])
class TestTransverseMapSectorGenerator:
# Generate sectors with local optics values when use_local_values is True
def test_local_optics_values(self, demo_ring):
positions = np.array([0, 25, 50, 75])
sectors = transverse_map_sector_generator(demo_ring, positions)
assert len(sectors) == len(positions)
for sector in sectors:
assert np.array_equal(sector.alpha0, demo_ring.optics.local_alpha)
assert np.array_equal(sector.beta0, demo_ring.optics.local_beta)
assert np.array_equal(sector.dispersion0, demo_ring.optics.local_dispersion)
# Generate sectors with AT lattice optics when use_local_values is False
def test_at_lattice_optics(self, ring_with_at_lattice):
positions = np.array([0, 25, 50, 75])
sectors = transverse_map_sector_generator(ring_with_at_lattice, positions)
assert len(sectors) == len(positions)
for i, sector in enumerate(sectors):
assert np.array_equal(sector.alpha0, ring_with_at_lattice.optics.alpha(positions[i]))
assert np.array_equal(sector.beta0, ring_with_at_lattice.optics.beta(positions[i]))
# Calculate phase differences between consecutive positions
def test_phase_differences(self, ring_with_at_lattice):
positions = np.array([0, 25, 50])
ring_with_at_lattice.optics.use_local_values = False
sectors = transverse_map_sector_generator(ring_with_at_lattice, positions)
for i, sector in enumerate(sectors):
if i < len(positions)-1:
expected_phase = ring_with_at_lattice.optics.mu(positions[i+1]) - ring_with_at_lattice.optics.mu(positions[i])
assert np.allclose(sector.tune_diff * (2 * np.pi), expected_phase)
# Compute chromaticity differences between sectors
def test_chromaticity_differences(self, demo_ring):
positions = np.array([0, 50])
sectors = transverse_map_sector_generator(demo_ring, positions)
expected_chro = np.asarray(demo_ring.chro) / len(positions)
assert np.allclose(sectors[0].chro_diff, expected_chro)
# Handle ADTS parameters correctly when provided
def test_adts_handling(self, demo_ring):
demo_ring.adts = np.array([1.0, 1.0, 1.0, 1.0])
positions = np.array([0, 50])
sectors = transverse_map_sector_generator(demo_ring, positions)
expected_adts = demo_ring.adts / len(positions)
assert np.allclose(sectors[0].adts_poly[0].coef, expected_adts[0])
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment