IMP logo
IMP Reference Guide  develop.b3a5ae88fa,2024/05/05
The Integrative Modeling Platform
SAXSMultiCombinationScore.h
Go to the documentation of this file.
1 /**
2  * \file IMP/multi_state/SAXSMultiCombinationScore.h
3  * \brief
4  *
5  * \authors Dina Schneidman
6  * Copyright 2007-2022 IMP Inventors. All rights reserved.
7  *
8  */
9 
10 #ifndef IMPMULTI_STATE_SAXS_MULTI_COMBINATION_SCORE_H
11 #define IMPMULTI_STATE_SAXS_MULTI_COMBINATION_SCORE_H
12 
13 #include "MultiStateModelScore.h"
14 #include "MultiStateModel.h"
15 
16 #include <IMP/saxs/Profile.h>
17 #include <IMP/saxs/ProfileFitter.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  */
34  SAXSMultiCombinationScore(const saxs::Profile* main_profile,
35  const saxs::Profiles& profiles,
36  const saxs::Profile* exp_profile,
37  bool c1_c2_approximate,
38  double min_c1 = 0.99, double max_c1 = 1.05,
39  double min_c2 = -0.5, double max_c2 = 2.0,
40  bool use_offset = false);
41 
42  double get_score(const MultiStateModel& m) const override;
43  double get_score(const MultiStateModel& m,
44  Vector<double>& weights) const override {
45  IMP_UNUSED(weights);
46  return get_score(m);
47  }
48 
49  saxs::WeightedFitParameters get_fit_parameters(MultiStateModel& m) const override;
50 
51  saxs::WeightedFitParameters get_fit_parameters() const override;
52 
53  void write_fit_file(MultiStateModel& m,
55  const std::string fit_file_name) const override;
56 
57  std::string get_state_name(unsigned int id) const override {
58  return profiles_[id]->get_name();
59  }
60 
61  std::string get_dataset_name() const override {
62  return exp_profile_->get_name();
63  }
64 
65  double get_average_c1() const { return average_c1_; }
66  double get_average_c2() const { return average_c2_; }
67 
68  void set_average_c1_c2(const Vector<saxs::FitParameters>& fps);
69 
70 private:
71 
72 private:
73  // input profiles
74  const saxs::Profiles profiles_; // all the others relative to main
75  const saxs::Profile* main_profile_;
77 
78  // scoring with exp_profile_
80 
81  double min_c1_, max_c1_, min_c2_, max_c2_;
82  double average_c1_, average_c2_;
83 
84  // approximate c1/c2 at get_score(), do accurate fitting at get_fit_parameters()
85  bool c1_c2_approximate_;
86 
87  // do not perform any c1/c2 fitting
88  bool c1_c2_no_fitting_;
89 
90  bool use_offset_;
91 };
92 
93 template <typename ScoringFunctionT>
95  const saxs::Profile* main_profile,
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), main_profile_(main_profile), 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("SAXSMultiCombinationScore - please provide at least one profile"
109  << std::endl, IOException);
110  }
111 
112  // init scoring object
113  score_ = new saxs::ProfileFitter<ScoringFunctionT>(exp_profile_);
114 
115  // compute average c1/c2
116  //set_average_c1_c2(score_, resampled_profiles_);
117  average_c1_ = 1.02;
118  average_c2_ = 1.0;
119 }
120 
121 template <typename ScoringFunctionT>
122 void SAXSMultiCombinationScore<ScoringFunctionT>::set_average_c1_c2(
123  const Vector<saxs::FitParameters>& fps) {
124  if(c1_c2_no_fitting_) return;
125  double c1 = 0.0;
126  double c2 = 0.0;
127  for(unsigned int i=0; i<fps.size(); i++) {
128  c1 += fps[i].get_c1();
129  c2 += fps[i].get_c2();
130  }
131  c1 /= fps.size();
132  c2 /= fps.size();
133 
134  average_c1_ = c1;
135  average_c2_ = c2;
136 }
137 
138 
139 template <typename ScoringFunctionT>
140 double SAXSMultiCombinationScore<ScoringFunctionT>::get_score(const MultiStateModel& m) const {
141  const Vector<unsigned int>& states = m.get_states();
142 
143  IMP_NEW(saxs::Profile, combined_profile,(main_profile_->get_min_q(),
144  main_profile_->get_max_q(),
145  main_profile_->get_delta_q()));
146 
147  // get the main part profile
148  combined_profile->add_partial_profiles(main_profile_);
149 
150  // add the partial profiles
151  for(unsigned int i=0; i<states.size(); i++) {
152  combined_profile->add_partial_profiles(profiles_[states[i]]);
153  }
154 
155  saxs::FitParameters fp =
156  score_->fit_profile(combined_profile, min_c1_, max_c1_, min_c2_, max_c2_, use_offset_);
157  return fp.get_chi_square();
158 }
159 
160 template <typename ScoringFunctionT>
161 saxs::WeightedFitParameters
162  SAXSMultiCombinationScore<ScoringFunctionT>::get_fit_parameters(MultiStateModel& m) const {
163 
164  if(c1_c2_no_fitting_) {
165  double s = get_score(m);
166  saxs::WeightedFitParameters fp(s, 1.0, 0.0);
167  return fp;
168  }
169  const Vector<unsigned int>& states = m.get_states();
170  IMP_NEW(saxs::Profile, combined_profile,(main_profile_->get_min_q(),
171  main_profile_->get_max_q(),
172  main_profile_->get_delta_q()));
173 
174  // get the main part profile
175  combined_profile->add_partial_profiles(main_profile_);
176 
177  // add the partial profiles
178  for(unsigned int i=0; i<states.size(); i++) {
179  combined_profile->add_partial_profiles(profiles_[states[i]]);
180  }
181 
182  saxs::WeightedFitParameters fp =
183  score_->fit_profile(combined_profile, min_c1_, max_c1_, min_c2_, max_c2_, use_offset_);
184  Vector<double> weights(states.size(), 1.0/(states.size()+1));
185  fp.set_weights(weights);
186  m.set_score(fp.get_chi_square());
187  return fp;
188 }
189 
190 template <typename ScoringFunctionT>
191 saxs::WeightedFitParameters
192  SAXSMultiCombinationScore<ScoringFunctionT>::get_fit_parameters() const {
193 
194  IMP_NEW(saxs::Profile, combined_profile,(main_profile_->get_min_q(),
195  main_profile_->get_max_q(),
196  main_profile_->get_delta_q()));
197 
198  // get the main part profile
199  combined_profile->add_partial_profiles(main_profile_);
200 
201  // add the partial profiles
202  for(unsigned int i=0; i<profiles_.size(); i++) {
203  combined_profile->add_partial_profiles(profiles_[i]);
204  }
205 
206  if(c1_c2_no_fitting_) {
207  double s = score_->compute_score(combined_profile, use_offset_);
208  saxs::WeightedFitParameters fp(s, 1.0, 0.0);
209  return fp;
210  }
211 
212  saxs::WeightedFitParameters fp = score_->fit_profile(combined_profile,
213  min_c1_, max_c1_,
214  min_c2_, max_c2_, use_offset_);
215  return fp;
216 }
217 
218 template <typename ScoringFunctionT>
219 void SAXSMultiCombinationScore<ScoringFunctionT>::write_fit_file(MultiStateModel& m,
220  const saxs::WeightedFitParameters& fp,
221  const std::string fit_file_name) const {
222 
223  IMP_UNUSED(fp);
224  const Vector<unsigned int>& states = m.get_states();
225 
226  IMP_NEW(saxs::Profile, combined_profile,(main_profile_->get_min_q(),
227  main_profile_->get_max_q(),
228  main_profile_->get_delta_q()));
229 
230  // get the main part profile
231  combined_profile->add_partial_profiles(main_profile_);
232 
233  // add the partial profiles
234  for(unsigned int i=0; i<states.size(); i++) {
235  combined_profile->add_partial_profiles(profiles_[states[i]]);
236  }
237 
238  saxs::WeightedFitParameters fpp = score_->fit_profile(combined_profile,
239  min_c1_, max_c1_,
240  min_c2_, max_c2_, use_offset_, fit_file_name);
241 }
242 
243 IMPMULTISTATE_END_NAMESPACE
244 
245 #endif /* IMPMULTI_STATE_SAXS_MULTI_COMBINATION_SCORE_H */
base class for MultiStateModel scoring classes
Base class for MultiStateModel scoring classes.
a class for fitting two profiles
#define IMP_NEW(Typename, varname, args)
Declare a ref counted pointer to a new object.
Definition: object_macros.h:74
An input/output exception.
Definition: exception.h:173
Keep track of multiple states.
#define IMP_UNUSED(variable)
#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.
Fit two profiles with user-defined scoring function as a template parameter.
Definition: ProfileFitter.h:29
Keep track of multiple states.
A class for profile storing and computation.