Source code for at.tracking.utils
"""
Utility functions for tracking simulations
"""
import numpy
from at.lattice import Lattice, DConstant
from typing import Optional
__all__ = ['get_bunches', 'get_bunches_std_mean', 'unfold_beam']
[docs]def get_bunches(r_in: numpy.ndarray, nbunch: int,
selected_bunches: Optional[numpy.ndarray] = None):
"""Function to get the bunches particles 6D coordinates
Parameters:
r_in: 6 x n_particles Fortran-ordered numpy array.
nbunch: integer, total number of bunches
selected_bunches: integer or array of integers, index
of the selected bunches
Returns:
List of ndarray containing the 6 x n particles coordinates
of the selected bunches
"""
if selected_bunches is None:
selected_bunches = numpy.arange(nbunch)
else:
selected_bunches = numpy.atleast_1d(selected_bunches)
bunches = [r_in.T[ib::nbunch].T for ib in selected_bunches]
return bunches
[docs]def get_bunches_std_mean(r_in: numpy.ndarray, nbunch: int,
selected_bunches: Optional[numpy.ndarray] = None):
"""Function to get the bunches standard deviation and center
of mass
Parameters:
r_in: 6 x n_particles Fortran-ordered numpy array.
nbunch: integer, total number of bunches
selected_bunches: integer or array of integers, index
of the selected bunches
Returns:
Lists of ndarray containing the 6D standard deviation
and center of mass (std, mean)
"""
bunches = get_bunches(r_in, nbunch, selected_bunches)
std = [numpy.nanstd(b, axis=1) for b in bunches]
mean = [numpy.nanmean(b, axis=1) for b in bunches]
return std, mean
[docs]def unfold_beam(ring: Lattice, beam: numpy.ndarray,
**kwargs) -> numpy.ndarray:
"""Function to unfold the beam based on the ring fill pattern.
The input particle distribution has to be in on bucket 0.
Particle are distributed in bunches using ``i%ring.nbunch``
where i is the particle index.
For each bunches the absolute ``ct`` is computed using the 6D
closed orbit search, this closed orbit is added to the input
particles.
Parameters:
ring: Lattice description
beam: array with shape(6, nparticles)
Keyword Arguments:
convergence (float): Convergence criterion for 6D orbit
Default: :py:data:`DConstant.OrbConvergence <.DConstant>`
max_iterations (int): Maximum number of iterations for
6D orbit.
Default: :py:data:`DConstant.OrbMaxIter <.DConstant>`
Return:
beam (numpy.ndarray): unfolded beam
"""
conv = kwargs.pop('convergence', DConstant.OrbConvergence)
maxiter = kwargs.pop('max_iterations', DConstant.OrbMaxIter)
o60, _ = ring.find_orbit(max_iterations=maxiter, convergence=conv)
unfolded_beam = numpy.zeros(beam.shape)
for i, spos in enumerate(ring.bunch_spos[::-1]):
guess = o60.copy()
guess[5] -= spos
o6, _ = ring.find_orbit(guess=guess, max_iterations=maxiter,
convergence=conv)
unfolded_beam[:, i::ring.nbunch] = (beam[:, i::ring.nbunch].T + o6).T
return unfolded_beam