Rosetta 3.5
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
SAXSEnergy.cc
Go to the documentation of this file.
1 // -*- mode:c++;tab-width:2;indent-tabs-mode:t;show-trailing-whitespace:t;rm-trailing-spaces:t -*-
2 // vi: set ts=2 noet:
3 //
4 // (c) Copyright Rosetta Commons Member Institutions.
5 // (c) This file is part of the Rosetta software suite and is made available under license.
6 // (c) The Rosetta software is developed by the contributing members of the Rosetta Commons.
7 // (c) For more information, see http://www.rosettacommons.org. Questions about this can be
8 // (c) addressed to University of Washington UW TechTransfer, email: license@u.washington.edu.
9 
10 /// @file core/scoring/saxs/SAXSEnergy.cc
11 /// @brief "Energy" based on a similarity of theoretical SAXS spectrum computed for a pose and the experimental data
12 /// @author Dominik Gront (dgront@chem.uw.edu.pl)
13 
14 // Unit headers
23 
27 
28 // Project headers
29 #include <core/pose/Pose.hh>
32 // AUTO-REMOVED #include <core/id/NamedAtomID.hh>
33 // AUTO-REMOVED #include <core/io/pdb/pose_io.hh>
34 #include <core/io/pdb/file_data.hh>
35 
36 #include <numeric/interpolation/spline/Interpolator.hh>
37 #include <numeric/interpolation/spline/SplineGenerator.hh>
38 
39 // Options
40 #include <basic/options/option.hh>
41 #include <basic/options/keys/OptionKeys.hh>
42 #include <basic/options/keys/in.OptionKeys.gen.hh>
43 #include <basic/options/keys/score.OptionKeys.gen.hh>
44 
46 
47 
48 // Utility headers
49 // AUTO-REMOVED #include <basic/prof.hh>
50 #include <basic/database/open.hh>
51 #include <basic/Tracer.hh>
52 #include <utility/io/izstream.hh>
53 
54 // C++
55 #include <iomanip>
56 #include <string>
57 
58 #include <utility/vector1.hh>
59 
60 //Auto Headers
61 //#include <core/import_pose/import_pose.hh>
62 
63 namespace core {
64 namespace scoring {
65 namespace saxs {
66 
67 static basic::Tracer trSAXSEnergy("core.scoring.saxs.SAXSEnergy");
68 
69 std::string SAXSEnergy::fa_cfg_file_("ff-rosetta-fa.cfg");
70 std::string SAXSEnergy::cen_cfg_file_("ff-rosetta-cen.cfg");
71 
73  ScoreTypes sts;
74  sts.push_back( saxs_score );
75  return sts;
76 }
77 
79 
83 }
84 
85 /// c-tor
87  ScoreType the_variant,SAXSEnergyCreator* creator) : WholeStructureEnergy( creator ) {
88 
89  using namespace basic::options;
90  using namespace basic::options::OptionKeys;
91 
92  saxs_score_variant_ = the_variant;
93  trSAXSEnergy.Warning << "SAXS score setup : " << the_variant << std::endl;
94  init_ff(config_file);
95  set_up_q();
96  the_config_file_ = config_file;
97 
98  score_bias_ = option[score::saxs::min_score]();
99  score_bias_ = std::pow(10,score_bias_);
100 
101  if(option[score::saxs::ref_spectrum].user()) {
102  std::string file = option[score::saxs::ref_spectrum]();
103  trSAXSEnergy << "Reading reference spectrum: " << file << std::endl;
105  } else {
106  if ( basic::options::option[in::file::native].user() ) {
107  core::pose::Pose reference_pose;
108  trSAXSEnergy << "Using "<<basic::options::option[in::file::native]()<<" as a reference for SAXS energy"<<std::endl;
109  //core::import_pose::pose_from_pdb(reference_pose, *rsd_set,basic::options::option[in::file::native]());
110  core::io::pdb::build_pose_from_pdb_as_is(reference_pose, *rsd_set, basic::options::option[in::file::native]());
112  trSAXSEnergy << "Calculated reference spectrum from a native: "
113  << basic::options::option[in::file::native]() << std::endl;
114  }
115  }
116 }
117 
118 /// c-tor
120  const utility::vector1<Real> & source_q,
121  const utility::vector1<Real> & reference_spectrum,
122  ScoreType score_variant,
123  SAXSEnergyCreator* the_creator) :
124  WholeStructureEnergy( the_creator ) {
125 
126  saxs_score_variant_ = score_variant;
127  the_config_file_ = config_file;
128  init_ff(config_file);
129  set_up_q(source_q);
130  fit_intensities(source_q,reference_spectrum,reference_intensities_);
131 }
132 
134 
135  using namespace basic::options;
136  using namespace basic::options::OptionKeys;
137 
138  Real s_min_ = basic::options::option[score::saxs::q_min]();
139  Real s_max_ = basic::options::option[score::saxs::q_max]();
140  Real s_step_ = basic::options::option[score::saxs::q_step]();
141  q_.clear();
142  for(Real s=s_min_;s<=s_max_;s+=s_step_)
143  q_.push_back(s);
144  pose_intensities_.resize(q_.size());
145  reference_intensities_.resize( q_.size() );
146 
147  trSAXSEnergy.Warning << "SAXS score q-set : " << q_.size() << " points from a file given at cmdline"<< std::endl;
148 }
149 
151 
152  q_.resize( source_q.size() );
153  for(Size i=1;i<=q_.size();i++)
154  q_[i] = source_q[i];
155  pose_intensities_.resize( source_q.size() );
156  reference_intensities_.resize( source_q.size() );
157  trSAXSEnergy.Warning << "SAXS score q-set : " << q_.size() << " points as a deep copy"<< std::endl;
158 }
159 
160 void SAXSEnergy::init_ff(const std::string & config_file) {
161 
162  using namespace basic::options;
163  using namespace basic::options::OptionKeys;
164 
166  if ( basic::options::option[score::saxs::custom_ff].user() ) {
167  trSAXSEnergy << "Loading custom FF from "<<basic::options::option[score::saxs::custom_ff]()<<std::endl;
168  ff_manager_->load_ff( basic::options::option[score::saxs::custom_ff]() );
169  } else {
170  ff_manager_->load_ff_from_db(basic::database::full_name( "scoring/score_functions/saxs/" + config_file ));
171  }
172 
173  if_hydrogens_=false;
174 }
175 
176 
178 
179  if( q_.size() != pose_intensities_.size() )
180  pose_intensities_.resize( q_.size() );
182 
184 }
185 
187  EnergyMap & totals ) const {
188 
189 // PROF_START( basic::SAXS );
190  if(q_.size() != pose_intensities_.size())
191  pose_intensities_.resize( q_.size() );
193 // totals[ saxs_score_variant_ ] = compute_L1(pose_intensities,reference_intensities_);
195 // PROF_STOP( basic::SAXS );
196 
197 }
198 
200 
201  Real tX,tY;
202  utility::io::izstream input(file_name.c_str());
203  if ( !input.good() )
204  utility_exit_with_message( "Unable to open reference spectrum file: " + file_name );
205  std::string line;
206  while( getline( input, line ) ) {
207  if ( line.substr(0,1) == "#" ) continue;
208  if ( line.length() < 4 ) continue;
209  std::istringstream line_stream( line );
210  line_stream >> tX >> tY;
211  q.push_back( tX );
212  I.push_back( tY );
213  trSAXSEnergy.Trace << "Reference SAXS data: "<<tX<<" "<<tY<<std::endl;
214  }
215 }
216 
218  utility::vector1<Real> & result) const {
219 
220  Real minX,minY;
221  Real maxX,maxY;
222 
223  minX = maxX = q[1];
224  maxY = minY = I[1];
225  for(Size i=2;i<=q.size();i++) {
226  if(q[i] < minX) minX = q[i];
227  if(q[i] > maxX) maxX = q[i];
228  if(I[i] < minY) minY = I[i];
229  if(I[i] > maxY) maxY = I[i];
230  }
231 
232  Real delta = 0.1;
233  numeric::interpolation::spline::SplineGenerator gen( minX-delta, minY-delta, 0, maxX+delta, maxY+delta, 0 );
234  for (Size i = 1; i <= q.size(); ++i) {
235  gen.add_known_value( q[i],I[i] );
236  }
237  utility::pointer::owning_ptr< numeric::interpolation::spline::Interpolator > spline_interpolator = gen.get_interpolator();
238 
239  if( result.size() != q_.size() ) {
240  result.clear();
241  result.resize( q_.size() );
242  }
243  Real dy = 0.0;
244  for(Size i_s=1;i_s<=q_.size();++i_s) {
245  Real r;
246  spline_interpolator->interpolate(q_[i_s], r, dy);
247  result[i_s] = r;
248  }
249 }
250 
252 
255  read_spectrum(file_name,x,y);
256  fit_intensities(x,y,result);
257 }
258 
259 
261 
262  // ---------- Tabulate form factors
264  std::set<FormFactorOP> ff_set;
265  // ---------- Find the unique set of atom types
266  for ( Size i = 1; i <= pose.total_residue(); ++i ) {
267  core::conformation::Residue resi = pose.residue(i);
268  for ( Size m = 1; m <= resi.natoms(); ++m ) {
269  trSAXSEnergy.Trace << "rehash: trying "<<resi.atom_type(m).name();
270  if((! if_hydrogens_)&&( resi.atom_type(m).is_hydrogen())) {
271  trSAXSEnergy.Trace << " rejected hydrogen"<<std::endl;
272  continue;
273  }
274  if( ! ff_manager_->is_known_atom( resi.atom_type(m).name() ) ) {
275  trSAXSEnergy.Trace << " rejected unknown"<<std::endl;
276  continue;
277  }
278  FormFactorOP fi = ff_manager_->get_ff(resi.atom_type(m).name());
279  ff_set.insert( fi );
280  }
281  }
282 
283  // ---------- Repack the set of unique FFs to a vactor and hash their indexes in with a map
284  std::set<FormFactorOP>::iterator it;
285  ff_ops_.clear();
286  ff_map_.clear();
287  Size i = 1;
288  for (it=ff_set.begin(); it!=ff_set.end(); it++) {
289  ff_map_.insert( std::pair<FormFactorOP,Size>(*it,i) );
290  ff_ops_.push_back( *it );
291  i++;
292  }
293 
294  // ---------- Create a matrix of distance histograms
295  for(Size i=1;i<=ff_ops_.size();i++) {
297  dhist_.push_back( row );
298  for(Size j=1;j<=ff_ops_.size();j++) {
299  dhist_[i].push_back( new DistanceHistogram() );
300  }
301  }
302 
303  // ---------- Prepare atoms, residues and assign atom types
304  for ( Size i = 1; i <= pose.total_residue(); ++i ) {
305  core::conformation::Residue resi = pose.residue(i);
306  for ( Size m = 1; m <= resi.natoms(); ++m ) {
307  if((! if_hydrogens_)&&( resi.atom_type(m).is_hydrogen()))
308  continue;
309  if( ! ff_manager_->is_known_atom( resi.atom_type(m).name() ) )
310  continue;
311  r_ids_.push_back( i );
312  a_ids_.push_back( m );
313  FormFactorOP fi = ff_manager_->get_ff(resi.atom_type(m).name());
314  atom_ff_types_.push_back( ff_map_[fi] );
315  }
316  }
317  trSAXSEnergy.Debug << "Found "<<atom_ff_types_.size()<<" atoms suitable for SAXS computations"<<std::endl;
320  trSAXSEnergy.Debug << "Zero-intensity is: "<<zero_<<std::endl;
321 }
322 
324 
325 
326  for(Size i=1;i<=ff_ops_.size();i++)
327  for(Size j=1;j<=ff_ops_.size();j++)
328  dhist_[i][j]->zeros();
329 
330  /*********** Compute distance histogram ************/
331  for ( Size i = 2; i <= r_ids_.size(); ++i ) {
332  Size res_i = r_ids_[i];
333  Size atm_i = a_ids_[i];
334  Size ti = atom_ff_types_[i];
335  numeric::xyzVector<Real> ai = pose.residue(res_i).xyz(atm_i);
336  for ( Size j = 1; j < i; ++j ) {
337  Size res_j = r_ids_[j];
338  Size atm_j = a_ids_[j];
339  Size tj = atom_ff_types_[j];
340  Real d = ai.distance( pose.residue(res_j).xyz(atm_j) );
341  if( tj <= ti )
342  dhist_[ ti ][ tj ]->insert(d);
343  else
344  dhist_[ tj ][ ti ]->insert(d);
345  }
346  }
347 
348 }
349 
351 
352 
353  SinXOverX *sin_x_by_x_ = SinXOverX::get_instance();
354 
355  if(ff_ops_.size() == 0) rehash_form_factors(pose);
356 
359 
360  for(Size i_s=1;i_s<=q_.size();++i_s) {
361 
362  Real sum(0);
363  Real val_s = q_[i_s];
364  for ( Size i = 1; i <= ff_ops_.size(); ++i ) {
365  Real fi = ff_ops_[i]->get(i_s);
366  for ( Size j = 1; j <= i; ++j ) {
367  Real fij = ff_ops_[j]->get(i_s) * fi;
368  DistanceHistogramOP dh = dhist_[i][j];
369  for(Size i_r=1;i_r<= dh->last_nonempty_bin();++i_r) { // ---------- Go through histogram bins
370  Size dn = dh->get( i_r );
371  if( dn > 0 )
372  sum += fij * dn * sin_x_by_x_->evaluate( dh->distance( i_r ) * val_s );
373  }
374  }
375  }
376 
377 // trSAXSEnergy.Trace <<std::setw(8)<<std::setprecision(4)<<val_s<<" "
378 // << std::setw(8)<<std::setprecision(4)<<sum<<std::endl;
379  result[i_s] = sum;
380  }
381 // trSAXSEnergy.Debug << "SAXS score: "<<ff_ops_.size()<<" atoms suitable for SAXS computations"<<std::endl;
382 }
383 
385 
386  Real sum(0);
387  for(Size i=1;i<=ff_ops_.size();i++)
388  for(Size j=1;j<=ff_ops_.size();j++) {
389  sum += dhist_[i][j]->total() * ff_ops_[i]->get(1) * ff_ops_[j]->get(1);
390  }
391  return 2.0 * sum;
392 }
393 
394 
395 Real SAXSEnergy::compute_L1(utility::vector1<Real> const & saxs_scored, utility::vector1<Real> const & saxs_reference) const {
396 
397  Real chi = -1.0;
398  Real sum = 0;
399  assert( saxs_scored.size() == saxs_reference.size() );
400  for(Size i=1;i<=saxs_scored.size();++i)
401  sum += saxs_reference[i] / saxs_scored[i];
402  Real lambda = sum / ((Real) saxs_scored.size());
403 
404  trSAXSEnergy.Trace << "\nComputing SAXS energy:\n";
405  trSAXSEnergy.Trace << " q pose reference\n";
406  for(Size i=1;i<=saxs_reference.size();++i) {
407  Real tmp = saxs_scored[i] * lambda - saxs_reference[i];
408  trSAXSEnergy.Trace << i<<" " << saxs_scored[i] * lambda <<" "<< saxs_reference[i] << "\n";
409  if( fabs(tmp) > chi )
410  chi = fabs(tmp);
411  }
412  trSAXSEnergy.Trace <<std::endl;
413 
414  trSAXSEnergy.Debug << "\nSAXS energy: " << chi << std::endl;
415  return chi;
416 }
417 
418 Real SAXSEnergy::compute_chi(utility::vector1<Real> const & saxs_scored, utility::vector1<Real> const & saxs_reference) const {
419 
420  Real chi = 0;
421  //Real sum = 0;
422  assert( saxs_scored.size() == saxs_reference.size() );
423 
424  trSAXSEnergy.Trace << "\nComputing SAXS energy:\n";
425  trSAXSEnergy.Trace << "norm(0): "<<zero_<<"\n";
426  trSAXSEnergy.Trace << " q pose pose*lambda reference\n";
427  for(Size i=1;i<=saxs_reference.size();++i) {
428  Real tmp = saxs_scored[i] - saxs_reference[i];
429  tmp /= zero_;
430  trSAXSEnergy.Trace << i<<" " << saxs_scored[i]/zero_ <<" "<< saxs_reference[i]/ zero_
431  << " " << (saxs_scored[i] / zero_ - saxs_reference[i]/ zero_) << "\n";
432  chi += tmp*tmp / saxs_reference[i] * zero_;
433  }
434  trSAXSEnergy.Trace <<std::endl;
435  chi /= ((Real) q_.size()) ;
436 
437 // Real energy = chi;
438  Real energy = log10(chi + score_bias_);
439  trSAXSEnergy.Debug << "\nSAXS chi2, energy, n_atoms: " << chi << " " << energy << " " << atom_ff_types_.size() << std::endl;
440  return energy;
441 }
442 
443 
444 Real SAXSEnergy::compute_chi_with_fit(utility::vector1<Real> const & saxs_scored, utility::vector1<Real> const & saxs_reference) const {
445 
446  Real chi = 0;
447  Real sum = 0;
448  assert( saxs_scored.size() == saxs_reference.size() );
449  for(Size i=1;i<=saxs_scored.size();++i)
450  sum += saxs_reference[i] / saxs_scored[i];
451  Real lambda = sum / ((Real) saxs_scored.size());
452 
453  trSAXSEnergy.Trace << "\nComputing SAXS energy:\n";
454  trSAXSEnergy.Trace << "lambda: "<<lambda<<"\n";
455  trSAXSEnergy.Trace << "norm(0): "<<zero_<<"\n";
456  trSAXSEnergy.Trace << " q pose pose*lambda reference\n";
457  for(Size i=1;i<=saxs_reference.size();++i) {
458  Real tmp = saxs_scored[i] * lambda / zero_ - saxs_reference[i] / zero_;
459  trSAXSEnergy.Trace << i<<" " << saxs_scored[i]<<" "<<saxs_scored[i] * lambda/ zero_ <<" "<< saxs_reference[i]/ zero_
460  << " " << (saxs_scored[i] * lambda / zero_ - saxs_reference[i]/ zero_) << "\n";
461  chi += tmp*tmp;
462  }
463  trSAXSEnergy.Trace <<std::endl;
464  chi /= ((Real) q_.size());
465 
466 // Real energy = chi;
467  Real energy = log10(chi + score_bias_);
468  trSAXSEnergy.Debug << "\nSAXS chi2, energy, n_atoms: " << chi << " " << energy << " " << atom_ff_types_.size() << std::endl;
469  return energy;
470 }
471 
474 {
475  return 1; // Initial versioning
476 }
477 
478 
479 } // saxs
480 } // scoring
481 } // core
482