PyChaste Developer Guide
This is a developer guide on generating Python wrappers for cell-based Chaste and fixing common problems related to wrappers.
Running tests
To get started, see the install guide for detailed instructions on building PyChaste from source.
From the build directory run all PyChaste tests with:
ctest -L pychaste
If working in a docker container or other headless environment, run the above with xvfb-run
for off-screen rendering:
xvfb-run --server-args="-screen 0 1024x768x24" ctest -L pychaste
To check for C++ classes that are missing Python wrappers, run:
ctest -V -R TestPyWrapperChanges$
This will flag any classes in cell-based Chaste that need wrappers. For example:
Unknown class NewCellCycleModel from /Chaste/cell_based/NewCellCycleModel.hpp
Wrapping classes
During cmake configuration, Python wrappers are automatically generated from the settings in Chaste/pychaste/dynamic/config.yaml
. The generated wrappers are stored under the build
directory in build/pychaste/wrappers
.
Wrapping a new class
To add a new class, put a new entry with the name of the class in the config.yaml
settings. For example, to create Python wrappers for a NewCellCycleModel
class, put in the following entry under classes
:
- name: NewCellCycleModel
If cmake configuration has already been run, re-generate the wrappers with:
make pychaste_wrappers
The new wrappers will now be stored under build/pychaste/wrappers
as NewCellCycleModel.cppwg.[c|h]pp
.
Excluding a class from wrapping
To exclude a class from wrapping, add an excluded
flag to the entry for the class e.g.
- name: NewCellCycleModel
excluded: True
This will ensure that wrappers are not created for the class. It will also prevent tests from flagging it as a class that is missing Python wrappers.
Removing or renaming an existing class
If a class has been removed or renamed in the main codebase, it should be removed or renamed in config.yaml
as well. Otherwise, errors will arise during cmake configuration such as:
fatal error: 'NewCellCycleModel.hpp' file not found
Fixing errors
UBLAS-related Errors
Error:
TypeError: Unregistered type : boost::numeric::ublas::c_vector<double, 3ul>
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
...
TypeError: Unable to convert function return value to a Python type! The signature was
(self: chaste._pychaste_lib.Foo_3) -> boost::numeric::ublas::c_vector<double, 3ul>
Failed
Solution:
In config.yaml
, add the following to Foo
- name: Foo
source_includes:
- PythonUblasObjectConverters.hpp
VTK-related Errors
Error:
TypeError: Unregistered type : vtkSmartPointer<vtkRenderer>
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
...
TypeError: Unable to convert function return value to a Python type! The signature was
(self: chaste._pychaste_lib.Foo) -> vtkSmartPointer<vtkRenderer>
Failed
Solution:
Ensure that your system VTK version matches the version installed in Python.
In config.yaml
, add the following to Foo
- name: Foo
source_includes:
- PythonVtkObjectConverters.hpp
Other Errors
Error:
pygccxml.declarations.runtime_errors.declaration_not_found_t: Unable to find declaration. Matcher: [(decl type==class_t) and (name==Foo)]
Solution:
Check if the template args of class Foo
are in the template_substitutions
list of config.yaml
and add it if missing.
For example, if Foo
is defined as <unsigned DIMENSIONS> class Foo {...}
, and Foo
is explicitly instantiated for DIMENSIONS=2
and DIMENSIONS=3
:
template_substitutions:
- signature: <unsigned FOO_DIM>
replacement: [[2], [3]]
Error
import chaste
ImportError: /.../lib.so: undefined symbol: _ZN11Foo7BarEv
Foo::Bar
has been declared but not implemented. If Foo::Bar
is not implemented, it can be excluded from wrapping by modifying config.yaml
:
- name: Foo
excluded_methods:
- Bar