IMP logo
IMP Reference Guide  develop.d4e9f3251e,2024/04/26
The Integrative Modeling Platform
MSConnectivityRestraint.h
Go to the documentation of this file.
1 /**
2  * \file IMP/core/MSConnectivityRestraint.h
3  * \brief Mass Spec Connectivity restraint.
4  *
5  * Restrict max distance between at least one pair of particles of any
6  * two distinct types. It also handles multiple copies of the same particles.
7  *
8  * Copyright 2007-2022 IMP Inventors. All rights reserved.
9  *
10  */
11 
12 #ifndef IMPCORE_MS_CONNECTIVITY_RESTRAINT_H
13 #define IMPCORE_MS_CONNECTIVITY_RESTRAINT_H
14 
15 #include <vector>
16 #include <string>
17 #include <IMP/core/core_config.h>
18 #include "DistanceRestraint.h"
19 
20 #include <IMP/SingletonContainer.h>
21 #include <IMP/Restraint.h>
22 #include <IMP/PairScore.h>
23 
24 IMPCORE_BEGIN_NAMESPACE
25 
26 // Hopefully this would "fix" the problem with friend access
27 // in older versions of gcc
28 #ifdef __GNUC__
29 #define IMP_GCC_VERSION \
30  (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__)
31 #if IMP_GCC_VERSION >= 40100
32 #define IMPCORE_FRIEND_IS_OK
33 #endif
34 #else
35 // assume that other compilers are fine
36 #define IMPCORE_FRIEND_IS_OK
37 #endif
38 
39 //! Ensure that a set of particles remains connected with one another.
40 /** The restraint implements ambiguous connectivity. That is, it takes
41  several particles including multiple copies and ensures that they remain
42  connected, but allows how they are connected to change. If you wish
43  to restrain the connectivity of sets of
44  particles (i.e. each protein is represented using a set of balls)
45  use an appropriate PairScore which calls a Refiner (such
46  as ClosePairsPairScore).
47 
48  \include ms_connectivity_restraint.py
49 
50  More precisely, the restraint scores by computing the MST on the complete
51  graph connecting all the particles. The edge weights are given by
52  the value of the PairScore for the two endpoints of the edge.
53  */
54 class IMPCOREEXPORT MSConnectivityRestraint : public Restraint {
57  double eps_;
58 
59  public:
60  //! Use the given PairScore
61  /** If sc is nullptr, a ListSingletonContainer is created internally.
62  eps is set to 0.1 by default.
63  */
64  MSConnectivityRestraint(Model *m, PairScore *ps, double eps = 0.1);
65  /** @name Particles to be connected
66 
67  The following methods are used to manipulate the list of particles
68  that are to be connected. Each particle should have all the
69  attributes expected by the PairScore used.
70 
71  Ideally, one should pass a singleton container instead. These
72  can only be used if none is passed.
73  */
74  /*@{*/
75  unsigned int add_type(const ParticlesTemp &ps);
76  unsigned int add_composite(const Ints &components);
77  unsigned int add_composite(const Ints &components, unsigned int parent);
78  // void add_particle(Particle *p);
79  // void add_particles(const Particles &ps);
80  // void set_particles(const Particles &ps);
81  /*@}*/
82 
83  //! Return the set of pairs which are connected by the restraint
84  /** This set of pairs reflects the current configuration at the time of
85  the get_connected_pairs() call, not the set at the time of the last
86  evaluate() call.
87  */
88  ParticlePairsTemp get_connected_pairs() const;
89 
90  //! Return the pair score used for scoring
91  PairScore *get_pair_score() const { return ps_; }
92 
94 
95  double unprotected_evaluate(
96  IMP::DerivativeAccumulator *accum) const override;
97 
98  ModelObjectsTemp do_get_inputs() const override;
99 
101 
102 #ifdef IMPCORE_FRIEND_IS_OK
103  private:
104 #endif
105 
106 #ifndef IMP_DOXYGEN
107  class ParticleMatrix {
108  public:
109  class ParticleData {
110  public:
111  ParticleData(Particle *p, unsigned int id)
112  : particle_(p), id_(id) {}
113 
114  Particle *get_particle() const { return particle_; }
115 
116  unsigned int get_id() const { return id_; }
117 
118  private:
119  Particle *particle_;
120  unsigned int id_;
121  };
122 
123  ParticleMatrix(unsigned int number_of_classes)
124  : protein_by_class_(number_of_classes),
125  min_distance_(std::numeric_limits<double>::max()),
126  max_distance_(0),
127  current_id_(0) {}
128 
129  ParticleMatrix()
130  : min_distance_(std::numeric_limits<double>::max()),
131  max_distance_(0),
132  current_id_(0) {}
133 
134  void resize(unsigned int number_of_classes) {
135  protein_by_class_.resize(number_of_classes);
136  }
137 
138  unsigned int add_particle(Particle *p, unsigned int id);
139  unsigned int add_type(const ParticlesTemp &ps);
140  void create_distance_matrix(const PairScore *ps);
141  void clear_particles() {
142  particles_.clear();
143  for (unsigned int i = 0; i < protein_by_class_.size(); ++i)
144  protein_by_class_[i].clear();
145  }
146  unsigned int size() const { return particles_.size(); }
147  unsigned int get_number_of_classes() const {
148  return protein_by_class_.size();
149  }
150  double get_distance(unsigned int p1, unsigned int p2) const {
151  return dist_matrix_[p1 * size() + p2];
152  }
153  Ints const &get_ordered_neighbors(unsigned int p) const {
154  return order_[p];
155  }
156  ParticleData const &get_particle(unsigned int p) const {
157  return particles_[p];
158  }
159  Ints const &get_all_proteins_in_class(unsigned int id) const {
160  return protein_by_class_[id];
161  }
162  double max_distance() const { return max_distance_; }
163  double min_distance() const { return min_distance_; }
164 
165  private:
166  class DistCompare {
167  public:
168  DistCompare(unsigned int source, ParticleMatrix const &parent)
169  : parent_(parent), source_(source) {}
170 
171  bool operator()(unsigned int p1, unsigned int p2) const {
172  return parent_.get_distance(source_, p1) <
173  parent_.get_distance(source_, p2);
174  }
175 
176  private:
177  ParticleMatrix const &parent_;
178  unsigned int source_;
179  };
180 
181  Vector<ParticleData> particles_;
182  Floats dist_matrix_;
183  Vector<Ints> order_;
184  Vector<Ints> protein_by_class_;
185  double min_distance_;
186  double max_distance_;
187  unsigned int current_id_;
188  };
189 
190  class ExperimentalTree {
191  public:
192  ExperimentalTree() : root_(-1), finalized_(false) {}
193 
194  void connect(unsigned int parent, unsigned int child);
195  void finalize();
196  unsigned int add_composite(const Ints &components);
197  unsigned int add_composite(const Ints &components, unsigned int parent);
198 
199  class Node {
200  public:
201  Node() : visited_(false) {}
202  unsigned int get_number_of_parents() const { return parents_.size(); }
203  bool is_root() const { return get_number_of_parents() == 0; }
204  unsigned int get_number_of_children() const { return children_.size(); }
205  bool is_leaf() const { return get_number_of_children() == 0; }
206  unsigned int get_parent(unsigned int idx) const { return parents_[idx]; }
207  unsigned int get_child(unsigned int idx) const { return children_[idx]; }
208  typedef Vector<std::pair<unsigned int, int> > Label;
209  const Label &get_label() const { return label_; }
210 
211  Vector<unsigned int> parents_;
212  Vector<unsigned int> children_;
213  Label label_;
214  bool visited_;
215  };
216 
217  bool find_cycle(unsigned int node_index);
218  bool is_consistent(unsigned int node_index) const;
219 
220  const Node *get_node(unsigned int index) const { return &nodes_[index]; }
221  unsigned int get_number_of_nodes() const { return nodes_.size(); }
222  unsigned int get_root() const { return root_; }
223  void desc_to_label(const Ints &components, Node::Label &label);
224 
225  Vector<Node> nodes_;
226  unsigned int root_;
227  bool finalized_;
228  };
229 #endif // IMP_DOXYGEN
230 
231  ParticleMatrix particle_matrix_;
232  mutable ExperimentalTree tree_;
233 
234  friend class MSConnectivityScore;
235 };
236 
237 IMPCORE_END_NAMESPACE
238 
239 #endif /* IMPCORE_MS_CONNECTIVITY_RESTRAINT_H */
Abstract class for scoring object(s) of type ParticleIndexPair.
Definition: PairScore.h:44
Distance restraint between two particles.
A container for Singletons.
IMP::Vector< Float > Floats
Standard way to pass a bunch of Float values.
Definition: types.h:46
#define IMP_OBJECT_METHODS(Name)
Define the basic things needed by any Object.
Definition: object_macros.h:25
virtual double unprotected_evaluate(DerivativeAccumulator *da) const
Return the unweighted score for the restraint.
void add_particle(RMF::FileHandle fh, Particle *hs)
Class for storing model, its restraints, constraints, and particles.
Definition: Model.h:86
virtual Restraints do_create_current_decomposition() const
Definition: Restraint.h:315
PairScore * get_pair_score() const
Return the pair score used for scoring.
Define PairScore.
Hierarchy get_root(Hierarchy h)
Return the root of the hierarchy.
Class to handle individual particles of a Model object.
Definition: Particle.h:43
Abstract base class for all restraints.
IMP::Vector< Int > Ints
Standard way to pass a bunch of Int values.
Definition: types.h:48
Ensure that a set of particles remains connected with one another.
double get_distance(const Line3D &s, const Vector3D &p)
Get closest distance between a line and a point.
virtual ModelObjectsTemp do_get_inputs() const =0
Class for adding derivatives from restraints to the model.
A restraint is a term in an IMP ScoringFunction.
Definition: Restraint.h:56