IMP  2.2.1
The Integrative Modeling Platform
Distribution.h
Go to the documentation of this file.
1 /**
2  * \file IMP/saxs/Distribution.h \brief computes distribution functions
3  *
4  * Distribution - base distance distribution class
5  * RadialDistributionFunction required for calculation of SAXS profile
6  * DeltaDistributionFunction requires for chi-square derivatives
7  *
8  * Copyright 2007-2014 IMP Inventors. All rights reserved.
9  *
10  */
11 
12 #ifndef IMPSAXS_DISTRIBUTION_H
13 #define IMPSAXS_DISTRIBUTION_H
14 
15 #include <IMP/saxs/saxs_config.h>
16 #include "Profile.h"
17 #include <IMP/kernel/Particle.h>
18 
19 #include <iostream>
20 #include <vector>
21 
22 IMPSAXS_BEGIN_NAMESPACE
23 
24 namespace { // anonymous
25 static const Float pr_resolution = 0.5;
26 }
27 
28 /**
29 base class for distribution classes
30 */
31 template <class ValueT>
32 class Distribution : public std::vector<ValueT> {
33  public:
34  //! Constructor
35  Distribution(Float bin_size = pr_resolution) { init(bin_size); }
36 
37  //! returns maximal distance value of distribution
38  Float get_max_distance() const { return max_distance_; }
39 
40  //! returns bin size
41  Float get_bin_size() const { return bin_size_; }
42 
43  unsigned int get_index_from_distance(Float dist) const {
44  return algebra::get_rounded(dist * one_over_bin_size_);
45  }
46  Float get_distance_from_index(unsigned int index) const {
47  return index * bin_size_;
48  }
49 
50  protected:
51  void init(Float bin_size) {
52  // clear();
53  bin_size_ = bin_size;
54  one_over_bin_size_ = 1.0 / bin_size_; // for faster calculation
55  max_distance_ = 50.0; // start with ~50A (by default)
56  std::vector<ValueT>::reserve(get_index_from_distance(max_distance_) + 1);
57  }
58 
59  protected:
60  Float bin_size_, one_over_bin_size_; // resolution of discretization
61  Float max_distance_; // parameter for maximum r value for p(r) function
62 };
63 
64 #ifdef SWIG
65 %template(FloatDistribution) Distribution<Float>;
66 %template(VectorDistribution) Distribution<algebra::Vector3D>;
67 #endif
68 
69 /**
70  Radial Distribution class for calculating SAXS Profile
71  this is distance distribution multiplied by form factors of atoms
72 */
73 class IMPSAXSEXPORT RadialDistributionFunction : public Distribution<Float> {
74 
75  public:
76  //! Constructor (default)
77  RadialDistributionFunction(Float bin_size = pr_resolution);
78 
79  //! Constructor from gnom file
80  RadialDistributionFunction(const std::string& file_name);
81 
82  //! scale distribution by a constant
83  void scale(Float c);
84 
85  //! add another distribution
86  void add(const RadialDistributionFunction& model_pr);
87 
88  //! print tables
89  void show(std::ostream& out = std::cout) const;
90 
91  //! analogy crystallographic R-factor score
92  Float R_factor_score(const RadialDistributionFunction& model_pr,
93  const std::string& file_name = "") const;
94 
95  // //! analogy to chi score \untested{chi_score}
96  // Float chi_score(const RadialDistributionFunction& model_pr) const;
97 
98  //! fit the distributions by scaling according to maximum
99  Float fit(const RadialDistributionFunction& model_pr,
100  const std::string& file_name = "") const;
101 
102  //! normalize to area = 1.0
103  void normalize();
104 
105  void add_to_distribution(Float dist, Float value) {
106  unsigned int index = get_index_from_distance(dist);
107  if (index >= size()) {
108  if (capacity() <= index)
109  reserve(2 * index); // to avoid many re-allocations
110  resize(index + 1, 0);
111  max_distance_ = get_distance_from_index(index + 1);
112  }
113  (*this)[index] += value;
114  }
115 
116  private:
117  //! read gnom file
118  void read_pr_file(const std::string& file_name);
119 
120  //! write fit file for the two distributions
121  void write_fit_file(const RadialDistributionFunction& model_pr, Float c = 1.0,
122  const std::string& file_name = "") const;
123 };
124 
125 /**
126 Delta Distribution class for calculating the derivatives of SAXS Score
127 this distribution is:
128 sum_i [f_p(0) * f_i(0) * (x_p - x_i)]
129 sum_i [f_p(0) * f_i(0) * (y_p - y_i)]
130 sum_i [f_p(0) * f_i(0) * (z_p - z_i)]
131 */
132 class IMPSAXSEXPORT DeltaDistributionFunction
134  public:
135  //! Constructor
137  Float max_distance = 0.0,
138  Float bin_size = pr_resolution);
139 
140  //! calculates distribution for an atom defined by particle
141  void calculate_derivative_distribution(kernel::Particle* particle);
142 
143  //! print tables
144  void show(std::ostream& out = std::cout, std::string prefix = "") const;
145 
146  private:
147  void add_to_distribution(Float dist, const algebra::Vector3D& value) {
148  unsigned int index = get_index_from_distance(dist);
149  if (index >= size()) {
150  if (capacity() <= index)
151  reserve(2 * index); // to avoid many re-allocations
152  resize(index + 1, algebra::Vector3D(0.0, 0.0, 0.0));
153  max_distance_ = get_distance_from_index(index + 1);
154  }
155  (*this)[index] += value;
156  }
157 
158  void init() {
159  clear();
160  insert(begin(), get_index_from_distance(max_distance_) + 1,
161  algebra::Vector3D(0.0, 0.0, 0.0));
162  }
163 
164  protected:
165  std::vector<algebra::Vector3D> coordinates_;
166  Floats form_factors_;
167 };
168 
169 IMPSAXS_END_NAMESPACE
170 
171 #endif /* IMPSAXS_DISTRIBUTION_H */
Distribution(Float bin_size=pr_resolution)
Constructor.
Definition: Distribution.h:35
Float get_max_distance() const
returns maximal distance value of distribution
Definition: Distribution.h:38
Float get_bin_size() const
returns bin size
Definition: Distribution.h:41
int get_rounded(const T &x)
Rounds a number to next integer.
Class to handle individual model particles.
Classes to handle individual model particles.
void show(Hierarchy h, std::ostream &out=std::cout)
Print out a molecular hierarchy.
VectorD< 3 > Vector3D
Definition: VectorD.h:395
double Float
Basic floating-point value (could be float, double...)
Definition: base/types.h:20
A class for profile storing and computation.