\chapter{GUI Installation}
\label{s:gui.install}

%-----------------------------------------------------------------
\section{Obtaining the Source Code}

Source code and documentation for \bmad, \tao and the GUI for \tao can be obtained, if needed, at
the \bmad web site at:
  \hfill\break \hspace*{0.3in} \url{https://www.classe.cornell.edu/bmad}

%-----------------------------------------------------------------
\section{Building Tao}
\label{s:building}

As a prerequisite, if not already available, \tao must be built before using the GUI. Build
instructions are available on the \bmad web site. There are two ways for the GUI scripts (written in
Python) to interact with \tao. One way is to use the \vn{pexpect} module which is a communications
layer that interfaces to \tao's command line interface. The other way is to use \vn{ctypes} (an
interface between Python and C) to communicate directly with the \tao subroutine library (the \tao
program is built by linking to the \tao library). 

The advantage of using \vn{ctypes} is that it is faster. The drawback is that \vn{ctypes} requires a
version of the \tao library that is \vn{shared object}. If you are using a \bmad
``\vn{Distribution}'' (a package that is downloaded from the Web containing \bmad, \tao, associated
libraries, etc.), the default is {\em not} to build shared object libraries. This default can, of
course, be changed but if you do not have control of how things are built, you may have to use
\vn{pexpect}. To check if there is a shared object library built, issue the following command:
\begin{example}
  ls $ACC_ROOT_DIR/production/lib/libtao.*
\end{example}
[This assumes that you are not setting \vn{ACC_LOCAL_ROOT} as discussed in \Sref{s:e.vars}.]
In all cases you will see a file \vn{libtao.a}. This is a static library which is always built but
not of use. A file with an extension \vn{.so} (UNIX) or \vn{.dylib} (Mac) is a shared object library. 

%-----------------------------------------------------------------
\section{Python Requirements}

Minimum Python version for the GUI is Python 3.6.

The GUI depends upon a number of modules that may have to be downloaded:
\begin{example}
  tkinter
  ttk (may be called pyttk)
  pexpect         # If using pexpect instead of ctypes.
  matplotlib
  cycler
  ateutil
  tkagg
\end{example}
Note: The GUI uses the TkAgg backend for matplotlib. There may be a problem with Python finding the
TkAgg backend. On the mac, using macports, the solution is to install matplotlib with the
\vn{tkinter} variant. Something like:
\begin{example}
  sudo port uninstall py36-matplotlib           # May not be needed.
  sudo port install  py36-matplotlib +tkinter   # This is when using Python version 3.6
\end{example}
For more information see:
\begin{example}
  https://matplotlib.org/tutorials/introductory/usage.html#backends
\end{example}

If one of the modules is missing, python will generate an error message. For example:
\begin{example}
> python ../../gui/main.py
Exception in Tkinter callback
Traceback (most recent call last):
  File "/opt/local/Library/Frameworks/Python.framework/Versions/3.7/lib/
                            python3.7/tkinter/__init__.py", line 1705, in __call__
    return self.func(*args)
  File "../../gui/main.py", line 372, in param_load
    from tao_interface import tao_interface
  File "/Users/dcs16/Bmad/bmad_dist/tao/gui/tao_interface.py", line 4, in <module>
    from tao_pipe import tao_io
  File "/Users/dcs16/Bmad/bmad_dist/tao/python/tao_pexpect/tao_pipe.py", line 14, in <module>
    import pexpect
ModuleNotFoundError: No module named 'pexpect'
\end{example}
Notice that the last line shows that the pexpect module is needed.

How to install missing modules on the mac: [Note: The exact installation commands will depend upon
which version of python is being used. Use the "python --version" command to see what version you
are using.

Using macports and python 3.6:
\begin{example}
  sudo port install py36-tkinter
  sudo port install py36-pexpect
\end{example}

Using pip (or pip3):
\begin{example}
  sudo pip install pytkk
  sudo pip install pexpect
\end{example}

WARNING: it can be dangerous to use pip to install/modify modules in your system Python. A much
safer way to install the modules you need is to set up a python virtual environment.  On Linux, you
may also be able to find versions of the required modules in your system package manager, which are
tailored to your Linux distribution and will not break your system python.

%-----------------------------------------------------------------
\section{Environmental Variables}
\label{s:e.vars}
To run the GUI (or even to run \tao without the GUI), certain environmental varibles must be
set. This is the same initialization that is done when compiling \bmad and \tao. See your local Guru or the
\bmad web site for more details. To see if the environmental variables have been set, run the
\vn{accinfo} command.

It may be desireable to specify a local build tree as the place for the python scripts to find the
\tao executable or \tao shared object library. To accomplish this, set the environmental variable
\vn{ACC_LOCAL_ROOT} to the base directory of your local build tree.
\begin{example}
  export ACC_LOCAL_ROOT=/home/dcs16/bmad_dist
\end{example}

The standard place for the GUI script files is at:
\begin{example}
  "${ACC_ROOT_DIR}/tao/python/pytao/gui
\end{example}
When doing GUI development work, the default location can be changed by setting \vn{ACC_PYTHONPATH}. Example:
\begin{example}
  export ACC_PYTHONPATH="$ACC_LOCAL_ROOT/tao/python/pytao/gui"
\end{example}
[This assumes that \vn{ACC_LOCAL_ROOT} has been set.]  \vn{ACC_PYTHONPATH} must be set before \bmad
is initialized. That is, if \bmad is initialized in the \vn{.bashrc} file, \vn{ACC_PYTHONPATH} must
be initialized in the \vn{.bashrc} file before the \bmad initialization.

To check that \vn{PYTHONPATH} has the correct value use the command:
\begin{example}
  printenv |grep PYTHONPATH
\end{example}

%-----------------------------------------------------------------
\section{Installation Troubleshooting}
\label{s:gui.trouble}

Got error:
\begin{example}
  ImportError: cannot import name ‘_tkagg'
\end{example}

Solution: Uninstall and then reinstall matplotlib. For example, if using pip:
\begin{example}
  sudo pip uninstall matplotlib
  sudo pip install matplotlib
\end{example}
