Source code for at.tracking.deprecated

from .atpass import atpass as _atpass, elempass as _elempass
from .utils import fortran_align
from .track import internal_lpass, internal_epass, internal_plpass
from .utils import initialize_lpass
from ..lattice import Lattice, Element, Particle, Refpts, End
from typing import Iterable, Optional
from warnings import warn


__all__ = ['element_pass', 'lattice_pass', 'patpass', 'atpass', 'elempass']


# noinspection PyIncorrectDocstring
def atpass(*args, **kwargs):
    """
    atpass(line, r_in, nturns, refpts=[], reuse=False, omp_num_threads=0)

    Track input particles *r_in* along line for *nturns* turns.

    Parameters:
        line (Sequence[Element]): list of elements
        r_in:                   6 x n_particles Fortran-ordered numpy array.
          On return, rin contains the final coordinates of the particles
        nturns (int):           number of turns to be tracked

    Keyword arguments:
        refpts (Uint32_refs):   numpy array of indices of elements where
          output is desired:

          * 0 means entrance of the first element
          * len(line) means end of the last element

        energy:                 nominal energy [eV]
        rest_energy:            rest_energy of the particle [eV]
        charge:                 particle charge [elementary charge]
        reuse (bool):           if True, use previously cached description
          of the lattice.
        omp_num_threads (int):  number of OpenMP threads
          (default 0: automatic)
        losses (bool):          if True, process losses

    Returns:
        r_out:  6 x n_particles x n_refpts x n_turns Fortran-ordered
          numpy array of particle coordinates

    :meta private:
    """
    warn(UserWarning("The public interface for tracking is 'lattice_pass'"))
    return _atpass(*args, **kwargs)


# noinspection PyIncorrectDocstring
def elempass(*args, **kwargs):
    """elempass(element, r_in)

    Track input particles *r_in* through a single element.

    Parameters:
        element (Element):  AT element
        rin:                6 x n_particles Fortran-ordered numpy array.
          On return, rin contains the final coordinates of the particles

    Keyword arguments:
        energy:             nominal energy [eV]
        rest_energy:        rest_energy of the particle [eV]
        charge:             particle charge [elementary charge]

    :meta private:
    """
    warn(UserWarning("The public interface for tracking is 'element_pass'"))
    return _elempass(*args, **kwargs)


[docs] def lattice_pass(lattice: Iterable[Element], r_in, nturns: int = 1, refpts: Refpts = End, **kwargs): """ :py:func:`lattice_pass` tracks particles through each element of a lattice calling the element-specific tracking function specified in the Element's *PassMethod* field. Parameters: lattice: list of elements r_in: (6, N) array: input coordinates of N particles. *r_in* is modified in-place and reports the coordinates at the end of the element. For the best efficiency, *r_in* should be given as F_CONTIGUOUS numpy array. nturns: number of turns to be tracked refpts: Selects the location of coordinates output. See ":ref:`Selecting elements in a lattice <refpts>`" Keyword arguments: keep_lattice (bool): Use elements persisted from a previous call. If :py:obj:`True`, assume that the lattice has not changed since the previous call. keep_counter (bool): Keep the turn number from the previous call. turn (int): Starting turn number. Ignored if *keep_counter* is :py:obj:`True`. The turn number is necessary to compute the absolute path length used in RFCavityPass. losses (bool): Boolean to activate loss maps output omp_num_threads (int): Number of OpenMP threads (default: automatic) The following keyword arguments overload the Lattice values Keyword arguments: particle (Optional[Particle]): circulating particle. Default: :code:`lattice.particle` if existing, otherwise :code:`Particle('relativistic')` energy (Optiona[float]): lattice energy. Default 0. unfold_beam (bool): Internal beam folding activate, this assumes the input particles are in bucket 0, works only if all bucket see the same RF Voltage. Default: :py:obj:`True` If *energy* is not available, relativistic tracking if forced, *rest_energy* is ignored. Returns: r_out: (6, N, R, T) array containing output coordinates of N particles at R reference points for T turns. loss_map: If *losses* is :py:obj:`True`: dictionary with the following key: ============== =================================================== **islost** (npart,) bool array indicating lost particles **turn** (npart,) int array indicating the turn at which the particle is lost **element** ((npart,) int array indicating the element at which the particle is lost **coord** (6, npart) float array giving the coordinates at which the particle is lost (zero for surviving particles) ============== =================================================== .. note:: * :pycode:`lattice_pass(lattice, r_in, refpts=len(line))` is the same as :pycode:`lattice_pass(lattice, r_in)` since the reference point len(line) is the exit of the last element. * :pycode:`lattice_pass(lattice, r_in, refpts=0)` is a copy of *r_in* since the reference point 0 is the entrance of the first element. * To resume an interrupted tracking (for instance to get intermediate results), one must use one of the *turn* or *keep_counter* keywords to ensure the continuity of the turn number. * For multiparticle tracking with large number of turn the size of *r_out* may increase excessively. To avoid memory issues :pycode:`lattice_pass(lattice, r_in, refpts=None)` can be used. An empty list is returned and the tracking results of the last turn are stored in *r_in*. * To model buckets with different RF voltage :pycode:`unfold_beam=False` has to be used. The beam can be unfolded using the function :py:func:`.unfold_beam`. This function takes into account the true voltage in each bucket and distributes the particles in the bunches defined by :code:`ring.fillpattern` using a 6D orbit search. """ lattice = initialize_lpass(lattice, nturns, kwargs) return internal_lpass(lattice, r_in, nturns=nturns, refpts=refpts, no_varelem=False, **kwargs)
[docs] @fortran_align def element_pass(element: Element, r_in, **kwargs): """Tracks particles through a single element. Parameters: element: AT element r_in: (6, N) array: input coordinates of N particles. *r_in* is modified in-place and reports the coordinates at the end of the element. For the best efficiency, *r_in* should be given as F_CONTIGUOUS numpy array. Keyword arguments: particle (Particle): circulating particle. Default: :code:`lattice.particle` if existing, otherwise :code:`Particle('relativistic')` energy (float): lattice energy. Default 0. If *energy* is not available, relativistic tracking if forced, *rest_energy* is ignored. Returns: r_out: (6, N) array containing output the coordinates of the particles at the exit of the element. """ return internal_epass(element, r_in, **kwargs)
[docs] def patpass(lattice: Iterable[Element], r_in, nturns: int = 1, refpts: Refpts = End, pool_size: int = None, start_method: str = None, **kwargs): """ Simple parallel implementation of :py:func:`.lattice_pass`. If more than one particle is supplied, use multiprocessing. For a single particle or if the lattice contains :py:class:`.Collective` elements, :py:func:`.atpass` is used. :py:func:`patpass` tracks particles through each element of a lattice calling the element-specific tracking function specified in the Element's *PassMethod* field. Parameters: lattice: list of elements r_in: (6, N) array: input coordinates of N particles. *r_in* is modified in-place and reports the coordinates at the end of the element. For the best efficiency, *r_in* should be given as F_CONTIGUOUS numpy array. nturns: number of turns to be tracked refpts: Selects the location of coordinates output. See ":ref:`Selecting elements in a lattice <refpts>`" pool_size: number of processes. If None, ``min(npart,nproc)`` is used start_method: python multiprocessing start method. :py:obj:`None` uses the python default that is considered safe. Available values: ``'fork'``, ``'spawn'``, ``'forkserver'``. Default for linux is ``'fork'``, default for macOS and Windows is ``'spawn'``. ``'fork'`` may be used on macOS to speed up the calculation or to solve Runtime Errors, however it is considered unsafe. Keyword arguments: keep_lattice (bool): Use elements persisted from a previous call. If :py:obj:`True`, assume that the lattice has not changed since the previous call. keep_counter (bool): Keep the turn number from the previous call. turn (int): Starting turn number. Ignored if *keep_counter* is :py:obj:`True`. The turn number is necessary to compute the absolute path length used in RFCavityPass. losses (bool): Boolean to activate loss maps output omp_num_threads (int): Number of OpenMP threads (default: automatic) The following keyword arguments overload the Lattice values Keyword arguments: particle (Particle): circulating particle. Default: *lattice.particle* if existing, otherwise *Particle('relativistic')* energy (float): lattice energy. Default 0. If *energy* is not available, relativistic tracking if forced, *rest_energy* is ignored. Returns: r_out: (6, N, R, T) array containing output coordinates of N particles at R reference points for T turns. loss_map: If *losses* is :py:obj:`True`: dictionary with the following key: ============== =================================================== **islost** (npart,) bool array indicating lost particles **turn** (npart,) int array indicating the turn at which the particle is lost **element** ((npart,) int array indicating the element at which the particle is lost **coord** (6, npart) float array giving the coordinates at which the particle is lost (zero for surviving particles) ============== =================================================== .. note:: * For multiparticle tracking with large number of turn the size of *r_out* may increase excessively. To avoid memory issues :pycode:`lattice_pass(lattice, r_in, refpts=[])` can be used. An empty list is returned and the tracking results of the last turn are stored in *r_in*. * By default, :py:func:`patpass` will use all the available CPUs. To change the number of cores used in ALL functions using :py:func:`patpass` (:py:mod:`~at.acceptance.acceptance` module for example) it is possible to set ``at.DConstant.patpass_poolsize`` to the desired value. """ kwargs['pool_size'] = pool_size kwargs['start_method'] = start_method lattice = initialize_lpass(lattice, nturns, kwargs) return internal_plpass(lattice, r_in, nturns=nturns, refpts=refpts, **kwargs)
Lattice.lattice_pass = lattice_pass