IMP  2.0.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-2013 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/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 protected:
44  void init(Float bin_size) {
45  // clear();
46  bin_size_ = bin_size;
47  one_over_bin_size_ = 1.0/bin_size_; // for faster calculation
48  max_distance_ = 50.0; // start with ~50A (by default)
49  std::vector< ValueT >::reserve(dist2index(max_distance_) + 1);
50  }
51  unsigned int dist2index(Float dist) const {
52  return algebra::get_rounded( dist * one_over_bin_size_ );
53  }
54  Float index2dist(unsigned int index) const { return index * bin_size_; }
55 protected:
56  Float bin_size_, one_over_bin_size_; // resolution of discretization
57  Float max_distance_; // parameter for maximum r value for p(r) function
58 };
59 
60 #ifdef SWIG
61 %template(FloatDistribution) Distribution<Float>;
62 %template(VectorDistribution) Distribution<algebra::Vector3D>;
63 #endif
64 
65 /**
66  Radial Distribution class for calculating SAXS Profile
67  this is distance distribution multiplied by form factors of atoms
68 */
69 class IMPSAXSEXPORT RadialDistributionFunction : public Distribution<Float> {
70 
71 public:
72  //! Constructor (default)
73  RadialDistributionFunction(Float bin_size = pr_resolution);
74 
75  //! Constructor from gnom file
76  RadialDistributionFunction(const std::string& file_name);
77 
78  friend class Profile;
79 
80  //! scale distribution by a constant
81  void scale(Float c);
82 
83  //! add another distribution
84  void add(const RadialDistributionFunction& model_pr);
85 
86  //! print tables
87  void show(std::ostream &out=std::cout) const;
88 
89  //! analogy crystallographic R-factor score
90  Float R_factor_score(const RadialDistributionFunction& model_pr,
91  const std::string& file_name = "") const;
92 
93  // //! analogy to chi score \untested{chi_score}
94  // Float chi_score(const RadialDistributionFunction& model_pr) const;
95 
96  //! fit the distributions by scaling according to maximum
97  Float fit(const RadialDistributionFunction& model_pr,
98  const std::string& file_name = "") const;
99 
100  //! normalize to area = 1.0
101  void normalize();
102 
103  private:
104 
105  void add_to_distribution(Float dist, Float value) {
106  unsigned int index = dist2index(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_ = index2dist(index + 1);
112  }
113  (*this)[index] += value;
114  }
115 
116  //! read gnom file
117  void read_pr_file(const std::string& file_name);
118 
119  //! write fit file for the two distributions
120  void write_fit_file(const RadialDistributionFunction& model_pr,
121  Float c = 1.0, const std::string& file_name = "") const;
122 
123 };
124 
125 
126 /**
127 Delta Distribution class for calculating the derivatives of SAXS Score
128 this distribution is:
129 sum_i [f_p(0) * f_i(0) * (x_p - x_i)]
130 sum_i [f_p(0) * f_i(0) * (y_p - y_i)]
131 sum_i [f_p(0) * f_i(0) * (z_p - z_i)]
132 */
133 class IMPSAXSEXPORT
135 public:
136  //! Constructor
137  DeltaDistributionFunction(const Particles& particles,
138  Float max_distance = 0.0,
139  Float bin_size = pr_resolution);
140 
141  //! calculates distribution for an atom defined by particle
142  void calculate_derivative_distribution(Particle* particle);
143 
144  //! print tables
145  void show(std::ostream &out=std::cout, std::string prefix="") const;
146 
147  private:
148  void add_to_distribution(Float dist, const algebra::Vector3D& value) {
149  unsigned int index = dist2index(dist);
150  if(index >= size()) {
151  if(capacity() <= index)
152  reserve(2 * index); // to avoid many re-allocations
153  resize(index + 1, algebra::Vector3D(0.0, 0.0, 0.0));
154  max_distance_ = index2dist(index + 1);
155  }
156  (*this)[index] += value;
157  }
158 
159  void init() {
160  clear();
161  insert(begin(), dist2index(max_distance_) + 1,
162  algebra::Vector3D(0.0, 0.0, 0.0));
163  }
164 
165  protected:
166  std::vector<algebra::Vector3D> coordinates_;
167  Floats form_factors_;
168 };
169 
170 IMPSAXS_END_NAMESPACE
171 
172 #endif /* IMPSAXS_DISTRIBUTION_H */