## Python Interface

Python is a powerful, high-level interpreted language that is widely used within the particle physics community. It is particularly useful as an interactive language that provides fast proto-typing of code. A Python interface to PYTHIA is available. This interface is automatically generated with Binder using the PyBind11 template library. Please note that this interface has not been extensively tested and consequently issues may arise. If bugs are found or additional features are required, as usual, please report them to the PYTHIA authors. This interface is a significant departure from the previous interface generated with SWIG, which does not support C++11.

A simplified interface ships with PYTHIA, which is intended to meet the needs of most users while remaining lightweight. Note, not all PYTHIA classes are available through this interface. It is also possible for users to automatically generate their own interface. This is particularly useful if users modify the PYTHIA source code and need to update the interface. When generating the interface there are three options: the simplified interface, a full interface, and a user defined interface. The process of generating these interfaces is described in more detail below.

### Simplified Interface

An attempt has been made to provide the everyday functionality of PYTHIA through the simplified interface. However, if classes or methods appear to be missing, please contact the PYTHIA authors; additional functionality can be included upon request. The following list highlights the available classes and methods in this interface, roughly categorized by function. Note that `help(pythia8)` will return all the available classes and methods in the interface.

- top level: `Pythia`
- event access: `Event`, `Particle`, `Vec4`, `RotBstMatrix`
- particle data: `ParticleData`, `ParticleDataEntry`, `DecayChannel`
- settings and information: `Info`, `HIInfo`, `Settings`, `Flag`, `Mode`, `Parm`, `Word`, `FVec`, `MVec`, `PVec`, `WVec`
- user interface pointers: `Rndm`, `PDF`, `DecayHandler`, `RndmEngine`, `UserHooks`, `MergingHooks`, `BeamShape`, `SigmaProcess`, `TimeShower`, `SpaceShower`, `HeavyIons`, `PartonVertex`
- analysis tools: `Hist`, `HistPlot`, `SlowJet`, `SlowJetHook`
- kinematic functions: `m`, `m2`, `dot3`, `cross3`, `cross4`, `theta`, `costheta`, `phi`, `cosphi`, `RRapPhi`, `REtaPhi`

There are some idiosyncrasies when working with standard template library classes. One of the notable examples are maps with keys as strings. In many cases, it is useful to be able to access the settings maps from the `Settings` class of a `Pythia` instance. Rather than calling something like `getFlagMap()`, `getFlagMap("")` must be called so the interface knows how to map the keys. A full working example is given below.

    import pythia8
    pythia = pythia8.Pythia("", False)
    settings = pythia.settings
    flags = settings.getFlagMap("")
    for key, val in settings.getFlagMap("").items(): print(key)

The following points highlight some of the features of the interface.

- Documentation through the built-in help function in Python provides the relevant mappings between the Python interface and the C++ code. For documentation on the purpose of the code, see the user HTML manual and Doxygen
- Templated C++ types are returned as native Python types, e.g. vectors are returned as lists, etc. Similarly, native Python types can be passed as arguments and are converted to their equivalent C++ templates
- No difference is made between passing by reference or pointer; methods in C++ which take a pointer as an argument in Python simply take the object, e.g. `foo(Vec4*)` and `foo(Vec4&)` are the same in the Python interface.
- All operators defined in C++, e.g. `Vec4*double` are available. Note that reverse operators are not, e.g. `double*Vec4`.
- Classes with defined `[]` operators are iterable, using standard Python iteration, e.g. `for prt in pythia.event`.
- Classes with a `<<` operator can be printed via the built-in print function in Python. Note this means that a string representation via `str` is also available for these classes in Python.
- Derived classes in Python can be passed back to PYTHIA, and should be available for all classes. See `main10.py` for a direct Python translation of the C++ `main10.cc` example which uses a derived class from the UserHooks class to veto events.
- The constant `Pythia::info` member is available as `Pythia::infoPython`. Note, this creates a new instance of the `Info` class, and so needs to be called each time the information might be updated.

### Limitations

In general, most code using PYTHIA implemented through C++ is also possible in the Python interface. There are a number of issues, such as passing streams, which cannot be handled in the Python interface. Additionally, protected members of classes are exposed as fully public members in the Python interface.

### Installation

To install the Python interface, the Python system header `Python.h` must be available. By default when configuring using `--with-python` the system `python-config` script will be used to determine the location of `Python.h`. In some cases, users might wish to use a different version of Python, and so `--with-python-config` can be used to set the Python configuration script used to pick up paths. Alternatively, the directory containing `Python.h` can be set manually with the option `--with-python-include`. Some example configurations could be as follows,

        ./configure --with-python
        ./configure --with-python-config=python3-config
        ./configure --with-python-include=/usr/include/python2.7

where the Python configuration script and path must be changed accordingly for the local system.

After configuring the Python interface for PYTHIA to be built and running `make` as usual, the following files should be generated in the directory `lib`.

- `pythia8.so`: compiled Python module.
- `libpythia8.[so,dylib]`: the standard shared PYTHIA library.

To ensure that the `pythia8.so` module is available to Python, the system variable `PYTHONPATH` should be set similar to

        export PYTHONPATH=$(PREFIX_LIB):$PYTHONPATH

where `PREFIX_LIB` is the directory `lib` which contains `pythia8.so`. Generally, the library paths should be set correctly, but it also may be necessary to set

        export LD_LIBRARY_PATH=$(PREFIX_LIB):$LD_LIBRARY_PATH

where `DYLD` should be substituted for `LD` in OS X. Alternatively, it is also possible to define the Python path from within Python, as is done within the provided examples. Note that the Python module is always compiled as `pythia8.so`, even in OS X. This is because older versions of Python in OS X do not correctly recognize modules ending with the `dylib` suffix.

### Examples

To use the Python interface for PYTHIA, start Python and `import pythia8`. The provided examples can be run by `python mainXX.py` where `XX` is the number of the example.

### Interface Generation

A script for automatically generating the Python interface, `generate`, is available in `plugins/python/` and should be run from this directory. This script requires that the user has Docker installed. A small Docker image of roughly 80 MB will be pulled to run the necessary generation code. There are a number of command line arguments which can be passed.

- `--help` prints the help message for the script.
- `--part` generates the simplified interface. When `generate` is run without arguments, then this is the default behaviour. Note that this requires running the interface generation twice. The first time the required classes are interfaced, the second time additional classes are removed.
- `--full` generates the full interface.
- `--user=FILE` generates a user defined interface using the Binder configuration given by `FILE`.
- `--debug` can be specified with any of the options above and stops the temporary files used in generation from being removed.

Whenever PYTHIA headers are modified, the Python interface is invalidated, and so this automatic generation is particularly useful in such a situation. An example of generating the full Python interface is as follows.

        cd plugins/python
        ./generate --full