Contributing to Psignifit 3.0

Psignifit 3.0 is free software. You are free to modify the software under the terms of the license that is distributed with Psignifit 3.0. We welcome developers that want to contribute to Psignifit 3.0.

Software Architecture

The Psignifit 3.x code base is logically split into several components:

psi++:The C++ engine of Psignifit.
pypsignifit:High level Python interface, including visualisation methods.
swignifit:Python interface to psi++ autogenerated using the swig tool.
cli:Pure C++ command-line interface to psi++
rpsignift:R interface to psi++.
mpsignifit:MATLAB interface to cli.

We refer to previous versions of psignifit (2.5.6 and before) as psignifit-classic.

The following UML inspired diagram shows the individual components of Psignifit 3.x, and how they relate:

Software Architecture

The diagram shows all components and how they are connected. The high-level interfaces pypsignifit, mpsignifit all eventually access the psi++ engine via an layer. Depending on the interface language, the layer may be either swignifit or cli.

In Linux, building the software begins with compiling the psi++ headers and sources into a shared library libpsipp.so. Then swignifit is compiled in two steps. First the swig tool translates the swig definition file swignifit_raw.i into the swignifit_raw.py and swignifit_raw.cxx. Then, the shared library _swignifit_raw.so is compiled and linked with libpsipp.so. When accessing the engine from Python, the high-level pypsignifit calls one of the Python files in swignifit interface_methods.py or swignifit_raw.py, which in turn call _swignifit_raw.so, which in turn calls libpsipp.so. For Matlab The situation is similar, but instead of swignifit the cli handles calling the engine.

Dependencies

This section lists all dependencies. The version numbers are the Debian versions we used when we began development, and hence they will probably be outdated by the time you read this.

Compile-Time

Run-Time

Documentation

  • sphinx (0.6.5-1)

    to generate the html documentation

  • doxygen (1.6.3-1)

    to generate the C++ documentation

  • epydoc (3.0.1-5)

    to generate the Python API documentation

Testing

  • nosetest (0.11.1-1) for running some of the unit tests

Build System

We use a combination of distutils and make to build the software.

There are several Makefiles:

Makefile:main makefile.
src/Makefile:psi++ makefile.
cli/Makefile:cli makefile.
cli/MakefileMinGW:
 cli makefile to compile mingw for windows.

Note that main makefile contains targets to invoke the psi++ and cli makefiles. The main targets are build, install, clean and test. The main targets will invoke separate targets to build the individual components of the software. If during development you wish to build components separately, have a look at the main makefile, it should contain everything you need.

There is a single setup.py file that can be used to compile and install pypsignifit including the swignifit interface. Since the source download we provide includes the already generated interface, this is the recommended method of installation for users.

For more information about how to use the setup.py file, you may look at: Installing Pyhon Modules.

Git-Repositories

We use Git for version control. Our main repository is hosted at Sourceforge as Psignifit. Clone the repository with the following command :

$ git clone git://psignifit.git.sourceforge.net/gitroot/psignifit/psignifit

You can also browse the Sourceforge repository online.

We also provide a alternative repository on Github: https://github.com/esc/Psignifit-3.x. This is a mirror of the sourceforge which is updated daily. If you prefer to use the Github workflow (fork -> clone -> pull-request) please fork from this repository.

Layout

Every developer has his/her own branch, and we use the master branch to do integration. Hence we have the following layout in the sourceforge repository:

master:the integration branch
ingo/master:Ingo’s main branch
val/master:Valentin’s main branch

In addition we also make heavy use of short-lived topic branches, which are deleted after being merged.

All branches except master are subject to rewind/rebase. So please base you development either on master or better yet, on the latest development snapshot(see below).

Commits

To make it easier to keep track of the development of Psignifit, we use the following marks forto identify what parts of the code base we worked on:

C++:C++ code base
swig:swig interface
py:Python code
R:R code
matlab:matlab code
build:Build system
docs:Documentation

And the following marks to identify the type of change that was made

NF:new feature
BF:bug fix
RF:refactor
FO:formatting
UT:unit test

Example:

[build/RF] do proper signed tags with new tag naming structure

Also, If you wish to automate the process of creating such markers, to increase consistency, we suggest using the following git-hook: https://github.com/esc/commit-marker

Merging

For easy tracking of what changes were absorbed during merge, we advise you to enable merge summary within git:

$ git-config merge.summary true

Execute without installation

Since it is tedious to install pypsignifit during development. We provide a so called in-place compilation. To compile the swignifit interface without installation simply type:

$ make

You can then run:

>>> import pypsignifit as psi

from the source directory. Furthermore you can use the environment variable PYTHONPATH in case you need to bring source directory into scope elsewhere in the filesystem.

Maintainers Notes

This section contains notes about the release process. We also support this process with various Makefile targets. All targets for release are prefixed with dist-

Since Psignift 3.x is still beta software we provide so called development snapshots as and when new features and bugfixes are available.

Development Snapshots

Development snapshots are made on a regular basis. They are invoked with:

$ make dist-upload-archives

This will create all the required zip files and windows installers, tag the git repository, and upload the files and tags to sourceforge.

Tags

Tags should mark critical points in the development history in the following way:

  • release/3.0_beta.YYYYMMDD.1 marks the release of a development snapshot
  • doc-YYYYMMDD marks a modification of the documentation that has been uploaded to sourceforge.

Older tags may have different versioning schemes. This scheme was established beginning of 2012.

Extending

This section contains hints about writing code.

Coding Style

We try to adhere to the: Numpy Docstring Conventions as far as possible.

Adding a new sigmoid

In principle every part of the library can be replaced. This is generally done by deriving from the fundamental base classes. An exception is adding a new sigmoid:

Adding a new sigmoid requires two steps:

  1. Write a new class that inherits from PsiSigmoid

  2. If you want your new sigmoid to work with mwCore objects, you have to add a label for that, too.

    The mwCore class scales the second parameter such that w can be directly interpreted as the width of the region in which the sigmoid still rises significantly. What to “rise significantly” means is parameterized by the parameter alpha of the mwCore. The default alpha==0.1 indicates that w is the width of the range over which the sigmoid rises from 0.1 to 0.9. Thus, the scaling of the second parameter obviously depends on the sigmoid. The constructor for the mwCore class looks roughly like this:

    mwCore::mwCore ( int sigmoid, double al )
            : sigmtype(sigmoid), alpha(al), zshift(0) {
        switch (sigmoid) {
        case 1:
            ...
            break;
        /////////////// here ////////////////
        default:
            throw NotImplementedError();
        }
    }
    

    At the position marked by:

    /////////////// here ////////////////
    

    in the above code example, you should add a new case that defines all the scaling parameters depending on your sigmoid. zalpha scales w to the correct range, zshift is an additional shift to ensure the the sigmoid has an output value of 0.5 at an input value of 0.

Adding a new source file

When adding a new C++ source or header file you will have to:

  • add the file to the git repository
  • add the filename to the Makefile
  • add the filename to the Python setup file