IMP logo
IMP Reference Guide  2.13.0
The Integrative Modeling Platform
SAXSMultiStateModelScore.h
Go to the documentation of this file.
1 /**
2  * \file IMP/multi_state/SAXSMultiStateModelScore.h
3  * \brief
4  *
5  * \authors Dina Schneidman
6  * Copyright 2007-2020 IMP Inventors. All rights reserved.
7  *
8  */
9 
10 #ifndef IMPMULTI_STATE_SAXS_MULTI_STATE_MODEL_SCORE_H
11 #define IMPMULTI_STATE_SAXS_MULTI_STATE_MODEL_SCORE_H
12 
13 #include "MultiStateModelScore.h"
14 #include "MultiStateModel.h"
15 
16 #include <IMP/saxs/Profile.h>
18 #include <IMP/Object.h>
19 
20 #include <vector>
21 
22 IMPMULTISTATE_BEGIN_NAMESPACE
23 
24 /** Score multi-state models against SAXS profiles */
25 template <typename ScoringFunctionT>
27 public:
28 
29  /* if c1_c2_approximate=true, get_score will return approximate score
30  based on average c1/c2
31  min_weight_threshold, multi-state models with one or more weights below
32  min_weight_threshold will get a negative score
33  */
35  const saxs::Profile* exp_profile,
36  bool c1_c2_approximate,
37  double min_c1 = 0.99, double max_c1 = 1.05,
38  double min_c2 = -0.5, double max_c2 = 2.0,
39  bool use_offset = false);
40 
41  double get_score(const MultiStateModel& m) const;
42 
43  double get_score(const MultiStateModel& m,
44  Vector<double>& weights) const;
45 
46  saxs::WeightedFitParameters get_fit_parameters(MultiStateModel& m) const;
47 
48  saxs::WeightedFitParameters get_fit_parameters() const;
49 
50  void write_fit_file(MultiStateModel& m,
52  const std::string fit_file_name) const;
53 
54  std::string get_state_name(unsigned int id) const { return profiles_[id]->get_name(); }
55 
56  std::string get_dataset_name() const { return exp_profile_->get_name(); }
57 
58  double get_average_c1() const { return average_c1_; }
59  double get_average_c2() const { return average_c2_; }
60 
61  void set_average_c1_c2(const Vector<saxs::WeightedFitParameters>& fps);
62 
63 private:
64  void resample(const saxs::Profile* exp_profile,
65  const saxs::Profiles& profiles,
66  saxs::Profiles& resampled_profiles);
67 
68  void set_average_c1_c2(saxs::WeightedProfileFitter<ScoringFunctionT>* score,
69  const saxs::Profiles& profiles);
70 
71 private:
72  // input profiles
73  const saxs::Profiles profiles_;
75 
76  // resampled on experimental profile q's
77  saxs::Profiles resampled_profiles_;
78 
79  // scoring with exp_profile_
81 
82  double min_c1_, max_c1_, min_c2_, max_c2_;
83  double average_c1_, average_c2_;
84 
85  // approximate c1/c2 at get_score(), do accurate fitting at get_fit_parameters()
86  bool c1_c2_approximate_;
87 
88  // do not perform any c1/c2 fitting
89  bool c1_c2_no_fitting_;
90 
91  bool use_offset_;
92 };
93 
94 template <typename ScoringFunctionT>
96  const saxs::Profiles& profiles,
97  const saxs::Profile* exp_profile,
98  bool c1_c2_approximate,
99  double min_c1, double max_c1,
100  double min_c2, double max_c2,
101  bool use_offset) :
102  profiles_(profiles), exp_profile_(exp_profile),
103  min_c1_(min_c1), max_c1_(max_c1), min_c2_(min_c2), max_c2_(max_c2),
104  c1_c2_approximate_(c1_c2_approximate), c1_c2_no_fitting_(false),
105  use_offset_(use_offset) {
106 
107  if(profiles_.size() < 1) {
108  IMP_THROW("SAXSMultiStateModelScore - please provide at least one profile"
109  << std::endl, IOException);
110  }
111 
112  // resample all models profiles
113  resample(exp_profile_, profiles_, resampled_profiles_);
114 
115  // init scoring object
116  score_ = new saxs::WeightedProfileFitter<ScoringFunctionT>(exp_profile_);
117 
118  // compute average c1/c2
119  set_average_c1_c2(score_, resampled_profiles_);
120 }
121 
122 template <typename ScoringFunctionT>
123 void SAXSMultiStateModelScore<ScoringFunctionT>::resample(
124  const saxs::Profile* exp_profile,
125  const saxs::Profiles& profiles,
126  saxs::Profiles& resampled_profiles) {
127 
128  resampled_profiles.reserve(profiles.size());
129  for(unsigned int i=0; i<profiles.size(); i++) {
130  saxs::Profile *resampled_profile =
131  new saxs::Profile(exp_profile->get_min_q(), exp_profile->get_max_q(),
132  exp_profile->get_delta_q());
133  profiles[i]->resample(exp_profile, resampled_profile);
134  resampled_profiles.push_back(resampled_profile);
135  if(!profiles[i]->is_partial_profile()) c1_c2_no_fitting_ = true;
136  }
137 }
138 
139 template <typename ScoringFunctionT>
140 void SAXSMultiStateModelScore<ScoringFunctionT>::set_average_c1_c2(
141  saxs::WeightedProfileFitter<ScoringFunctionT>* score,
142  const saxs::Profiles& profiles) {
143  if(c1_c2_no_fitting_) return;
144  average_c1_ = 0.0;
145  average_c2_ = 0.0;
146  saxs::ProfilesTemp profiles_temp(1);
147  for(unsigned int i=0; i<profiles.size(); i++) {
148  profiles_temp[0] = profiles[i];
149  saxs::WeightedFitParameters fp =
150  score->fit_profile(profiles_temp, min_c1_, max_c1_, min_c2_, max_c2_, use_offset_);
151  average_c1_ += fp.get_c1();
152  average_c2_ += fp.get_c2();
153  }
154  average_c1_ /= profiles.size();
155  average_c2_ /= profiles.size();
156 }
157 
158 template <typename ScoringFunctionT>
159 void SAXSMultiStateModelScore<ScoringFunctionT>::set_average_c1_c2(
160  const Vector<saxs::WeightedFitParameters>& fps) {
161  if(c1_c2_no_fitting_) return;
162  double c1 = 0.0;
163  double c2 = 0.0;
164  for(unsigned int i=0; i<fps.size(); i++) {
165  c1 += fps[i].get_c1();
166  c2 += fps[i].get_c2();
167  }
168  c1 /= fps.size();
169  c2 /= fps.size();
170 
171  average_c1_ = c1;
172  average_c2_ = c2;
173 }
174 
175 
176 template <typename ScoringFunctionT>
177 double SAXSMultiStateModelScore<ScoringFunctionT>::get_score(const MultiStateModel& m,
178  Vector<double>& weights) const {
179  const Vector<unsigned int>& states = m.get_states();
180  saxs::ProfilesTemp profiles(states.size());
181  for(unsigned int i=0; i<states.size(); i++) {
182  profiles[i] = resampled_profiles_[states[i]];
183  if(c1_c2_approximate_ && !c1_c2_no_fitting_)
184  profiles[i]->sum_partial_profiles(average_c1_, average_c2_);
185  }
186 
187  double chi_square;
188  if(c1_c2_approximate_ || c1_c2_no_fitting_) { // just score calculation
189  chi_square = score_->compute_score(profiles, weights, use_offset_);
190  } else { // optimize c1/c2 fit and score
191  saxs::WeightedFitParameters fp =
192  score_->fit_profile(profiles, min_c1_, max_c1_, min_c2_, max_c2_, use_offset_);
193  chi_square = fp.get_chi_square();
194  }
195  return chi_square;
196 }
197 
198 template <typename ScoringFunctionT>
199 double SAXSMultiStateModelScore<ScoringFunctionT>::get_score(const MultiStateModel& m) const {
200  Vector<double> weights;
201  return get_score(m, weights);
202 }
203 
204 
205 template <typename ScoringFunctionT>
206 saxs::WeightedFitParameters
207  SAXSMultiStateModelScore<ScoringFunctionT>::get_fit_parameters(MultiStateModel& m) const {
208 
209  if(c1_c2_no_fitting_) {
210  Vector<double> weights;
211  double s = get_score(m, weights);
212  saxs::WeightedFitParameters wfp(s, 1.0, 0.0, weights);
213  return wfp;
214  }
215 
216  const Vector<unsigned int>& states = m.get_states();
217  saxs::ProfilesTemp profiles(states.size());
218  for(unsigned int i=0; i<states.size(); i++)
219  profiles[i] = resampled_profiles_[states[i]];
220 
221  saxs::WeightedFitParameters fp =
222  score_->fit_profile(profiles, min_c1_, max_c1_, min_c2_, max_c2_, use_offset_);
223  m.set_score(fp.get_chi_square());
224  return fp;
225 }
226 
227 template <typename ScoringFunctionT>
228 saxs::WeightedFitParameters
229  SAXSMultiStateModelScore<ScoringFunctionT>::get_fit_parameters() const {
230 
231  if(c1_c2_no_fitting_) {
232  Vector<double> weights;
233  double s = score_->compute_score(resampled_profiles_, weights, use_offset_);
234  saxs::WeightedFitParameters wfp(s, 1.0, 0.0, weights);
235  return wfp;
236  }
237 
238  saxs::WeightedFitParameters fp = score_->fit_profile(resampled_profiles_,
239  min_c1_, max_c1_,
240  min_c2_, max_c2_, use_offset_);
241  return fp;
242 }
243 
244 template <typename ScoringFunctionT>
245 void SAXSMultiStateModelScore<ScoringFunctionT>::write_fit_file(MultiStateModel& m,
246  const saxs::WeightedFitParameters& fp,
247  const std::string fit_file_name) const {
248 
249  const Vector<unsigned int>& states = m.get_states();
250  saxs::ProfilesTemp profiles(states.size());
251  for(unsigned int i=0; i<states.size(); i++)
252  profiles[i] = resampled_profiles_[states[i]];
253  score_->write_fit_file(profiles, fp, fit_file_name, use_offset_);
254 }
255 
256 IMPMULTISTATE_END_NAMESPACE
257 
258 #endif /* IMPMULTI_STATE_SAXS_MULTI_STATE_MODEL_SCORE_H */
IMP::Vector< IMP::Pointer< Profile > > Profiles
Definition: Profile.h:304
base class for MultiStateModel scoring classes
Fitting of multiple profiles to the experimental one. The weights of the profiles are computed analyt...
Base class for MultiStateModel scoring classes.
A more IMP-like version of the std::vector.
Definition: Vector.h:39
An input/output exception.
Definition: exception.h:174
Fitting of multiple profiles to the experimental one.
Keep track of multiple states.
IMP::Vector< IMP::WeakPointer< Profile > > ProfilesTemp
Definition: Profile.h:304
#define IMP_THROW(message, exception_name)
Throw an exception with a message.
Definition: check_macros.h:50
Parameters of a weighted fit, from WeightedProfileFitter.
A shared base class to help in debugging and things.
Keep track of multiple states.
A class for profile storing and computation.