Index: kernel/test/modeller/test_pdb_read.py =================================================================== --- kernel/test/modeller/test_pdb_read.py (revision 347) +++ kernel/test/modeller/test_pdb_read.py (working copy) @@ -22,6 +22,12 @@ IMP.depth_first_traversal(mp, hc) f_num_res_type= IMP.ResidueType.get_number_unique() f_num_atom_type= IMP.AtomType.get_number_unique() + mpp= mp.get_parent() + self.assertEqual(mpp, IMP.MolecularHierarchyDecorator(), + "Should not have a parent") + mpc= mp.get_child(0) + self.assertEqual(mpc.get_parent(), mp, + "Should not have a parent") #print str(hc.get_count()) self.assertEqual(i_num_res_type, f_num_res_type, "too many residue types") self.assertEqual(i_num_atom_type, f_num_atom_type, "too many atom types") Index: kernel/include/IMP/utility.h =================================================================== --- kernel/include/IMP/utility.h (revision 347) +++ kernel/include/IMP/utility.h (working copy) @@ -300,7 +300,10 @@ lcname##_vector_.clear(); //! Call the assert_is_valid method in the object base -#define IMP_CHECK_OBJECT(obj) (obj)->assert_is_valid() +#define IMP_CHECK_OBJECT(obj) do { \ + IMP_assert(obj != NULL, "NULL object"); \ + (obj)->assert_is_valid(); \ + } while (false) namespace IMP { Index: kernel/include/IMP/DecoratorBase.h =================================================================== --- kernel/include/IMP/DecoratorBase.h (revision 347) +++ kernel/include/IMP/DecoratorBase.h (working copy) @@ -1,5 +1,5 @@ /** - * \file decorators/DecoratorBase.h \brief The base class for decorators. + * \file DecoratorBase.h \brief The base class for decorators. * * Copyright 2007-8 Sali Lab. All rights reserved. * @@ -8,6 +8,8 @@ #ifndef __IMP_DECORATOR_BASE_H #define __IMP_DECORATOR_BASE_H +#include "Object.h" + namespace IMP { @@ -35,10 +37,13 @@ /** \return the particle wrapped by this decorator*/ Particle *get_particle() const { + IMP_CHECK_OBJECT(particle_); return particle_; } /** \return the Model containing the particle */ Model *get_model() const { + IMP_CHECK_OBJECT(particle_); + IMP_CHECK_OBJECT(particle_->get_model()); return particle_->get_model(); } @@ -48,6 +53,7 @@ */ template static D cast(Particle *p) { + IMP_CHECK_OBJECT(p); D:: decorator_initialize_static_data(); IMP_check(D::has_required_attributes(p), "Attempting to cast a Particle which does not have" @@ -62,6 +68,7 @@ */ template static D create(Particle *p) { + IMP_CHECK_OBJECT(p); D::decorator_initialize_static_data(); D::add_required_attributes(p); return D(p); Index: kernel/include/IMP/decorators/HierarchyDecorator.h =================================================================== --- kernel/include/IMP/decorators/HierarchyDecorator.h (revision 347) +++ kernel/include/IMP/decorators/HierarchyDecorator.h (working copy) @@ -22,8 +22,14 @@ { +/** \defgroup hierarchy Hierarchies of particles + These functions and classes aid in manipulating particles representing + molecules at multiple levels. + */ + //! A visitor for traversal of a hierarchy /** This works from both C++ and Python + \ingroup hierarchy */ class IMPDLLEXPORT HierarchyVisitor { @@ -39,6 +45,8 @@ //! A decorator for helping deal with a hierarchy. +/** \ingroup hierarchy + */ class IMPDLLEXPORT HierarchyDecorator: public DecoratorBase { IMP_DECORATOR(HierarchyDecorator, DecoratorBase, return true || p, ++p); @@ -111,15 +119,15 @@ //! Apply the visitor to each particle, breadth first. /** \param[in] d The HierarchyDecorator for the tree in question - \param[in] f The functor to be applied. This is passed by value - \return A copy of the functor passed in. Use this if you care about - the functor state. + \param[in] v The visitor to be applied. This is passed by reference. + \ingroup hierarchy */ IMPDLLEXPORT void breadth_first_traversal(HierarchyDecorator d, HierarchyVisitor &v); //! Depth first traversal of the hierarchy /** See breadth_first_traversal and HierarchyVisitor for more information + \ingroup hierarchy */ IMPDLLEXPORT void depth_first_traversal(HierarchyDecorator d, HierarchyVisitor &v); @@ -146,6 +154,8 @@ \return A copy of the functor passed in. Use this if you care about the functor state. + + \ingroup hierarchy */ template F breadth_first_traversal_with_data(HD d, F f, typename F::result_type i) @@ -169,6 +179,7 @@ //! Apply functor F to each particle, traversing the hierarchy depth first. /** See breadth_first_traversal for documentation. + \ingroup hierarchy */ template F depth_first_traversal_with_data(HD d, F f, typename F::result_type i) @@ -194,6 +205,7 @@ //! A simple visitor which pretty-prints the hierarchy /** The template argument NP is the decorator to use to print each node. + \ingroup hierarchy */ template struct HierarchyPrinter @@ -233,6 +245,7 @@ //! Print the hierarchy using a given decorator as to display each node /** The last argument limits how deep will be printed out. + \ingroup hierarchy */ template std::ostream &show(HierarchyDecorator h, std::ostream &out=std::cout, @@ -246,6 +259,7 @@ //! A simple functor to count the number of particles in a hierarchy. /** This is a good example of a simple HierarchyVisitor. + \ingroup hierarchy */ struct HierarchyCounter: public HierarchyVisitor { @@ -290,6 +304,8 @@ } // namespace internal //! Gather all the Particle* in the hierarchy which meet some criteria +/** \ingroup hierarchy + */ template Out hierarchy_gather(HierarchyDecorator h, F f, Out out) { Index: kernel/include/IMP/decorators/MolecularHierarchyDecorator.h =================================================================== --- kernel/include/IMP/decorators/MolecularHierarchyDecorator.h (revision 347) +++ kernel/include/IMP/decorators/MolecularHierarchyDecorator.h (working copy) @@ -21,6 +21,8 @@ { //! A decorator for helping deal with a hierarchy of molecules +/** \ingroup hierarchy + */ class IMPDLLEXPORT MolecularHierarchyDecorator: public HierarchyDecorator { IMP_DECORATOR(MolecularHierarchyDecorator, @@ -108,7 +110,7 @@ //! Get the parent MolecularHierarchyDecorator get_parent() const { HierarchyDecorator hd= P::get_parent(); - if (hd != HierarchyDecorator()) { + if (hd == HierarchyDecorator()) { return MolecularHierarchyDecorator(); } else { return cast(hd.get_particle()); @@ -121,6 +123,7 @@ /** Gather all the molecular particles of a certain level in the molecular hierarchy + \ingroup hierarchy */ IMPDLLEXPORT Particles get_particles(MolecularHierarchyDecorator mhd, MolecularHierarchyDecorator::Type t); Index: kernel/src/restraints/NonbondedRestraint.cpp =================================================================== --- kernel/src/restraints/NonbondedRestraint.cpp (revision 347) +++ kernel/src/restraints/NonbondedRestraint.cpp (working copy) @@ -27,7 +27,7 @@ Float NonbondedRestraint::evaluate(DerivativeAccumulator *accum) { - IMP_CHECK_OBJECT(sf_); + IMP_CHECK_OBJECT(sf_.get()); IMP_CHECK_OBJECT(nbl_); Float score=0; Index: kernel/src/decorators/MolecularHierarchyDecorator.cpp =================================================================== --- kernel/src/decorators/MolecularHierarchyDecorator.cpp (revision 347) +++ kernel/src/decorators/MolecularHierarchyDecorator.cpp (working copy) @@ -21,6 +21,10 @@ void MolecularHierarchyDecorator::show(std::ostream &out, std::string prefix) const { + if (is_default()) { + out << "NULL Molecular Hierarchy node"; + return; + } if (get_type() == ATOM) { AtomDecorator ad= AtomDecorator::cast(get_particle()); if (ad != AtomDecorator()) {