pyAT#

Introduction#

Accelerator Toolbox is a code used for simulating particle accelerators, used particularly for synchrotron light sources. It is hosted on Github. Its original implementation is in Matlab.

pyAT is a Python interface to Accelerator Toolbox. It uses the ‘pass methods’ defined in Accelerator Toolbox, implemented by compiling the C code used in the AT ‘integrators’ into a Python extension. These pass methods are used by higher-level functions to provide physics results.

See the pyAT website for a more detailed introduction.

pyAT supports Python 3.7 to 3.11.

Installation#

Install accelerator-toolbox from PyPI:

$ pip install accelerator-toolbox

Usage#

Example usage:

>>> import at
>>> ring = at.Lattice.load('machine_data/hmba.mat')
>>> print(at.radiation_parameters(ring))
          Frac. tunes: [0.2099983  0.34001317 0.00349013]
                Tunes: [76.2099983  27.34001317]
       Chromaticities: [5.73409894 3.91761206]
Momentum compact. factor: 8.506669e-05
          Slip factor: -8.505944e-05
               Energy: 6.000000e+09 eV
   Energy loss / turn: 2.526189e+06 eV
Radiation integrals - I1: 0.07179435013387388 m
                   I2: 0.13844595446798158 m^-1
                   I3: 0.003357584058614851 m^-2
                   I4: -0.07375725030666251 m^-1
                   I5: 5.281495714523264e-07 m^-1
      Mode emittances: [1.3148797e-10           nan           nan]
Damping partition numbers: [1.53275121 1.         1.46724879]
        Damping times: [0.00872477 0.0133729  0.00911427] s
        Energy spread: 0.000934463
         Bunch length: 0.0030591 m
     Cavities voltage: 6000000.0 V
    Synchrotron phase: 2.70701 rd
Synchrotron frequency: 1239.74 Hz

For more examples of how to use pyAT, see pyat_examples.rst.

Developer Notes#

Developer notes are in developers.rst.

pyAT Developer Notes#

See also README.rst.

Installation preparation#

Windows#

Download the appropriate version of Visual C++.

Linux#

Install the Python development package for your OS. For example, using yum:

$ sudo yum install python3-devel

Source download#

Download the latest version of AT:

$ git clone https://github.com/atcollab/at.git

Installation (all platforms)#

All the binaries should be built when building the Python extension.

It is easiest to do this using a virtualenv. inside pyat:

$ python3 -m venv venv

Then:

  • activate the virtual environment:

    $ source venv/bin/activate  # or venv\Scripts\activate on Windows
    
  • make sure you have a recent pip installer:

    $ pip install --upgrade pip
    
  • Go to the AT root directory:

    cd <atroot>
    
  • install AT, with the developer tools. 2 option sets are available:

    • [dev] installs test modules (pytest,…)

    • [doc] installs documentation tools (sphinx and extensions)

    They can be installed together: [dev, doc]:

    $ pip install -e ".[dev]"
    

Finally, you should be able to run the tests:

$ python -m pytest pyat/test

Comparing results with Matlab#

There is a second set of tests that require a Matlab licence and allows comparing results directly with a Matlab session. See test_matlab/README for information.

Debugging#

Print statements in the C code will work once the integrators are recompiled. To force recompilation, remove the build directory:

$ rm -rf build

Any changes to .py files are automatically reinstalled in the build, but to ensure any changes to .c files are reinstalled rerun:

$ pip install -e .

If you get strange behaviour even after running pip install develop again, then running the following, inside pyat, should fix it:

$ rm -rf build
$ find at -name "*.pyc" -exec rm '{}' \;
$ find at -name "*.so" -exec rm '{}' \;
$ pip install -e .

N.B. pip install -e . needs to be run with the same version of Python (and numpy) that you are using to run pyAT.

Releasing a version to PyPI#

Because pyAT compiles C code, releasing a version is not simple. The code must be compiled for different operating systems and Python versions.

To do this, we use the continuous integration service Github Actions. When a tag of the form pyat-* is pushed to Github, wheels for each supported platform will be built and automatically uploaded as an ‘artifact’.

We use Semantic Versioning for this project. As documented by the full specification, we use a version number with three dot-separated numbers: MAJOR.MINOR.PATCH. Increment the:

  • MAJOR version when you make incompatible API changes

  • MINOR version when you add functionality in a backward compatible manner

  • PATCH version when you make backward compatible bug fixes

Release procedure#

To upload a release to PyPI, you will need to be a ‘maintainer’ of Accelerator Toolbox on PyPI.

For testing any version that you have installed, the simple snippet in README.rst is sufficient.

Decide the Python versions that should be supported in the release#

  • Set these Python versions in requires-python in pyproject.toml

  • Set at least these Python versions as python-version in .github/workflows/python-tests.yml

Determine the minimum numpy and scipy versions:#

  • the version ensuring the requirements necessary to run PyAT is set in the dependencies item of the [project] section of pyproject.toml

  • The version required to build PyAT is set in the requires item of the [build-system] section of pyproject.toml. It depends on the python version and must be higher or equal to the “run” version.

  • To avoid ABI compatibility issues, the pre-compiled binaries are built with the earliest possible version of numpy for the given Python version. This ensures that the user’s libraries are more recent than the one AT has been compiled with. For that, a copy of pyproject.toml named githubproject.toml is used for compilation. In this copy, the numpy version specifications are set using ~= instead of minimum (>=). Apart from these lines, the 2 files should be strictly identical.

Prepare the “Release notes”#

A draft can be obtained by creating a new tag on GitHub. Click “Draft a new release” in the releases page, choose a new tag in the form pyat-x.y.z with the correct incremented version number. The pyat- prefix is necessary to identify python releases. Select the master branch as target. In the description area, choose the current release in the “previous tag” pull-down, and press “Generate release notes”.

The generated notes can now be copied and edited. You can then either cancel or save the release as a draft while editing the release notes.

The ## What's changed section should be split into ## Bug fixes and ## New features. It must be filtered to keep only the python changes, ignoring the Matlab ones. The tags on each pull request are there to help in this filtering.

The release notes should start with a ## Main modifications section summarising the important points of the new release.

They must end with a section pointing out ## Incompatibilities and mentioning the necessary actions before upgrading to this release.

Open a Pull Request for the new release#

The goal is to make all contributors aware of the new release, to check that no pending modifications are worth being included and to review the release notes.

There should be no code modifications except updates of version informations in the documentation. Once the pull request is approved and merged, the release may be built.

Build the release#

Now either go back to the draft release saved above, or start again the procedure, but now finalising with the Publish button.

If all goes well, there will be a build of “Build and upload wheels and sdist” associated with the tag pyat-x.y.z: on the Github Actions page. This build will have ‘tar.gz’ and ‘wheels’ downloads available.

Upload the release to pip#

  • Download the tar.gz and wheels files and unzip them into a directory <dir>

  • Manually install at least one wheel to make sure that it has built correctly

  • Install Twine for uploading the files to PyPI. One way is to use pipx. Once pipx installed, use:

    $ pipx install twine  # or:
    $ pipx upgrade twine
    
  • Use Twine to upload the files to PyPI. You will be prompted for your PyPI credentials:

    $ twine upload <dir>/*.whl
    $ twine upload <dir>/*.tar.gz
    
  • Finally, check that the wheels are uploaded properly. You can use the same virtualenv:

    $ pip install accelerator-toolbox
    

Note that 46 different files were uploaded for pyat-0.0.4 covering different platforms and architectures.

The configuration for this is in .github/workflows/build-python-wheels.yml.

pyAT Examples#

Please follow <at>/pyat/README.rst for installation instructions. In these examples, we use the ring from hmba.mat found in <at>/pyat/machine_data; however, they will also work on the err.mat ring if you want to be more representative of a real accelerator.

Initialisation:#

  • Start Python within the virtual environment where PyAT in installed and import at:

    $ cd <at>
    $ source venv/bin/activate
    $ python
    Python 2.7.3 (default, Nov  9 2013, 21:59:00)
    [GCC 4.4.7 20120313 (Red Hat 4.4.7-3)] on linux2
    Type "help", "copyright", "credits" or "license" for more information.
    >>> import at
    >>>
    
  • Load a pyAT ring from a .mat file:

    >>> ring = at.load_lattice('pyat/machine_data/hmba.mat')
    

Basic Use:#

  • The lattice object is a Python interator:

    >>> for element in ring:
    ...   print(element)
    
  • Viewing the first element in the ring:

    >>> ring[0]
    RFCavity('RFC', 0.0, 187500.0, 352372212.4670127, 31, 6000000000.0, PassMethod='IdentityPass')
    
  • Changing the pass method of an element:

    >>> ring[0].PassMethod = "CavityPass"
    
  • Get the s position of the 10th element in the ring:

    >>> at.get_s_pos(ring, 10)
    array([3.4295565])
    

Calculating Physics Data:#

  • Return the linear optics data at the first 5 elements:

    >>> at.get_optics(ring, refpts=[0, 1, 2, 3, 4])
    
  • Physics data functions can also be called as methods on the lattice:

    >>> ring.find_orbit(refpts=[0, 1, 2, 3, 4])