Getting started with Finesse development

Finesse is an open source program where contributions (of any size) from members of the optical simulation community are welcome and encouraged. This page contains information on how to contribute, either with bug reports or feature requests or with direct development.

Submitting a bug report

If you encounter a bug in the code or documentation, especially in a release version, do not hesitate to submit an issue to the Issue Tracker.

When reporting a bug, please include the following:

  • A short, top-level summary of the bug. In most cases, this should be 1-2 sentences.

  • A minimal but complete and verifiable code snippet example to reproduce the bug.

  • The actual result(s) of the example provided versus the expected result(s)

  • The Finesse version, Python version and platform (i.e. OS version) you are using. You can find the first two from a Python interpreter with, e.g:

import platform
import finesse

print(platform.python_version())
print(finesse.__version__)
3.12.4
3.0a26

If the bug is Physics-related (e.g. an unexpected discrepancy in results between Finesse and another method) then you should also provide details of the method(s) used to compute the result - in particular the equations used.

Contributing to development

The preferred way to contribute to Finesse development is to fork the main repository https://gitlab.com/ifosim/finesse/finesse3, work on this copy of the code then submit a “merge request”.

A brief summary of the process is given below, with more details to be found in the sections later on.

  1. Install git and set up a fork of the main Finesse repository.

  2. Set up the Finesse development environment.

  3. Install the pre-commit hooks that will check your code for style errors when you commit:

    $ pre-commit install
    
  4. Create a new branch on your local copy to hold the changes you want to contribute:

    $ git checkout -b <feature-name> origin/develop
    

    The name format should follow either feature/xyz or fix/xyz where xyz is an informative branch slug, otherwise the branch might be rejected when pushed.

    Once you have reached this stage you can start programming!

  5. Work on your branch, on your machine, using git to do the version control. Push any changes you have committed to your copy of the Finesse repository:

    $ git push -u origin <feature-name>
    
  6. Once you are happy with the state of your changes, submit a merge request for review.

Installing git

Linux / macOS

Install git using your system package manager.

Windows

Install Git for Windows. You can either use the tools this provides directly to clone the Finesse repository or add the path to your git executable to the Windows environment variables - details on how to do this are shown in the next step, but you can skip this if you intend to use the git bash/gui here feature(s) of Git for Windows.

To be able to use git from the command line, and via an Anaconda Prompt, you need to add the path to your git executable (installed in the step above) to the Windows environment variables.

Type “environment variables” into the Windows search bar and open the first result. Click the “Environment Variables…” button.

In the new window that pops up, navigate to the lower panel (System Variables) and find the field named “Path”. Click the “Edit” button with this field highlighted. You will now be presented with a window showing all the currently stored paths. Click the “New” button in this Window and add the following two paths separately:

C:\Program Files\Git\bin\git.exe C:\Program Files\Git\cmd

Note that these paths above are assuming that you did not change the default install location of Git for Windows.

Setting up your fork

Finesse development takes place on a server provided primarily for members of the LIGO, Virgo or KAGRA collaborations. If you are a member, you can fork the project on this service:

  1. Log-in to the the LIGO GitLab server with your LIGO / Virgo / KAGRA account.

  2. Go to the Finesse repository homepage: https://gitlab.com/ifosim/finesse/finesse3.

  3. Click on the “Fork” button near the top of the page. This will create a copy of the Finesse repository under your account on the GitLab server. For more information about this step, see Setting up your fork below.

If you are not a member, you can fork Finesse using your preferred git service, or just create your own local repository.

Once you have a fork, change directory to your local copy. Now you want to link your repository to the upstream repository (the main Finesse repository), so that you can fetch changes from trunk. To do this, run:

$ git remote add upstream git://gitlab.com/ifosim/finesse/finesse3.git

upstream here is an arbitrary name we use to refer to the main Finesse repository. Note the use of git:// for the URL - this is a read-only URL which means that you cannot accidentally write to the upstream repository. You can only use it to merge into your fork.

Check that your remotes are set-up correctly with:

$ git remote -v show

This should list something similar to:

upstream    git://gitlab.com/ifosim/finesse/finesse.git (fetch)
upstream    git://gitlab.com/ifosim/finesse/finesse.git (push)
origin      git@git.ligo.org:<username>/finesse3.git (fetch)
origin      git@git.ligo.org:<username>/finesse3.git (push)

Occasionally you should synchronize your fork with the upstream Finesse repository to ensure your copy does not get too out-of-date.

Todo

write info on syncing forks with upstream

Setting up the Finesse development environment

If you’re just getting started, it is easiest to set up Finesse for development using the Conda environment files provided in the git repository. These install system prerequisites (such as a C compiler) and install Finesse with all of its development tools and requirements. Alternatively you can manage the prerequisites yourself (e.g. via your system package manager) and set up Finesse using the included setuptools configuration. Both approaches are described below.

Note

In these steps Finesse is installed in “editable” mode, meaning that any changes to source files in the local git copy (i.e. after pulling the latest changes from the upstream repository) will be reflected in the installed version. When you change a file or synchronize your fork, you may have to recompile the Finesse C extensions.

Developing via Conda

Conda is the free and open source package manager included in the Anaconda and Miniconda scientific computing packages.

Regardless of platform, you need to first install the Conda package manager, either via Anaconda or Miniconda.

Note

Conda commands can be notoriously slow to execute. Mamba is a much faster drop-in replacement for all conda commands (e.g. conda install can be replaced with mamba install). Alternatively, you can add the --solver libmamba argument when using conda commands.

Change directory to your local copy of the Finesse repository:

$ cd /path/to/finesse3

Create a new Conda environment using the Finesse environment file:

$ conda env create -n <name_of_environment> -f <environment-spec>.yml

where you should substitute <name_of_environment> for a suitable name of your choice, e.g: finesse3, and <environment-spec> for either environment (Linux and macOS) or environment-win (Windows).

The above step should install all necessary requirements to build and install Finesse. Depending on your configuration, Conda may or may not activate your new environment automatically. If it did not, you can simply run:

$ conda activate <name_of_environment>

At this point you should see a (<name_of_environment>) at the start of your shell prompt, indicating that the environment is active.

The last step is to install Finesse in editable mode inside your new environment, meaning changes you make to the code will be reflected in the PYTHONPATH used by the Python interpreter. A Make target to do this is provided:

$ make develop-conda

Using ccache for faster cython compilation

If you are going to re-compile the Cython extensions often during development, it might be worth it to set up ccache. Ccache is a compiler cache. It speeds up recompilation by caching the result of previous compilations and detecting when the same compilation is being done again.

On linux, it is available in most package managers (e.g. sudo apt-get install ccache), or can be installed from source.

Afterwards, the easiest way for the python build system to pick up ccache is by symlinking:

mkdir ~/.ccache_symlinks
ln -s `which ccache` ~/.ccache_symlinks/gcc
ln -s `which ccache` ~/.ccache_symlinks/cc
ln -s `which ccache` ~/.ccache_symlinks/g++
ln -s `which ccache` ~/.ccache_symlinks/c++
export PATH=/home/.ccache_symlinks:$PATH

Depending on your distribution, such a folder with symlinks might already exist at /usr/lib/ccache.

Some extra configuration should be placed in ~/.config/ccache/ccache.conf:

hash_dir = false
base_dir = /home

You can test your setup by building finesse twice

make clean # delete all .so files
ccache -s # show ccache statistics
make # will take a few minutes
make clean
ccache -s # You can see the cache size has grown
make # this should only take a few seconds
ccache -s # the cache hit counter should have incremented by ~50

The downside is that this does not work for pip commands that run in isolated environments, since it installs the dependencies in a folder with a randomly generated name, causing the -I` arguments on the gcc calls to have a different value every time.

So pip install -e . will not use the cache, neither will `pip wheel .. Use the --no-build-isolation flag to be able to use the cache in these cases (requires you to have the build dependencies available in the environment).

Troubleshooting Windows installation

A number of different errors may occur when attempting to install Finesse from source on Windows. The list below should be a comprehensive guide to addressing these issues.

‘cannot find -lmsvcr140’ error during the compilation process

Here are the steps to resolve this error:

  1. Use the Windows search bar to find a vcruntime140.dll file. Open the folder location of this file and copy the file.

  2. Paste this file to: C:\<ANACONDA_PATH>\envs\<ENV_NAME>\Library\mingw-w64\lib where <ANACONDA_PATH> is the path to your Conda installation and <ENV_NAME> is the name of your Conda environment that you are using for your Finesse installation.

  3. If you still get this error after the steps above, then use the Windows search bar to find the file cygwinccompiler.py. Open this file and edit the following lines, from this:

    elif int(msc_ver) >= 1900:
        # VS2015 / MSVC 14.0
        return ['msvcr140']
    

    to this:

    elif int(msc_ver) >= 1900:
        # VS2015/ MSVC 14.0
        return ['vcruntime140']
    

Developing via Python package manager

With this approach you are responsible for ensuring the Finesse system requirements are installed and available.

Finesse and the development extras can be installed using pip with:

$ make develop-pep517

Rebuilding extensions

If you change (or pull changes from upstream) any files with names ending .pyx / .pxd then you will need to re-build the Finesse C extensions. This means running make inside a terminal from the top level Finesse git directory.

Note

The Finesse repository contains a PEP 517 compatible build configuration (see Requirements for building, running and developing Finesse). Most build frontends (such as pip) will install projects that define PEP 517 compatible build configurations in an isolated environment with only the necessary build requirements available. This default behaviour presents a small annoyance when quickly trying to rebuild Finesse extensions during development, whereupon pip (or whatever build frontend is being used) will first create a new temporary environment then download (or retrieve from cache) and install the build requirements, then proceed to rebuild the full project and extensions without checking whether anything actually needs rebuilt. This process is slow, taking many minutes on some machines. To mitigate this nuisance, the Makefile in the Finesse project root builds in-place, performing recompilation of extensions directly within the local directory without first setting up an isolated build environment. This is much faster and only rebuilds files that have actually changed, but, in order for this to work, the build requirements specified in pyproject.toml have to also be installed in the local development environment. These are available as an optional set of requirements named "inplacebuild", installation of which is included in the instructions above.

Once PEP 660 is widely supported by build frontends like pip, this step may not be required.