9 #ifndef IMPCORE_HIERARCHY_H
10 #define IMPCORE_HIERARCHY_H
12 #include <IMP/core/core_config.h>
13 #include "internal/hierarchy_helpers.h"
20 #include <IMP/internal/utility.h>
23 #include <boost/tuple/tuple.hpp>
24 #include <cereal/access.hpp>
29 #include <cereal/access.hpp>
30 #include <cereal/types/base_class.hpp>
32 IMPCORE_BEGIN_NAMESPACE
54 friend class cereal::access;
55 template<
class Archive>
void serialize(Archive &ar) {
56 ar(children_, parent_);
66 return parent_ == o.parent_;
87 friend class cereal::access;
88 template<
class Archive>
void serialize(Archive &ar) {
89 ar(cereal::base_class<Decorator>(
this), traits_);
97 for (
unsigned int i = 0; i < children.size(); ++i) {
105 do_setup_particle(m, pi,
get_indexes(children), traits);
109 void update_changed_trigger()
const {
115 traits, get_default_traits());
135 if (
get_model()->get_has_attribute(get_decorator_traits().get_parent_key(),
145 unsigned int get_number_of_children()
const {
156 Hierarchy get_child(
unsigned int i)
const {
157 IMP_USAGE_CHECK(i < get_number_of_children(),
"Invalid child requested");
159 get_decorator_traits().get_children_key(),
161 get_decorator_traits());
164 IMP_USAGE_CHECK(i < get_number_of_children(),
"Invalid child requested");
168 ParticleIndexes get_children_indexes()
const {
174 return ParticleIndexes();
177 GenericHierarchies get_children()
const {
178 GenericHierarchies ret(get_number_of_children());
179 for (
unsigned int i = 0; i < ret.size(); ++i) {
180 ret[i] = get_child(i);
184 void remove_child(
unsigned int i) {
185 IMP_USAGE_CHECK(i < get_number_of_children(),
"Invalid child requested");
186 Hierarchy c = get_child(i);
187 ParticleIndexes &pis =
get_model()->access_attribute(
189 pis.erase(pis.begin() + i);
191 c.get_particle_index());
192 update_changed_trigger();
194 void remove_child(Hierarchy h) { remove_child(h.get_child_index()); }
195 void clear_children() {
196 ParticleIndexes &pis =
get_model()->access_attribute(
198 for (
unsigned int i = 0; i < pis.size(); ++i) {
204 update_changed_trigger();
206 void add_child(Hierarchy h)
const {
210 ->access_attribute(get_decorator_traits().get_children_key(),
212 .push_back(h.get_particle_index());
216 ParticleIndexes(1, h.get_particle_index()));
220 update_changed_trigger();
222 void add_child_at(Hierarchy h,
unsigned int pos) {
226 ParticleIndexes &pis =
get_model()->access_attribute(
228 pis.insert(pis.begin() + pos, h.get_particle_index());
232 ParticleIndexes(1, h.get_particle_index()));
236 update_changed_trigger();
239 int get_child_index()
const;
241 static const HierarchyTraits &get_default_traits();
243 HierarchyTraits get_traits() {
return get_decorator_traits(); }
256 virtual bool operator()(
Hierarchy p) = 0;
279 #if !defined(SWIG) && !defined(IMP_DOXYGEN)
281 template <
class H,
class F,
class Out,
bool Slice = false>
284 Gather(F f, Out out) : f_(f), out_(out) {}
285 bool operator()(H p) {
289 if (Slice)
return false;
294 Out get_out()
const {
return out_; }
310 template <
class HD,
class F>
312 std::deque<HD> stack;
316 HD cur = stack.front();
320 for (
int i = cur.get_number_of_children() - 1; i >= 0; --i) {
321 stack.push_back(cur.get_child(i));
324 }
while (!stack.empty());
333 template <
class HD,
class F>
339 HD cur = stack.back();
343 for (
int i = cur.get_number_of_children() - 1; i >= 0; --i) {
344 stack.push_back(cur.get_child(i));
347 }
while (!stack.empty());
376 template <
class HD,
class F>
378 typename F::result_type data) {
379 typedef std::pair<typename F::result_type, HD> DP;
380 std::deque<DP> stack;
381 stack.push_back(DP(data, d));
384 DP cur = stack.front();
386 typename F::result_type r = f(cur.second.get_particle(), cur.first);
388 for (
int i = cur.second.get_number_of_children() - 1; i >= 0; --i) {
389 stack.push_back(std::make_pair(r, cur.second.get_child(i)));
391 }
while (!stack.empty());
400 template <
class HD,
class F>
402 typedef std::pair<typename F::result_type, HD> DP;
404 stack.push_back(DP(data, d));
407 DP cur = stack.back();
409 typename F::result_type r = f(cur.second, cur.first);
411 for (
int i = cur.second.get_number_of_children() - 1; i >= 0; --i) {
412 stack.push_back(DP(r, cur.second.get_child(i)));
414 }
while (!stack.empty());
424 IMP_PRINT_TREE(out,
Hierarchy, h, n.get_number_of_children(), n.get_child,
448 friend class cereal::access;
450 template<
class Archive>
void serialize(Archive &ar) {
471 template <
class H,
class Out,
class F>
473 internal::Gather<H, F, Out>
gather(f, out);
475 return gather.get_out();
485 template <
class H,
class Out,
class F>
487 internal::Gather<H, F, Out, true>
gather(f, out);
489 return gather.get_out();
496 template <
class H,
class Out,
class K,
class V>
498 internal::Gather<H, internal::MatchAttribute<K, V>, Out>
gather(
499 internal::MatchAttribute<K, V>(k, v), out);
501 return gather.get_out();
508 template <
class H,
class Out,
class K0,
class V0,
class K1,
class V1>
510 internal::Gather<H, internal::MatchAttributes<K0, V0, K1, V1>, Out>
gather(
511 internal::MatchAttributes<K0, V0, K1, V1>(k0, v0, k1, v1), out);
513 return gather.get_out();
520 template <
class HD,
class F>
522 if (f(h.get_particle()))
return h;
527 HD cur = stack.back();
530 for (
int i = cur.get_number_of_children() - 1; i >= 0; --i) {
531 HD hd = cur.get_child(i);
532 if (f(hd.get_particle())) {
538 }
while (!stack.empty());
548 IMPCOREEXPORT GenericHierarchies
get_leaves(Hierarchy mhd);
553 IMPCOREEXPORT GenericHierarchies
get_internal(Hierarchy mhd);
569 IMPCORE_END_NAMESPACE
F visit_breadth_first(HD d, F f)
Apply the visitor to each particle, breadth first.
The base class for decorators.
A base class for modifiers of ParticlesTemp.
A visitor for traversal of a hierarchy.
A Modifier on ParticlesTemp.
ParticleIndex get_particle_index() const
Returns the particle index decorated by this decorator.
#define IMP_SHOWABLE_INLINE(Name, how_to_show)
Declare the methods needed by an object that can be printed.
static bool get_is_setup(Model *, ParticleIndex, HierarchyTraits=Hierarchy::get_default_traits())
F visit_depth_first(HD d, F &f)
Apply functor F to each particle, traversing the hierarchy depth first.
bool operator()(Hierarchy) override
Increment the counter.
Model * get_model() const
Returns the Model containing the particle.
Storage of a model, its restraints, constraints and particles.
HD find_breadth_first(HD h, F f)
Find the first node which matches some criteria.
void remove_attribute(TypeKey attribute_key, ParticleIndex particle)
remove particle attribute with the specified key
Index< ParticleIndexTag > ParticleIndex
#define IMP_DECORATOR_TRAITS_SETUP_1(Name, FirstArgumentType,first_argument_name)
A more IMP-like version of the std::vector.
GenericHierarchies get_all_descendants(Hierarchy mhd)
Get all the particles in the subtree.
A visitor which applies a modifier to each Particle in a hierarchy.
Class for storing model, its restraints, constraints, and particles.
Out gather_by_attributes(H h, K0 k0, V0 v0, K1 k1, V1 v1, Out out)
Gather all the particles in the hierarchy which match on two attributes.
virtual bool operator()(Hierarchy p) override
Return true if the traversal should visit this node's children.
#define IMP_VALUES(Name, PluralName)
Define the type for storing sets of values.
F visit_depth_first_with_data(HD d, F f, typename F::result_type data)
Apply functor F to each particle, traversing the hierarchy depth first.
Hierarchy get_root(Hierarchy h)
Return the root of the hierarchy.
Hierarchy get_parent() const
void add_attribute(TypeKey attribute_key, ParticleIndex particle, Type value)
add particle attribute with the specified key and initial value
F visit_breadth_first_with_data(HD d, F f, typename F::result_type data)
Apply functor F to each particle, traversing the hierarchy breadth first.
Out gather_slice(H h, F f, Out out)
Gather all the uppermost particles in the hierarchy that meet some criteria.
A simple functor to count the number of particles in a hierarchy.
Define the type for a type of hierarchy.
Helper macros for implementing Decorators.
A smart pointer to a ref-counted Object that is a class member.
#define IMP_DECORATOR_TRAITS_SETUP_0(Name)
Out gather(H h, F f, Out out)
Gather all the particles in the hierarchy that meet some criteria.
Out gather_by_attribute(H h, K k, V v, Out out)
Gather all the particles in the hierarchy which match on an attribute.
GenericHierarchies get_internal(Hierarchy mhd)
Get all the non-leaves of the bit of hierarchy.
Interface to specialized Particle types (e.g. atoms)
Classes to handle individual model particles. (Note that implementation of inline functions is in int...
#define IMP_DECORATOR_WITH_TRAITS_METHODS(Name, Parent, TraitsType,traits_name, default_traits)
void show(Hierarchy h, std::ostream &out=std::cout)
Print out a molecular hierarchy.
A nullptr-initialized pointer to an IMP Object.
unsigned int get_count() const
Return how many nodes have been visited.
#define IMP_USAGE_CHECK(expr, message)
A runtime test for incorrect usage of a class or method.
A decorator for helping deal with a generalized hierarchy.
void set_trigger_updated(TriggerKey tk)
Update the given trigger.
Hierarchies get_leaves(Hierarchy h)
Type get_attribute(TypeKey attribute_key, ParticleIndex particle)
get the value of the particle attribute with the specified key
ParticleIndexes get_indexes(const ParticlesTemp &ps)
Get the indexes from a list of particles.