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:
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.
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:
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.
Extending
This section contains hints about writing code.
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:
Write a new class that inherits from PsiSigmoid
- 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