Returning Space

14 views
Skip to first unread message

julien

unread,
Oct 21, 2010, 6:22:17 PM10/21/10
to Sire Developers
Hi Chris,

I am trying to get the following code to work in python

molecules, space = amber.readcrdtop(crd_file, top_file)

which requires this declaration in amber.h

tuple<Molecules,Space> readcrdtop(const QString &crdfile, const
QString &topfile);

Actually Space can be different classes depending on what was read in
the topfile. The relevant code in amber.cpp is
(...)
// Finally, box information
// Assume by default non periodic
Cartesian space = Cartesian();
if ( pointers[IFBOX] == 1)
{
/** Rectangular box */
Vector dimensions = ( boxDimensions[1], boxDimensions[2],
boxDimensions[3] );
PeriodicBox space = PeriodicBox(dimensions);
}
(...)
return molecules, space

There are a couple of errors here because the code does not compile.

[ 77%] Building CXX object src/libs/SireIO/CMakeFiles/SireIO.dir/
amber.cpp.o
In file included from /usr/include/boost/tuple/tuple.hpp:33,
from /home/julien/software/devel/sire/corelib/src/
libs/SireIO/amber.h:31,
from /home/julien/software/devel/sire/corelib/src/
libs/SireIO/amber.cpp:33:
/usr/include/boost/tuple/detail/tuple_basic.hpp: In instantiation of
‘boost::tuples::cons<SireVol::Space, boost::tuples::null_type>’:
/usr/include/boost/tuple/detail/tuple_basic.hpp:329: instantiated
from ‘boost::tuples::cons<SireMol::Molecules,
boost::tuples::cons<SireVol::Space, boost::tuples::null_type> >’
/usr/include/boost/tuple/detail/tuple_basic.hpp:535: instantiated
from ‘boost::tuples::tuple<SireMol::Molecules, SireVol::Space,
boost::tuples::null_type, boost::tuples::null_type,
boost::tuples::null_type, boost::tuples::null_type,
boost::tuples::null_type, boost::tuples::null_type,
boost::tuples::null_type, boost::tuples::null_type>’
/home/julien/software/devel/sire/corelib/src/libs/SireIO/amber.cpp:
175: instantiated from here
/usr/include/boost/tuple/detail/tuple_basic.hpp:419: error: cannot
declare field ‘boost::tuples::cons<SireVol::Space,
boost::tuples::null_type>::head’ to be of abstract type
‘SireVol::Space’
/home/julien/software/devel/sire/corelib/src/libs/SireVol/space.h:118:
note: because the following virtual functions are pure within
‘SireVol::Space’:

This is challenging my C++ skills. How do you think I could achieve
the desired behavior ?

Thanks,

Julien

Christopher Woods

unread,
Oct 21, 2010, 6:31:29 PM10/21/10
to sire-de...@googlegroups.com
Hi Julien,

You can't return a virtual base class by value - you have to return a
pointer to the class. In Sire this is achieved by using the PropPtr<T>
pointer holder for the base class you wish to return. In the case of
Space, this is SpacePtr. You can see this with the two lines in
space.h;

typedef SireBase::PropPtr<Space> SpacePtr;

SIRE_EXPOSE_PROPERTY( SireVol::SpacePtr, SireVol::Space )

(the first line lets you use "SpacePtr" instead of having to type
SireBase::PropPtr<Space>, while the second line is the instruction to
the code that generates the python wrappers that lets python create a
value copy of the object pointed to by the SpacePtr, so you don't have
to think of it as a pointer in python).

For your code, all you have to do is when returning a virtual base
class from a function, return *Ptr rather than *, e.g.

SpacePtr someFunction();

rather than

Space someFunction();

The same applies when you return a tuple - return

tuple<Molecules,SpacePtr> readcrdtop(const QString &crdfile, const
QString &topfile);

rather than

tuple<Molecules,Space> readcrdtop(const QString &crdfile, const
QString &topfile);

This will then compile. For it to work in python the
tuple<Molecules,SpacePtr> class must be wrapped. This is declared in
the *_containers.cpp file of the highest class (in this case Molecules
is higher than SpacePtr as SireMol is above SireVol - thus you want to
put it in python2/Mol/SireMol_containers.cpp).

You need to add the line;

register_tuple< boost::tuple<Molecules,SireVol::SpacePtr> >();

(you will see lots of other lines that look like this)

I hope this helps,

Best regards,

Christopher

julien

unread,
Oct 21, 2010, 6:58:27 PM10/21/10
to Sire Developers
Hi Chris,

Thanks for the incredibly fast answer. I have followed your
instructions and indeed got rid of the previous compile error.
However I am now faced with the following error:

[ 77%] Building CXX object src/libs/SireIO/CMakeFiles/SireIO.dir/
amber.cpp.o
/home/julien/software/devel/sire/corelib/src/libs/SireIO/amber.cpp: In
member function ‘boost::tuples::tuple<SireMol::Molecules,
SireBase::PropPtr<SireVol::Space>, boost::tuples::null_type,
boost::tuples::null_type, boost::tuples::null_type,
boost::tuples::null_type, boost::tuples::null_type,
boost::tuples::null_type, boost::tuples::null_type,
boost::tuples::null_type> SireIO::Amber::readcrdtop(const QString&,
const QString&)’:
/home/julien/software/devel/sire/corelib/src/libs/SireIO/amber.cpp:
916: error: ‘molecules’ cannot appear in a constant-expression
/home/julien/software/devel/sire/corelib/src/libs/SireIO/amber.cpp:
916: error: ‘space’ cannot appear in a constant-expression
/home/julien/software/devel/sire/corelib/src/libs/SireIO/amber.cpp:
916: error: template argument 1 is invalid
/home/julien/software/devel/sire/corelib/src/libs/SireIO/amber.cpp:
916: error: template argument 2 is invalid

Is something else that needs to be done before molecules and space can
be used with a tuple or is it just not allowed?

Best regards,

Julien

Christopher Woods

unread,
Oct 22, 2010, 1:29:00 AM10/22/10
to sire-de...@googlegroups.com
Hi Julien,

I've taken a look at your source code and your problem is because you
haven't quite got the syntax of boost::tuple right.

You've written;

return tuple<molecules, space>;

However you should write;

return tuple<Molecules,SpacePtr>(molecules,space);

This is because the angle brackets are used to instantiate the
template, and you may only put class types (or integers) in this part.
This is because "tuple<Molecules,SpacePtr>" is the instantiated class
- not the object. This is easier to see if you wrote;

tuple<Molecules,SpacePtr> tuple_to_return(molecules, space);

return tuple_to_return;

So we create an object (tuple_to_return) of the class
tuple<Molecules,SpacePtr>, which is constructed using the constructor
that took arguments "molecules" and "space". We then returned that
object from the function.

C++ lets you create and return an object in a single line, hence why
we can combine these two lines together to;

return tuple<Molecules,SpacePtr>(molecules, space);

Best regards,

Christopher

julien

unread,
Oct 22, 2010, 10:25:23 AM10/22/10
to Sire Developers
Hi Chris,

Thanks, I fixed this error and now am stuck trying to compile the
python code.
As you can see I have done minimal changes to SireMol_containers.cpp.
The other files, as far as I can tell are automatically generated.

julien@axon:python2$ svn status
M Mol/SireMol_containers.cpp
M Move/active_headers.h
? IO/Amber.pypp.cpp
? IO/Amber.pypp.hpp
M IO/SireIO_registrars.cpp
M IO/CMakeAutogenFile.txt
M IO/active_headers.h
M IO/_IO.main.cpp
julien@axon:python2$ svn diff Mol/SireMol_containers.cpp
Index: Mol/SireMol_containers.cpp
===================================================================
--- Mol/SireMol_containers.cpp (revision 1358)
+++ Mol/SireMol_containers.cpp (working copy)
@@ -48,6 +48,7 @@
#include "SireMol/chain.h"
#include "SireMol/segment.h"
#include "SireMol/molecule.h"
+#include "SireMol/molecules.h"
#include "SireMol/atomselection.h"
#include "SireMol/moleculegroup.h"
#include "SireMol/moleculegroups.h"
@@ -65,6 +66,8 @@
#include "SireMol/angleid.h"
#include "SireMol/dihedralid.h"

+#include "SireVol/space.h"
+
using namespace SireMol;

using boost::python::register_tuple;
@@ -127,6 +130,7 @@
register_tuple< boost::tuple<MGIdentifier,SireBase::PropertyMap>
>();
register_tuple<
boost::tuple<QList<MGIdentifier>,SireBase::PropertyMap> >();
register_tuple<
boost::tuple<QList<MolGroupPtr>,SireBase::PropertyMap> >();
+ register_tuple< boost::tuple<Molecules,SireVol::SpacePtr> >();

register_PackedArray< SireBase::PackedArray2D<Element> >();


The following compile errors are produced

Scanning dependencies of target IO
[ 24%] Building CXX object IO/CMakeFiles/IO.dir/_IO.main.cpp.o
[ 24%] Building CXX object IO/CMakeFiles/IO.dir/
SireIO_properties.cpp.o
[ 24%] Building CXX object IO/CMakeFiles/IO.dir/
SireIO_registrars.cpp.o
In file included from /home/julien/local/include/Sire/sireglobal.h:14,
from /home/julien/local/include/Sire/SireError/
exception.h:39,
from /home/julien/local/include/Sire/SireError/
version_error.h:32,
from /home/julien/local/include/Sire/SireStream/
version_error.h:32,
from /home/julien/local/include/Sire/SireStream/
datastream.h:38,
from /home/julien/local/include/Sire/SireBase/
sharedpolypointer.hpp:32,
from /home/julien/local/include/Sire/SireBase/
property.h:32,
from /home/julien/local/include/Sire/SireSystem/
systemmonitor.h:32,
from /home/julien/local/include/Sire/SireIO/
trajectorymonitor.h:36,
from /home/julien/software/devel/sire/python2/IO/
SireIO_registrars.cpp:6:
/usr/include/qt4/QtCore/qmetatype.h: In function ‘void*
qMetaTypeConstructHelper(const T*) [with T =
SireMol::Selector<SireMol::Atom>]’:
/usr/include/qt4/QtCore/qmetatype.h:163: instantiated from ‘int
qRegisterMetaType(const char*, T*) [with T =
SireMol::Selector<SireMol::Atom>]’
/home/julien/local/include/Sire/SireMol/atom.h:529: instantiated
from here
/usr/include/qt4/QtCore/qmetatype.h:137: error: invalid use of
incomplete type ‘struct SireMol::Selector<SireMol::Atom>’
/home/julien/local/include/Sire/SireMol/atomid.h:48: error:
declaration of ‘struct SireMol::Selector<SireMol::Atom>’
/usr/include/qt4/QtCore/qmetatype.h:138: error: invalid use of
incomplete type ‘struct SireMol::Selector<SireMol::Atom>’
/home/julien/local/include/Sire/SireMol/atomid.h:48: error:
declaration of ‘struct SireMol::Selector<SireMol::Atom>’
/usr/include/qt4/QtCore/qmetatype.h: In function ‘void
qMetaTypeDeleteHelper(T*) [with T =
SireMol::Selector<SireMol::Atom>]’:
/usr/include/qt4/QtCore/qmetatype.h:165: instantiated from ‘int
qRegisterMetaType(const char*, T*) [with T =
SireMol::Selector<SireMol::Atom>]’
/home/julien/local/include/Sire/SireMol/atom.h:529: instantiated
from here
/usr/include/qt4/QtCore/qmetatype.h:130: warning: possible problem
detected in invocation of delete operator:
/usr/include/qt4/QtCore/qmetatype.h:128: warning: ‘t’ has incomplete
type
/home/julien/local/include/Sire/SireMol/atomid.h:48: warning:
declaration of ‘struct SireMol::Selector<SireMol::Atom>’
/usr/include/qt4/QtCore/qmetatype.h:130: note: neither the destructor
nor the class-specific operator delete will be called, even if they
are declared when the class is defined.
In file included from /home/julien/local/include/Sire/SireSystem/
systemmonitor.h:32,
from /home/julien/local/include/Sire/SireIO/
trajectorymonitor.h:36,
from /home/julien/software/devel/sire/python2/IO/
SireIO_registrars.cpp:6:
/home/julien/local/include/Sire/SireBase/property.h: At global scope:
/home/julien/local/include/Sire/SireBase/property.h: In instantiation
of
‘SireBase::ConcreteProperty<SireMol::Mover<SireMol::Selector<SireMol::Atom>
>, SireMol::Selector<SireMol::Atom> >’:
/home/julien/local/include/Sire/SireMol/mover.hpp:60: instantiated
from ‘SireMol::Mover<SireMol::Selector<SireMol::Atom> >’
/usr/include/qt4/QtCore/qmetatype.h:137: instantiated from ‘void*
qMetaTypeConstructHelper(const T*) [with T =
SireMol::Mover<SireMol::Selector<SireMol::Atom> >]’
/usr/include/qt4/QtCore/qmetatype.h:163: instantiated from ‘int
qRegisterMetaType(const char*, T*) [with T =
SireMol::Mover<SireMol::Selector<SireMol::Atom> >]’
/home/julien/local/include/Sire/SireMol/atom.h:531: instantiated
from here
/home/julien/local/include/Sire/SireBase/property.h:168: error:
invalid use of incomplete type ‘struct
SireMol::Selector<SireMol::Atom>’
/home/julien/local/include/Sire/SireMol/atomid.h:48: error:
declaration of ‘struct SireMol::Selector<SireMol::Atom>’
/home/julien/local/include/Sire/SireBase/property.h: In constructor
‘SireBase::ConcreteProperty<Derived, Base>::ConcreteProperty() [with
Derived = SireMol::Mover<SireMol::Selector<SireMol::Atom> >, Base =
SireMol::Selector<SireMol::Atom>]’:
/home/julien/local/include/Sire/SireMol/mover.hpp:154: instantiated
from ‘SireMol::Mover<T>::Mover() [with T =
SireMol::Selector<SireMol::Atom>]’
/usr/include/qt4/QtCore/qmetatype.h:137: instantiated from ‘void*
qMetaTypeConstructHelper(const T*) [with T =
SireMol::Mover<SireMol::Selector<SireMol::Atom> >]’
/usr/include/qt4/QtCore/qmetatype.h:163: instantiated from ‘int
qRegisterMetaType(const char*, T*) [with T =
SireMol::Mover<SireMol::Selector<SireMol::Atom> >]’
/home/julien/local/include/Sire/SireMol/atom.h:531: instantiated
from here
/home/julien/local/include/Sire/SireBase/property.h:556: error: type
‘SireMol::Selector<SireMol::Atom>’ is not a direct base of
‘SireBase::ConcreteProperty<SireMol::Mover<SireMol::Selector<SireMol::Atom>
>, SireMol::Selector<SireMol::Atom> >’
/home/julien/local/include/Sire/SireBase/property.h: In constructor
‘SireBase::ConcreteProperty<Derived, Base>::ConcreteProperty(const
T0&) [with T0 = SireMol::Mover<SireMol::Selector<SireMol::Atom> >,
Derived = SireMol::Mover<SireMol::Selector<SireMol::Atom> >, Base =
SireMol::Selector<SireMol::Atom>]’:
/home/julien/local/include/Sire/SireMol/mover.hpp:180: instantiated
from ‘SireMol::Mover<T>::Mover(const SireMol::Mover<T>&) [with T =
SireMol::Selector<SireMol::Atom>]’
/usr/include/qt4/QtCore/qmetatype.h:138: instantiated from ‘void*
qMetaTypeConstructHelper(const T*) [with T =
SireMol::Mover<SireMol::Selector<SireMol::Atom> >]’
/usr/include/qt4/QtCore/qmetatype.h:163: instantiated from ‘int
qRegisterMetaType(const char*, T*) [with T =
SireMol::Mover<SireMol::Selector<SireMol::Atom> >]’
/home/julien/local/include/Sire/SireMol/atom.h:531: instantiated
from here
/home/julien/local/include/Sire/SireBase/property.h:562: error: type
‘SireMol::Selector<SireMol::Atom>’ is not a direct base of
‘SireBase::ConcreteProperty<SireMol::Mover<SireMol::Selector<SireMol::Atom>
>, SireMol::Selector<SireMol::Atom> >’
/home/julien/local/include/Sire/SireMaths/constants.h: At global
scope:
/home/julien/local/include/Sire/SireMaths/constants.h:88: warning:
‘SireMaths::smallest’ defined but not used
/home/julien/local/include/Sire/SireMaths/constants.h:97: warning:
‘SireMaths::largest’ defined but not used
make[2]: *** [IO/CMakeFiles/IO.dir/SireIO_registrars.cpp.o] Error 1
make[1]: *** [IO/CMakeFiles/IO.dir/all] Error 2
make: *** [all] Error 2
julien@axon:buildpython2$

Best regards,

Julien

Christopher Woods

unread,
Oct 22, 2010, 11:01:05 AM10/22/10
to sire-de...@googlegroups.com
Hi Julien,

You've included the SireMol/moleditor.h and SireMol/atomeditor.h
header files in amber.h. This is not wrong, but it brings into amber.h
all of the dependencies of moleditor.h and atomeditor.h, with the
exception of selector.hpp (as I have not included selector.hpp
automatically as it has a large number of dependencies of its own).
The solution is to not include these header files in amber.h, and
instead to just declare the names of the classes (as their definitions
are not needed in the header file).

Christopher

Reply all
Reply to author
Forward
0 new messages