Index: kernel/include/base_types.h =================================================================== --- kernel/include/base_types.h (revision 855) +++ kernel/include/base_types.h (working copy) @@ -49,27 +49,22 @@ struct ScoreStateTag {}; struct OptimizerStateTag {}; -typedef Index ParticleIndex; typedef Index RestraintIndex; typedef Index ScoreStateIndex; typedef Index OptimizerStateIndex; +typedef Index ParticleIndex; +typedef std::vector ParticleIndexes; +/* This needs to be here so that both Model and Particle can use Particles */ class Particle; //! A class which is used for representing collections of particles /** - We need this to have a uniform return type for python. - \todo It would be nice to use internal::Vector instead, but that - is not as pretty for Python. + We need this to have a uniform return type for python. + \todo It would be nice to use internal::Vector instead, but that + is not as pretty for Python. */ typedef std::vector Particles; -typedef std::pair ParticlePair; -typedef std::vector ParticlePairs; - -typedef std::vector ParticleIndexes; - -class Particle; - //! The type used to identify float attributes in the Particles IMP_DECLARE_KEY_TYPE(FloatKey, 0); //! The type used to identify int attributes in the Particles Index: kernel/include/Model.h =================================================================== --- kernel/include/Model.h (revision 855) +++ kernel/include/Model.h (working copy) @@ -11,7 +11,9 @@ #include "IMP_config.h" #include "Object.h" +#include "Particle.h" #include "internal/kernel_version_info.h" +#include "container_macros.h" #include "base_types.h" #include "VersionInfo.h" Index: kernel/include/SConscript =================================================================== --- kernel/include/SConscript (revision 855) +++ kernel/include/SConscript (working copy) @@ -7,7 +7,8 @@ 'DecoratorBase.h', 'Vector3D.h', 'UnaryFunction.h', 'PairScore.h', 'SingletonScore.h', 'macros.h', 'TripletScore.h', 'exception.h', 'VersionInfo.h', - 'Object.h', 'Pointer.h', 'RefCountedObject.h', 'ParticleRefiner.h'] + 'Object.h', 'Pointer.h', 'RefCountedObject.h', 'ParticleRefiner.h', + 'container_macros.h'] # Subdirectories files = [File(f) for f in files] \ Index: kernel/include/Particle.h =================================================================== --- kernel/include/Particle.h (revision 855) +++ kernel/include/Particle.h (working copy) @@ -629,6 +629,87 @@ particles_.remove(name); } + +//! A class to store a pair of particles. +/** \note These do not due ref counting currently. SWIG prevents + use of Pointer as the storage type without some + gynmastics. + */ +class ParticlePair { + bool is_default() const {return false;} +public: + typedef ParticlePair This; + Particle *first, *second; + ParticlePair(): first(NULL), second(NULL){} + ParticlePair(Particle *a, Particle *b): + first(a), second(b) {} + IMP_COMPARISONS_2(first, second) + Particle * operator[](unsigned int i) const { + switch (i) { + case 0: + return first; + case 1: + return second; + default: + throw IndexException("Invalid member of pair"); + } + } + Particle *& operator[](unsigned int i) { + switch (i) { + case 0: + return first; + case 1: + return second; + default: + throw IndexException("Invalid member of pair"); + } + } + +}; + +typedef std::vector ParticlePairs; + + + +//! Store three particles +class ParticleTriplet { + bool is_default() const {return false;} +public: + typedef ParticleTriplet This; + Particle *first, *second, *third; + ParticleTriplet(): first(NULL), second(NULL), third(NULL){} + ParticleTriplet(Particle *a, Particle *b, Particle *c): + first(a), second(b), third(c) {} + IMP_COMPARISONS_3(first, second, third) + Particle *operator[](unsigned int i) const { + switch (i) { + case 0: + return first; + case 1: + return second; + case 2: + return third; + default: + throw IndexException("Invalid member of triplet"); + }; + } + Particle *&operator[](unsigned int i) { + switch (i) { + case 0: + return first; + case 1: + return second; + case 2: + return third; + default: + throw IndexException("Invalid member of triplet"); + }; + } + +}; + +typedef std::vector ParticleTriplets; + IMP_END_NAMESPACE #endif /* IMP_PARTICLE_H */ Index: kernel/include/Object.h =================================================================== --- kernel/include/Object.h (revision 855) +++ kernel/include/Object.h (working copy) @@ -63,4 +63,11 @@ IMP_END_NAMESPACE +//! Call the assert_is_valid method in the object base +#define IMP_CHECK_OBJECT(obj) do { \ +IMP_assert(obj != NULL, "NULL object"); \ +(obj)->assert_is_valid(); \ +} while (false) + + #endif /* IMP_OBJECT_H */ Index: kernel/include/Restraint.h =================================================================== --- kernel/include/Restraint.h (revision 855) +++ kernel/include/Restraint.h (working copy) @@ -17,6 +17,7 @@ #include "Pointer.h" #include "log.h" #include "utility.h" +#include "container_macros.h" #include #include Index: kernel/include/ParticleRefiner.h =================================================================== --- kernel/include/ParticleRefiner.h (revision 855) +++ kernel/include/ParticleRefiner.h (working copy) @@ -9,6 +9,7 @@ #include "IMP_config.h" #include "base_types.h" +#include "Particle.h" #include "VersionInfo.h" #include "RefCountedObject.h" Index: kernel/include/macros.h =================================================================== --- kernel/include/macros.h (revision 855) +++ kernel/include/macros.h (working copy) @@ -247,194 +247,4 @@ #define IMP_COPY_CONSTRUCTOR(TC) TC(const TC &o){copy_from(o);} \ TC& operator=(const TC &o) {copy_from(o); return *this;} - - - -/** \internal - */ -#define IMP_CONTAINER_CORE(protection, Ucname, lcname, Data, IndexType,\ - Container) \ - protection: \ - /** \short Add an object. - \param[in] obj Pointer to the object - \return index of object within the object - */ \ - IndexType add_##lcname(Data obj); \ - /** \short Add several objects. - \param[in] obj a vector of pointers - */ \ - void add_##lcname##s(const std::vector& obj); \ - /** \short Clear the contents of the container */ \ - void clear_##lcname##s(); \ - /** \short return the number of objects*/ \ - unsigned int get_number_of_##lcname##s() const { \ - return lcname##_vector_.size();} \ - /** \short Get object refered to by the index - \throws IndexException if the index is out of range - */ \ - Data get_##lcname(IndexType i) const { \ - return lcname##_vector_[i]; \ - } \ - /** \short An iterator through the objects. - The value type is a pointer.*/ \ - typedef Container::iterator Ucname##Iterator; \ - /** \short A const iterator through the objects. - The value type is a pointer.*/ \ - typedef Container::const_iterator Ucname##ConstIterator; \ - Ucname##Iterator lcname##s_begin() {return lcname##_vector_.begin();} \ - Ucname##Iterator lcname##s_end() {return lcname##_vector_.end();} \ - Ucname##ConstIterator lcname##s_begin() const { \ - return lcname##_vector_.begin();} \ - Ucname##ConstIterator lcname##s_end() const { \ - return lcname##_vector_.end();} \ - private: \ - /** \internal */ \ - Container lcname##_vector_; \ - protection: - -/** \internal - */ -#define IMP_CONTAINER_CORE_IMPL(Class, Ucname, lcname, Data, IndexType, \ - Init_obj, Onchanged) \ - IndexType Class::add_##lcname(Data obj) { \ - IndexType index= lcname##_vector_.push_back(obj); \ - Init_obj; \ - Onchanged; \ - if (false) {index=index; obj=obj;}; \ - return index; \ - } \ - void Class::add_##lcname##s(const std::vector &objs) { \ - unsigned int osz= lcname##_vector_.size(); \ - lcname##_vector_.insert(lcname##_vector_.end(), objs.begin(), \ - objs.end()); \ - for (unsigned int i=0; i< objs.size(); ++i) { \ - Data obj= lcname##_vector_[osz+i]; \ - IndexType index(osz+i); \ - Init_obj; \ - if (false) {obj=obj; index=index;} \ - } \ - Onchanged; \ - } \ - /** \short Clear the contents of the container */ \ - void Class::clear_##lcname##s(){ \ - lcname##_vector_.clear(); \ - Onchanged; \ - } \ - - -//! Use this to add a container of IMP objects -/** - Such a container adds public methods add_foo, get_foo, get_number_of_foo - and a private type foo_iterator, with methods foo_begin, foo_end. - \param[in] protection The level of protection for the container. - \param[in] Ucname The name of the type in uppercase - \param[in] lcname The name of the type in lower case - \param[in] Data The type of the data to store. - - \note the type Ucnames must be declared and be a vector of - Data. - */ -#define IMP_LIST(protection, Ucname, lcname, Data) \ - protection: \ - /** \short Remove any occurences of d from the container */ \ - void erase_##lcname(Data d); \ - /** \short Get a container of all the objects. - This is for Python as the container can be used like a Python list*/\ - const Ucname##s &get_##lcname##s() const { \ - return static_cast< const Ucname##s &>(lcname##_vector_); \ - } \ - void set_##lcname##s(const Ucname##s &ps) { \ - clear_##lcname##s(); \ - add_##lcname##s(ps); \ - } \ - IMP_CONTAINER_CORE(protection, Ucname, lcname, Data, unsigned int, \ - IMP::internal::Vector) - - - -//! Use this to add a container of IMP objects -/** - This code should go in a .cpp file. One macro for each IMP_CONTAINER. - \param[in] init Code to modify the passed in object. The object is obj - its index index. - \param[in] OnChanged Code to get executed when the container changes. - */ -#define IMP_LIST_IMPL(Class, Ucname, lcname, Data, init, OnChanged) \ - IMP_CONTAINER_CORE_IMPL(Class, Ucname, lcname, Data, unsigned int, \ - init, OnChanged) \ - /** \short Remove any occurences of d from the container */ \ - void Class::erase_##lcname(Data d) { \ - for (Ucname##Iterator it= lcname##s_begin(); \ - it != lcname##s_end(); ++it) { \ - if (*it == d) { \ - lcname##_vector_.erase(it); break; \ - } \ - } \ - OnChanged; \ - } \ - - - -//! Use this to add a set of IMP objects owned by the containing one -/** - Such a container adds public methods add_foo, get_foo, get_number_of_foo - and a private type foo_iterator, with methods foo_begin, foo_end. - \param[in] Ucname The name of the type in uppercase - \param[in] lcname The name of the type in lower case - \param[in] IndexType The type to use for the index. This should be - an instantiation of Index or something similar. - - \note The type Ucnames must be declared and be a vector of - Data. - \note these containers are always public -*/ -#define IMP_CONTAINER(Ucname, lcname, IndexType) \ - public: \ - void remove_##lcname(IndexType i) ; \ -private: \ -/** \internal - This is an implementation detail.*/ \ -typedef IMP::internal::ObjectContainer \ -Ucname##Container; \ -IMP_CONTAINER_CORE(public, Ucname, lcname, Ucname*, IndexType, \ - Ucname##Container) - - - -//! Use this to add a container of IMP objects -/** - This code should go in a .cpp file. One macro for each - IMP_CONTAINER. - \param[in] init Code to modify the passed in object. The object is obj - its index index. - \param[in] onchanged Code to execute when the container is changed. - \param[in] onremove Code to execute when an object is removed. The object - being removed is obj. - */ -#define IMP_CONTAINER_IMPL(Class, Ucname, lcname, IndexType, init, \ -onchanged, onremove) \ - void Class::remove_##lcname(IndexType i) { \ - Ucname* obj= lcname##_vector_[i]; \ - onremove; \ - lcname##_vector_.remove(i); \ - if (false) std::cout << *obj; \ - } \ - IMP_CONTAINER_CORE_IMPL(Class, Ucname, lcname, Ucname*, IndexType, \ - init,onchanged) - - - -//! Call the assert_is_valid method in the object base -#define IMP_CHECK_OBJECT(obj) do { \ - IMP_assert(obj != NULL, "NULL object"); \ - (obj)->assert_is_valid(); \ - } while (false) - - -// They use IMP_CHECK_OBJECT and so must be included at the end - -#include "internal/Vector.h" -#include "internal/ObjectContainer.h" - - #endif /* IMP_MACROS_H */ Index: kernel/include/internal/ExponentialNumber.h =================================================================== --- kernel/include/internal/ExponentialNumber.h (revision 855) +++ kernel/include/internal/ExponentialNumber.h (working copy) @@ -10,6 +10,7 @@ #define IMP_EXPONENTIAL_NUMBER_H #include "../macros.h" +#include "../base_types.h" #include #include Index: kernel/include/container_macros.h =================================================================== --- kernel/include/container_macros.h (revision 0) +++ kernel/include/container_macros.h (revision 0) @@ -0,0 +1,188 @@ +/* + * \file container_macros.h + * \brief Macros to define containers of objects + * + * Copyright 2007-8 Sali Lab. All rights reserved. + * + */ + +#ifndef IMP_INTERNAL_CONTAINER_MACROS_H +#define IMP_INTERNAL_CONTAINER_MACROS_H + +#include "internal/Vector.h" +#include "internal/ObjectContainer.h" +#include "macros.h" + +/** \internal + */ +#define IMP_CONTAINER_CORE(protection, Ucname, lcname, Data, IndexType,\ +Container) \ +protection: \ +/** \short Add an object. +\param[in] obj Pointer to the object +\return index of object within the object +*/ \ +IndexType add_##lcname(Data obj); \ +/** \short Add several objects. +\param[in] obj a vector of pointers +*/ \ +void add_##lcname##s(const std::vector& obj); \ +/** \short Clear the contents of the container */ \ +void clear_##lcname##s(); \ +/** \short return the number of objects*/ \ +unsigned int get_number_of_##lcname##s() const { \ +return lcname##_vector_.size();} \ +/** \short Get object refered to by the index +\throws IndexException if the index is out of range +*/ \ +Data get_##lcname(IndexType i) const { \ +return lcname##_vector_[i]; \ +} \ +/** \short An iterator through the objects. +The value type is a pointer.*/ \ +typedef Container::iterator Ucname##Iterator; \ +/** \short A const iterator through the objects. +The value type is a pointer.*/ \ +typedef Container::const_iterator Ucname##ConstIterator; \ +Ucname##Iterator lcname##s_begin() {return lcname##_vector_.begin();} \ +Ucname##Iterator lcname##s_end() {return lcname##_vector_.end();} \ +Ucname##ConstIterator lcname##s_begin() const { \ +return lcname##_vector_.begin();} \ +Ucname##ConstIterator lcname##s_end() const { \ +return lcname##_vector_.end();} \ +private: \ +/** \internal */ \ +Container lcname##_vector_; \ +protection: + +/** \internal + */ +#define IMP_CONTAINER_CORE_IMPL(Class, Ucname, lcname, Data, IndexType, \ +Init_obj, Onchanged) \ +IndexType Class::add_##lcname(Data obj) { \ +IndexType index= lcname##_vector_.push_back(obj); \ +Init_obj; \ +Onchanged; \ +if (false) {index=index; obj=obj;}; \ +return index; \ +} \ +void Class::add_##lcname##s(const std::vector &objs) { \ +unsigned int osz= lcname##_vector_.size(); \ +lcname##_vector_.insert(lcname##_vector_.end(), objs.begin(), \ +objs.end()); \ +for (unsigned int i=0; i< objs.size(); ++i) { \ +Data obj= lcname##_vector_[osz+i]; \ +IndexType index(osz+i); \ +Init_obj; \ +if (false) {obj=obj; index=index;} \ +} \ +Onchanged; \ +} \ +/** \short Clear the contents of the container */ \ +void Class::clear_##lcname##s(){ \ +lcname##_vector_.clear(); \ +Onchanged; \ +} \ + + +//! Use this to add a container of IMP objects +/** + Such a container adds public methods add_foo, get_foo, get_number_of_foo + and a private type foo_iterator, with methods foo_begin, foo_end. + \param[in] protection The level of protection for the container. + \param[in] Ucname The name of the type in uppercase + \param[in] lcname The name of the type in lower case + \param[in] Data The type of the data to store. + + \note the type Ucnames must be declared and be a vector of + Data. + */ +#define IMP_LIST(protection, Ucname, lcname, Data) \ +protection: \ +/** \short Remove any occurences of d from the container */ \ +void erase_##lcname(Data d); \ +/** \short Get a container of all the objects. +This is for Python as the container can be used like a Python list*/\ +const Ucname##s &get_##lcname##s() const { \ +return static_cast< const Ucname##s &>(lcname##_vector_); \ +} \ +void set_##lcname##s(const Ucname##s &ps) { \ +clear_##lcname##s(); \ +add_##lcname##s(ps); \ +} \ +IMP_CONTAINER_CORE(protection, Ucname, lcname, Data, unsigned int, \ +IMP::internal::Vector) + + + +//! Use this to add a container of IMP objects +/** + This code should go in a .cpp file. One macro for each IMP_CONTAINER. + \param[in] init Code to modify the passed in object. The object is obj + its index index. + \param[in] OnChanged Code to get executed when the container changes. + */ +#define IMP_LIST_IMPL(Class, Ucname, lcname, Data, init, OnChanged) \ +IMP_CONTAINER_CORE_IMPL(Class, Ucname, lcname, Data, unsigned int, \ +init, OnChanged) \ +/** \short Remove any occurences of d from the container */ \ +void Class::erase_##lcname(Data d) { \ +for (Ucname##Iterator it= lcname##s_begin(); \ +it != lcname##s_end(); ++it) { \ +if (*it == d) { \ +lcname##_vector_.erase(it); break; \ +} \ +} \ +OnChanged; \ +} \ + + + +//! Use this to add a set of IMP objects owned by the containing one +/** + Such a container adds public methods add_foo, get_foo, get_number_of_foo + and a private type foo_iterator, with methods foo_begin, foo_end. + \param[in] Ucname The name of the type in uppercase + \param[in] lcname The name of the type in lower case + \param[in] IndexType The type to use for the index. This should be + an instantiation of Index or something similar. + + \note The type Ucnames must be declared and be a vector of + Data. + \note these containers are always public + */ +#define IMP_CONTAINER(Ucname, lcname, IndexType) \ +public: \ +void remove_##lcname(IndexType i) ; \ +private: \ +/** \internal +This is an implementation detail.*/ \ +typedef IMP::internal::ObjectContainer \ +Ucname##Container; \ +IMP_CONTAINER_CORE(public, Ucname, lcname, Ucname*, IndexType, \ +Ucname##Container) + + + +//! Use this to add a container of IMP objects +/** + This code should go in a .cpp file. One macro for each + IMP_CONTAINER. + \param[in] init Code to modify the passed in object. The object is obj + its index index. + \param[in] onchanged Code to execute when the container is changed. + \param[in] onremove Code to execute when an object is removed. The object + being removed is obj. + */ +#define IMP_CONTAINER_IMPL(Class, Ucname, lcname, IndexType, init, \ +onchanged, onremove) \ +void Class::remove_##lcname(IndexType i) { \ +Ucname* obj= lcname##_vector_[i]; \ +onremove; \ +lcname##_vector_.remove(i); \ +if (false) std::cout << *obj; \ +} \ +IMP_CONTAINER_CORE_IMPL(Class, Ucname, lcname, Ucname*, IndexType, \ +init,onchanged) + +#endif Property changes on: kernel/include/container_macros.h ___________________________________________________________________ Added: svn:mergeinfo Index: kernel/pyext/IMP_macros.i =================================================================== --- kernel/pyext/IMP_macros.i (revision 855) +++ kernel/pyext/IMP_macros.i (working copy) @@ -53,3 +53,4 @@ %enddef %include "IMP/macros.h" +%include "IMP/container_macros.h" Index: kernel/pyext/IMP.i =================================================================== --- kernel/pyext/IMP.i (revision 855) +++ kernel/pyext/IMP.i (working copy) @@ -15,6 +15,31 @@ %include "typemaps.i" +%ignore IMP::ParticlePair::operator[]; +%ignore IMP::ParticleTriplet::operator[]; +%extend IMP::ParticlePair { + Particle* __getitem__(unsigned int index) const { + return self->operator[](index); + } + void __setitem__(unsigned int index, Particle* val) { + self->operator[](index) = val; + } + int __len__() const { + return 2; + } +} +%extend IMP::ParticleTriplet { + Particle* __getitem__(unsigned int index) const { + return self->operator[](index); + } + void __setitem__(unsigned int index, Particle* val) { + self->operator[](index) = val; + } + int __len__() const { + return 3; + } +} + namespace IMP { %typemap(out) std::pair { PyObject *tup= PyTuple_New(2); @@ -124,8 +149,8 @@ %template(OptimizerStateIndex) Index; %template(Particles) ::std::vector; %template(ParticlesList) ::std::vector; - %template(ParticlePair) ::std::pair; %template(ParticlePairs) ::std::vector; + %template(ParticleTriplets) ::std::vector; %template(Restraints) ::std::vector; %template(ScoreStates) ::std::vector; %template(OptimizerStates) ::std::vector;