IMP  2.2.1
The Integrative Modeling Platform
ConsecutivePairContainer.h
Go to the documentation of this file.
1 /**
2  * \file IMP/container/ConsecutivePairContainer.h
3  * \brief Return all pairs from a SingletonContainer
4  *
5  * Copyright 2007-2014 IMP Inventors. All rights reserved.
6  */
7 
8 #ifndef IMPCONTAINER_CONSECUTIVE_PAIR_CONTAINER_H
9 #define IMPCONTAINER_CONSECUTIVE_PAIR_CONTAINER_H
10 
11 #include <IMP/container/container_config.h>
12 #include <IMP/generic.h>
13 #include <IMP/PairContainer.h>
14 #include <IMP/PairPredicate.h>
15 #include <IMP/SingletonContainer.h>
17 #include <boost/unordered_map.hpp>
18 #include <IMP/pair_macros.h>
19 
20 IMPCONTAINER_BEGIN_NAMESPACE
21 
22 //! A container which contains all consecutive pairs from an input list
23 // of particles
24 /** If it is assumed that each particle is in at most one such container,
25  then ExclusiveConsecutivePairContainer should be used instead,
26  since it is faster when doing certain computations.
27 
28  Also see ConsecutivePairFilter.
29 */
30 class IMPCONTAINEREXPORT ConsecutivePairContainer : public PairContainer {
31  friend class ConsecutivePairFilter;
32  const kernel::ParticleIndexes ps_;
33  IntKey key_;
34  /**
35  add the key of this container as an attribute to all particles
36  if there might be ovrlaps - create a different keys for each instance
37  */
38  void init();
39 
40  bool get_contains(const kernel::ParticleIndexPair &p) const {
41  if (!get_model()->get_has_attribute(key_, p[0])) return false;
42  int ia = get_model()->get_attribute(key_, p[0]);
43  if (!get_model()->get_has_attribute(key_, p[1])) return false;
44  int ib = get_model()->get_attribute(key_, p[1]);
45  return std::abs(ia - ib) == 1;
46  }
47 
48  protected:
49  virtual std::size_t do_get_contents_hash() const IMP_OVERRIDE { return 0; }
50 
51  public:
52  //! apply to each item in container
53  template <class F>
54  void apply_generic(F *f) const {
55  for (unsigned int i = 1; i < ps_.size(); ++i) {
56  f->apply_index(get_model(),
57  kernel::ParticleIndexPair(ps_[i - 1], ps_[i]));
58  }
59  }
60  //! Get the individual particles from the passed SingletonContainer
62  std::string name = "ConsecutivePairContainer%1%");
63  virtual kernel::ParticleIndexPairs get_indexes() const IMP_OVERRIDE;
64  virtual kernel::ParticleIndexPairs get_range_indexes() const IMP_OVERRIDE;
65  virtual kernel::ModelObjectsTemp do_get_inputs() const IMP_OVERRIDE;
66  virtual kernel::ParticleIndexes get_all_possible_indexes() const IMP_OVERRIDE;
68  IMP_OBJECT_METHODS(ConsecutivePairContainer);
69 };
70 
71 IMP_OBJECTS(ConsecutivePairContainer, ConsecutivePairContainers);
72 
73 /** Check for whether the pair is a member of a specific
74  ConsecutivePairContainer. */
75 class IMPCONTAINEREXPORT ConsecutivePairFilter : public PairPredicate {
77 
78  public:
79  ConsecutivePairFilter(ConsecutivePairContainer *cpc);
80 
82  const kernel::ParticleIndexPair &pip) const
83  IMP_OVERRIDE {
84  return cpc_->get_contains(pip);
85  }
87  kernel::Model *m, const kernel::ParticleIndexes &pi) const IMP_OVERRIDE {
89  ret += IMP::get_particles(m, pi);
90  return ret;
91  }
94 };
95 
96 /** This is an ConsecutivePairContainer where each particle can only be on
97  one ExclusiveConsecutivePairContainer. The exclusivity makes the code
98  more efficient and allows one to use the ExclusiveConsecutivePairFilter,
99  which is way more efficient than using an InContainerPairFilter
100  with a ConsecutivePairContainer.*/
101 class IMPCONTAINEREXPORT ExclusiveConsecutivePairContainer
102  : public PairContainer {
103  friend class ExclusiveConsecutivePairFilter;
104  const kernel::ParticleIndexes ps_;
105  static IntKey get_exclusive_key() {
106  static IntKey k("exclusive consecutive numbering");
107  return k;
108  }
109  static ObjectKey get_exclusive_object_key() {
110  static ObjectKey k("exclusive consecutive container");
111  return k;
112  }
113  static bool get_contains(kernel::Model *m,
114  const kernel::ParticleIndexPair &pp) {
115  ObjectKey ok =
116  ExclusiveConsecutivePairContainer::get_exclusive_object_key();
117  if (!m->get_has_attribute(ok, pp[0]) || !m->get_has_attribute(ok, pp[1]))
118  return false;
119  if (m->get_attribute(ok, pp[0]) != m->get_attribute(ok, pp[1])) {
120  return false;
121  }
122  IntKey k = ExclusiveConsecutivePairContainer::get_exclusive_key();
123  int ia = m->get_attribute(k, pp[0]);
124  int ib = m->get_attribute(k, pp[1]);
125  return std::abs(ia - ib) == 1;
126  }
127  void init();
128 
129  protected:
130  virtual std::size_t do_get_contents_hash() const IMP_OVERRIDE { return 0; }
131 
132  public:
133  //! apply to each item in container
134  template <class F>
135  void apply_generic(F *f) const {
136  for (unsigned int i = 1; i < ps_.size(); ++i) {
137  f->apply_index(get_model(),
138  kernel::ParticleIndexPair(ps_[i - 1], ps_[i]));
139  }
140  }
141 
142  //! Get the individual particles from the passed SingletonContainer
144  std::string name =
145  "ExclusiveConsecutivePairContainer%1%");
146  virtual kernel::ParticleIndexPairs get_indexes() const IMP_OVERRIDE;
147  virtual kernel::ParticleIndexPairs get_range_indexes() const IMP_OVERRIDE;
148  virtual kernel::ModelObjectsTemp do_get_inputs() const IMP_OVERRIDE;
149  virtual kernel::ParticleIndexes get_all_possible_indexes() const IMP_OVERRIDE;
151  IMP_OBJECT_METHODS(ExclusiveConsecutivePairContainer);
152 };
153 
154 /** Check for whether the pair is a member of any
155  ExclusiveConsecutivePairContainer. */
156 class IMPCONTAINEREXPORT ExclusiveConsecutivePairFilter : public PairPredicate {
157  public:
159  : PairPredicate("ExclusiveConsecutivePairFilter %1%") {}
160 
162  const kernel::ParticleIndexPair &pip) const
163  IMP_OVERRIDE {
164  return ExclusiveConsecutivePairContainer::get_contains(m, pip);
165  }
167  kernel::Model *m, const kernel::ParticleIndexes &pi) const IMP_OVERRIDE {
169  ret += IMP::get_particles(m, pi);
170  return ret;
171  }
174 };
175 
176 IMPCONTAINER_END_NAMESPACE
177 
178 #endif /* IMPCONTAINER_CONSECUTIVE_PAIR_CONTAINER_H */
virtual int get_value_index(kernel::Model *, const kernel::ParticleIndexPair &pip) const
Compute the predicate and the derivative if needed.
A base class for Keys.
Definition: kernel/Key.h:46
Import IMP/kernel/pair_macros.h in the namespace.
IMP::base::Vector< IMP::base::WeakPointer< kernel::ModelObject > > ModelObjectsTemp
Import IMP/kernel/SingletonContainer.h in the namespace.
void apply_generic(F *f) const
apply to each item in container
void apply_generic(F *f) const
apply to each item in container
A smart pointer to a ref-counted Object that is a class memeber.
Definition: base/Pointer.h:147
ParticlesTemp get_particles(kernel::Model *m, const ParticleIndexes &ps)
A container which contains all consecutive pairs from an input list.
#define IMP_PAIR_CONTAINER_METHODS(Name)
virtual kernel::ParticleIndexPairs get_indexes() const =0
A shared container for Pairs.
Type get_attribute(TypeKey attribute_key, ParticleIndex particle)
A class to store an fixed array of same-typed values.
Definition: base/Array.h:33
virtual int get_value_index(kernel::Model *m, const kernel::ParticleIndexPair &pip) const
Compute the predicate and the derivative if needed.
Import IMP/kernel/PairContainer.h in the namespace.
Import IMP/kernel/PairPredicate.h in the namespace.
virtual kernel::ModelObjectsTemp do_get_inputs(kernel::Model *m, const kernel::ParticleIndexes &pi) const
#define IMP_PAIR_PREDICATE_METHODS(Name)
Define extra the functions needed for a PairPredicate.
#define IMP_OBJECT_METHODS(Name)
Define the basic things needed by any Object.
virtual kernel::ModelObjectsTemp do_get_inputs(kernel::Model *m, const kernel::ParticleIndexes &pi) const
Store a list of kernel::ParticlePairsTemp.
Abstract predicate function.
#define IMP_OBJECTS(Name, PluralName)
Define the types for storing sets of objects.
IMP::kernel::PairPredicate PairPredicate
Class for storing model, its restraints, constraints, and particles.
Definition: kernel/Model.h:72
Import IMP/kernel/generic.h in the namespace.