IMP logo
IMP Reference Guide  2.14.0
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-2020 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 particle pairs from an input list
23 /** If it is assumed that each particle is in at most one such container,
24  then ExclusiveConsecutivePairContainer should be used instead,
25  since it is faster when doing certain computations.
26 
27  Also see ConsecutivePairFilter.
28 */
29 class IMPCONTAINEREXPORT ConsecutivePairContainer : public PairContainer {
30  friend class ConsecutivePairFilter;
31  const ParticleIndexes ps_;
32  IntKey key_;
33  /**
34  add the key of this container as an attribute to all particles
35  if there might be overlaps - create a different key for each instance
36  */
37  void init();
38 
39  bool get_contains(const ParticleIndexPair &p) const {
40  if (!get_model()->get_has_attribute(key_, p[0])) return false;
41  int ia = get_model()->get_attribute(key_, p[0]);
42  if (!get_model()->get_has_attribute(key_, p[1])) return false;
43  int ib = get_model()->get_attribute(key_, p[1]);
44  return std::abs(ia - ib) == 1;
45  }
46 
47  protected:
48  virtual std::size_t do_get_contents_hash() const IMP_OVERRIDE { return 0; }
49 
50  public:
51  //! apply to each item in container
52  template <class F>
53  void apply_generic(F *f) const {
54  for (unsigned int i = 1; i < ps_.size(); ++i) {
55  f->apply_index(get_model(),
56  ParticleIndexPair(ps_[i - 1], ps_[i]));
57  }
58  }
59 
61  std::string name = "ConsecutivePairContainer%1%");
62 
64  virtual ParticleIndexPairs get_range_indexes() const IMP_OVERRIDE;
65  virtual ModelObjectsTemp do_get_inputs() const IMP_OVERRIDE;
66  virtual 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  /** @param cpc the consecutive pair container that stores
80  filtered pairs
81  */
82  ConsecutivePairFilter(ConsecutivePairContainer *cpc);
83 
84  virtual int get_value_index(Model *,
85  const ParticleIndexPair &pip) const
86  IMP_OVERRIDE {
87  return cpc_->get_contains(pip);
88  }
90  Model *m, const ParticleIndexes &pi) const IMP_OVERRIDE {
91  ModelObjectsTemp ret;
92  ret += IMP::get_particles(m, pi);
93  return ret;
94  }
97 };
98 
99 /** This is an ConsecutivePairContainer where each particle can only be on
100  one ExclusiveConsecutivePairContainer. The exclusivity makes the code
101  more efficient and allows one to use the ExclusiveConsecutivePairFilter,
102  which is way more efficient than using an InContainerPairFilter
103  with a ConsecutivePairContainer.*/
104 class IMPCONTAINEREXPORT ExclusiveConsecutivePairContainer
105  : public PairContainer {
106  friend class ExclusiveConsecutivePairFilter;
107  const ParticleIndexes ps_;
108  static IntKey get_exclusive_key() {
109  static IntKey k("exclusive consecutive numbering");
110  return k;
111  }
112  static ObjectKey get_exclusive_object_key() {
113  static ObjectKey k("exclusive consecutive container");
114  return k;
115  }
116  static bool get_contains(Model *m,
117  const ParticleIndexPair &pp) {
118  ObjectKey ok =
119  ExclusiveConsecutivePairContainer::get_exclusive_object_key();
120  bool has_eok_0 = m->get_has_attribute(ok, pp[0]);
121  bool has_eok_1= m->get_has_attribute(ok, pp[1]);
122  if ( !has_eok_0 || !has_eok_1 )
123  return false;
124  if (m->get_attribute(ok, pp[0]) != m->get_attribute(ok, pp[1])) {
125  return false;
126  }
127  IntKey k = ExclusiveConsecutivePairContainer::get_exclusive_key();
128  int ia = m->get_attribute(k, pp[0]);
129  int ib = m->get_attribute(k, pp[1]);
130  return std::abs(ia - ib) == 1;
131  }
132  void init();
133 
134  protected:
135  virtual std::size_t do_get_contents_hash() const IMP_OVERRIDE { return 0; }
136 
137  /**
138  Called by Object destructor - removes all keys associated with
139  the exclusive consecutive pair container, so it can be now added to
140  another exclusive consecutive pair container
141  */
142  virtual void do_destroy();
143 
144 
145  public:
146  //! apply to each item in container
147  template <class F>
148  void apply_generic(F *f) const {
149  for (unsigned int i = 1; i < ps_.size(); ++i) {
150  f->apply_index(get_model(),
151  ParticleIndexPair(ps_[i - 1], ps_[i]));
152  }
153  }
154 
156  std::string name =
157  "ExclusiveConsecutivePairContainer%1%");
158 
160  virtual ParticleIndexPairs get_range_indexes() const IMP_OVERRIDE;
161  virtual ModelObjectsTemp do_get_inputs() const IMP_OVERRIDE;
162  virtual ParticleIndexes get_all_possible_indexes() const IMP_OVERRIDE;
164  IMP_OBJECT_METHODS(ExclusiveConsecutivePairContainer);
165 };
166 
167 /** Check for whether the pair is a member of any
168  ExclusiveConsecutivePairContainer. */
169 class IMPCONTAINEREXPORT ExclusiveConsecutivePairFilter : public PairPredicate {
170  public:
172  : PairPredicate("ExclusiveConsecutivePairFilter %1%") {}
173 
174  virtual int get_value_index(Model *m,
175  const ParticleIndexPair &pip) const
176  IMP_OVERRIDE {
177  return ExclusiveConsecutivePairContainer::get_contains(m, pip);
178  }
180  Model *m, const ParticleIndexes &pi) const IMP_OVERRIDE {
181  ModelObjectsTemp ret;
182  ret += IMP::get_particles(m, pi);
183  return ret;
184  }
187 };
188 
189 IMPCONTAINER_END_NAMESPACE
190 
191 #endif /* IMPCONTAINER_CONSECUTIVE_PAIR_CONTAINER_H */
A shared container for Pairs.
Definition: PairContainer.h:37
virtual ModelObjectsTemp do_get_inputs(Model *m, const ParticleIndexes &pi) const
Overload this method to specify the inputs.
Macros for various classes.
A container for Singletons.
void apply_generic(F *f) const
apply to each item in container
void apply_generic(F *f) const
apply to each item in container
#define IMP_OBJECT_METHODS(Name)
Define the basic things needed by any Object.
Definition: object_macros.h:25
A container which contains all consecutive particle pairs from an input list.
ParticlesTemp get_particles(Model *m, const ParticleIndexes &ps)
#define IMP_PAIR_CONTAINER_METHODS(Name)
Definition: pair_macros.h:117
Class for storing model, its restraints, constraints, and particles.
Definition: Model.h:72
A container for Pairs.
virtual void do_destroy()
Definition: Object.h:231
Define PairPredicate.
A smart pointer to a ref-counted Object that is a class member.
Definition: Pointer.h:146
Store a list of ParticleIndexPairs.
virtual int get_value_index(Model *m, const ParticleIndexPair &pip) const
Compute the predicate and the derivative if needed.
#define IMP_OBJECTS(Name, PluralName)
Define the types for storing lists of object pointers.
Definition: object_macros.h:44
Abstract predicate function.
Definition: PairPredicate.h:31
virtual int get_value_index(Model *, const ParticleIndexPair &pip) const
Compute the predicate and the derivative if needed.
virtual ParticleIndexPairs get_indexes() const =0
bool get_has_attribute(TypeKey attribute_key, ParticleIndex particle) const
return true if particle has attribute with the specified key
virtual ModelObjectsTemp do_get_inputs(Model *m, const ParticleIndexes &pi) const
Overload this method to specify the inputs.
Type get_attribute(TypeKey attribute_key, ParticleIndex particle)
get the value of the particle attribute with the specified key
#define IMP_OVERRIDE
Cause a compile error if this method does not override a parent method.
#define IMP_PAIR_PREDICATE_METHODS(Name)
Define extra the functions needed for a PairPredicate.
Definition: pair_macros.h:47
Various important functionality for implementing decorators.