Rosetta 3.5
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
OptEData.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 protocols/optimization/OptEData.cc
11 /// @author ashworth
12 /// @author Jim Havranek
13 /// @author Andrew Leaver-Fay
14 
15 #ifdef USEMPI
16 #include <mpi.h>
17 #endif
18 
19 
20 // Unit headers
26 #ifdef USEMPI
28 #endif
29 
30 // Project headers
33 // AUTO-REMOVED #include <basic/options/util.hh>
34 
35 #include <utility/LexicographicalIterator.hh>
36 #include <utility/string_util.hh>
37 #include <utility/vector1.functions.hh>
38 #include <utility/exit.hh>
39 
40 #include <ObjexxFCL/format.hh>
41 
42 #include <numeric/numeric.functions.hh>
43 #include <numeric/statistics.functions.hh>
44 
45 #include <fstream>
46 #include <ostream>
47 #include <sstream>
48 #include <string>
49 #include <cmath>
50 
51 #include <basic/Tracer.hh>
52 
53 // option key includes
54 #include <basic/options/keys/optE.OptionKeys.gen.hh>
55 #include <basic/options/keys/corrections.OptionKeys.gen.hh>
56 
57 //Auto Headers
58 #include <utility/vector1.hh>
59 #include <basic/options/option.hh>
60 
61 
62 
63 using basic::T;
64 using basic::Error;
65 using basic::Warning;
66 
67 using namespace core;
68 using namespace scoring;
69 using namespace ObjexxFCL::fmt;
70 
71 namespace protocols {
72 namespace optimize_weights {
73 
74 /// @details Auto-generated virtual destructor
75 OptEData::~OptEData() {}
76 
77 /// @details Auto-generated virtual destructor
78 PNatRotOptERotamerData::~PNatRotOptERotamerData() {}
79 
80 /// @details Auto-generated virtual destructor
81 PNatAAOptERotamerData::~PNatAAOptERotamerData() {}
82 
83 static basic::Tracer TR("protocols.optimize_weights.OptEData");
84 
85 ///@begin (ostream operator for OptERotamerDataOP)
86 ///@author ashworth
87 std::ostream & operator << ( std::ostream & os, PNatAAOptERotamerDataOP rd )
88 {
89  os << rd->rot_number() << "," << rd->this_aa() << ",";
90 
91  utility::vector1< Real > const & fixed_data( rd->fixed_data() );
92  for ( utility::vector1< Real >::const_iterator fd( fixed_data.begin() );
93  fd != fixed_data.end(); ++fd ) {
94  if ( fd != fixed_data.begin() ) os << " ";
95  os << *fd;
96  }
97  os << ",";
98 
99  utility::vector1< Real > const & data( rd->data() );
100  for ( utility::vector1< Real >::const_iterator d( data.begin() );
101  d != data.end(); ++d ) {
102  if ( d != data.begin() ) os << " ";
103  os << *d;
104  }
105  return os;
106 }
107 
108 //
109 // ------------------- OptEPositionData -----------------------//
110 //
111 
112 OptEPositionData::OptEPositionData()
113 {}
114 
115 OptEPositionData::~OptEPositionData()
116 {}
117 
118 void
119 OptEPositionData::update_range(
121  ScoreTypes const & free_score_list,
122  ScoreTypes const & fixed_score_list,
123  EnergyMap & lower_bound,
124  EnergyMap & upper_bound
125 ) const
126 {
127  for ( Size ii = 1; ii <= free_score_list.size(); ++ii ) {
128  Real ii_min = lower_bound[ free_score_list[ ii ] ];
129  Real ii_max = upper_bound[ free_score_list[ ii ] ];
130  if ( ii_min > structure->free_data()[ ii ] ) {
131  ii_min = structure->free_data()[ ii ];
132  }
133  if ( ii_max < structure->free_data()[ ii ] ) {
134  ii_max = structure->free_data()[ ii ];
135  }
136  lower_bound[ free_score_list[ ii ] ] = ii_min;
137  upper_bound[ free_score_list[ ii ] ] = ii_max;
138  }
139 
140  for ( Size ii = 1; ii <= fixed_score_list.size(); ++ii ) {
141  Real ii_min = lower_bound[ fixed_score_list[ ii ] ];
142  Real ii_max = upper_bound[ fixed_score_list[ ii ] ];
143  if ( ii_min > structure->fixed_data()[ ii ] ) {
144  ii_min = structure->fixed_data()[ ii ];
145  }
146  if ( ii_max < structure->fixed_data()[ ii ] ) {
147  ii_max = structure->fixed_data()[ ii ];
148  }
149  lower_bound[ fixed_score_list[ ii ] ] = ii_min;
150  upper_bound[ fixed_score_list[ ii ] ] = ii_max;
151  }
152 }
153 
154 void
155 OptEPositionData::tag( std::string const & tag_in )
156 {
157  tag_ = tag_in;
158 }
159 
160 std::string const &
161 OptEPositionData::tag() const
162 {
163  return tag_;
164 }
165 
166 #ifdef USEMPI
167 void
168 OptEPositionData::send_to_node(
169  int const destination_node,
170  int const tag
171 ) const
172 {
173  int len( tag_.size() );
174  MPI_Send( &len, 1, MPI_INT, destination_node, tag, MPI_COMM_WORLD );
175  MPI_Send( const_cast< char * > (tag_.c_str()), len, MPI_CHAR, destination_node, tag, MPI_COMM_WORLD );
176 }
177 
178 void
179 OptEPositionData::receive_from_node(
180  int const source_node,
181  int const tag
182 )
183 {
184  MPI_Status stat;
185 
186  int len( 0 );
187  MPI_Recv( &len, 1, MPI_INT, source_node, tag, MPI_COMM_WORLD, & stat );
188  char * str = new char[ len + 1 ];
189  str[ len ] = '\0'; // ? do I need null terminated strings?
190  MPI_Recv( str, len, MPI_CHAR, source_node, tag, MPI_COMM_WORLD, & stat );
191  std::string tag_from_node( str, len );
192  delete [] str;
193  tag_ = tag_from_node;
194 }
195 #endif
196 
197 
198 //
199 // ------------------- PNatAAOptEPositionData -----------------------//
200 //
201 
202 PNatAAOptEPositionData::PNatAAOptEPositionData()
203 {}
204 
205 PNatAAOptEPositionData::~PNatAAOptEPositionData()
206 {}
207 
208 /// Does actual work for OptE minimization
209 /// @details Determine the metric for optimization of energy weights. Original source
210 /// is Brian Kuhlman's FORTRAN weight training program. Since the goal is to
211 /// maximize site-by-site sequence recovery, the metric is decomposable by
212 /// positions, and this does the work for one position. First, a pass is made
213 /// through all the rotamers at the position, and the lowest energy rotamer for
214 /// each amino acid is identified. Next, a rough partition function is constructed.
215 /// The score to be minimized is the negative log of the probabilty of selecting
216 /// a native aa rotamer (needn't be the native _conformation_).
217 /// @details Limitations:
218 /// 1. Assumes that the choices available at each position are the 20 canonical
219 /// amino acids - no DNA base recovery, no pTyr.
220 /// 2. Doesn't have Chris Saunder's compositional constraints. This would
221 /// require implementation of a direction-set ( aka powell ) minimizer, as his
222 /// optimization metric doesn't yield gradients.
223 //
224 Real
225 PNatAAOptEPositionData::get_score(
226  optimization::Multivec const & component_weights,
227  optimization::Multivec const & vars,
228  optimization::Multivec & dE_dvars,
229  /// Basically, turn over all the private data from OptEMultiFunc
230  Size const num_energy_dofs,
231  int const num_ref_dofs,
232  int const,
233  EnergyMap const & fixed_terms,
234  ScoreTypes const & score_list,
235  ScoreTypes const & fixed_score_list
236 ) const
237 {
238  using namespace core::optimization;
239  using namespace basic::options;
240  using namespace basic::options::OptionKeys;
241 
242  Size const aa_range( chemical::num_canonical_aas );
243  chemical::AA const this_native_aa( native_aa() );
244 
245  static Real const inv_kT( option[ optE::inv_kT_nataa ] );
246 
247  // contains the best energy for each amino acid at this position
248  utility::vector1< Real > best_energy_by_aa( aa_range, 1000.0 );
249 
250  // containers for derivatives
251  Multivec ref_deriv_weight( aa_range, 0.0 );
252  utility::vector1< Real > dummy_set( score_list.size(), 0.0 );
253  utility::vector1< utility::vector1< Real > > unweighted_E_dof( aa_range, dummy_set );
254 
255  process_rotamers(
256  vars, num_energy_dofs, fixed_terms, score_list, fixed_score_list, aa_range, dummy_set,
257  best_energy_by_aa, unweighted_E_dof, ref_deriv_weight );
258 
259  //Real const very_best = utility::min( best_energy_by_aa );
260  //for ( Size ii = 1; ii <= best_energy_by_aa.size(); ++ii ) {
261  // best_energy_by_aa[ ii ] -= very_best;
262  //}
263 
264 
265  // now do the partition function analysis
266  // reference energy deriv
267 
268  Real numerator(0.0), partition(0.0);
269  Multivec dpartition( vars.size(), 0.0 ), dnumerator( vars.size(), 0.0 );
270 
271  for( Size aa(1); aa <= aa_range; ++aa ) {
272 
273  Real const exp_term( std::exp( -1.0 * inv_kT * best_energy_by_aa[ aa ] ) );
274  partition += exp_term;
275  if ( aa == size_t(this_native_aa) )
276  numerator = exp_term;
277 
278  // for reference energy derivatives, but don't assume the protocol is using them
279  // note for derivatives: d/dw( e^-(E*w+...) ) = -E * e^-(E*w+...) but as this is an energy, the 'weight' here is 0 or 1
280  if ( num_ref_dofs != 0 ) {
281  Real const ref_deriv_term( -1.0 * inv_kT * ref_deriv_weight[ aa ] * exp_term );
282  dpartition[ num_energy_dofs + aa ] = ref_deriv_term;
283  if ( aa == size_t(this_native_aa) )
284  dnumerator[ num_energy_dofs + aa ] = ref_deriv_term;
285  }
286 
287  // partitions for energy derivatives
288  // note for derivatives: d/dw( e^-(E*w+...) ) = -E * e^-(E*w+...)
289  for( Size e_dof(1); e_dof <= num_energy_dofs; ++e_dof ) {
290  Real e_dof_deriv( -1.0 * inv_kT * unweighted_E_dof[ aa ][ e_dof ] * exp_term );
291  dpartition[ e_dof ] += e_dof_deriv;
292  if ( aa == size_t(this_native_aa) )
293  dnumerator[ e_dof ] = e_dof_deriv;
294  }
295  }
296 
297  // accumulate to passed-in derivative sums
298  for ( Size dof(1); dof <= vars.size(); ++dof ) {
299  dE_dvars[ dof ] += component_weights[ type() ] * ( dpartition[ dof ] / partition - dnumerator[ dof ] / numerator );
300  }
301 
302  return ( -1.0 * component_weights[ type() ] * std::log( numerator / partition ) );
303 }
304 
305 void
306 PNatAAOptEPositionData::print_score(
307  std::ostream & ostr,
308  optimization::Multivec const & component_weights,
309  optimization::Multivec const & vars,
310  optimization::Multivec & dE_dvars,
311  /// Basically, turn over all the private data from OptEMultiFunc
312  Size const num_energy_dofs,
313  int const num_ref_dofs,
314  int const,
315  EnergyMap const & fixed_terms,
316  ScoreTypes const & score_list,
317  ScoreTypes const & fixed_score_list
318 ) const
319 {
320  //TR << "PNatAAOptEPositionData::print_score" << std::endl;
321  using namespace core::optimization;
322  using namespace basic::options;
323  using namespace basic::options::OptionKeys;
324 
325  Size const aa_range( chemical::num_canonical_aas );
326  chemical::AA const this_native_aa( native_aa() );
327 
328 
329  static Real const inv_kT( option[ optE::inv_kT_nataa ] );
330 
331  // contains the best energy for each amino acid at this position
332  utility::vector1< Real > best_energy_by_aa( aa_range, 1000.0 );
333 
334  // containers for derivatives
335  Multivec ref_deriv_weight( aa_range, 0.0 );
336  utility::vector1< Real > dummy_set( score_list.size(), 0.0 );
337  utility::vector1< utility::vector1< Real > > unweighted_E_dof( aa_range, dummy_set );
338 
339  process_rotamers(
340  vars, num_energy_dofs, fixed_terms, score_list, fixed_score_list, aa_range, dummy_set,
341  best_energy_by_aa, unweighted_E_dof, ref_deriv_weight );
342 
343  // now do the partition function analysis
344  // reference energy deriv
345 
346  Real numerator(0.0), partition(0.0);
347  Multivec dpartition( vars.size(), 0.0 ), dnumerator( vars.size(), 0.0 );
348 
349  for( Size aa(1); aa <= aa_range; ++aa ) {
350 
351  Real const exp_term( std::exp( -1.0 * inv_kT * best_energy_by_aa[ aa ] ) );
352  partition += exp_term;
353  if ( aa == size_t(this_native_aa) ) numerator = exp_term;
354 
355  // for reference energy derivatives, but don't assume the protocol is using them
356  // note for derivatives: d/dw( e^-(E*w+...) ) = -E * e^-(E*w+...) but as this is an energy, the 'weight' here is 0 or 1
357  if ( num_ref_dofs != 0 ) {
358  Real const ref_deriv_term( -1.0 * inv_kT * ref_deriv_weight[ aa ] * exp_term );
359  dpartition[ num_energy_dofs + aa ] = ref_deriv_term;
360  if ( aa == size_t(this_native_aa) ) dnumerator[ num_energy_dofs + aa ] = ref_deriv_term;
361  }
362 
363  // partitions for energy derivatives
364  for( Size e_dof(1); e_dof <= num_energy_dofs; ++e_dof ) {
365  // note for derivatives: d/dw( e^-(E*w+...) ) = -E * e^-(E*w+...)
366  Real e_dof_deriv( -1.0 * inv_kT * unweighted_E_dof[ aa ][ e_dof ] * exp_term );
367  dpartition[ e_dof ] += e_dof_deriv;
368  if ( aa == size_t(this_native_aa) ) dnumerator[ e_dof ] = e_dof_deriv;
369  }
370  }
371 
372  // accumulate to passed-in derivative sums
373  for ( Size dof(1); dof <= vars.size(); ++dof ) {
374  dE_dvars[ dof ] += dpartition[ dof ] / partition - dnumerator[ dof ] / numerator;
375  }
376 
377  ostr << "PNATAA " << tag() << X(1) << this_native_aa << "," << I(2, (int)this_native_aa) << X(1)
378  << " nbs: " << I(2,neighbor_count())
379  << " num: " << F(7,3,numerator) << " part: " << F(7,3,partition)
380  << " p: " << F(7,5,numerator / partition)
381  << " -lnp: " << F(6,4,-1.0 * std::log( numerator / partition ))
382  << " -compwt_lnp: " << F(6, 4, component_weights[ type() ] * (-1.0 * std::log( numerator / partition )) )
383  << std::endl;
384 
385  //ostr << "PNATAA " << this_native_aa << " " << (int) this_native_aa << " ";
386  //ostr << " nneighb: " << neighbor_count_ << " p: " << numerator / partition << " -lnp: ";
387  //ostr << -1.0 * std::log( numerator / partition );
388  //ostr << " -compwt_lnp: " << component_weights[ type() ] * -1.0 * std::log( numerator / partition );
389  //ostr << " " << tag() << "\n";
390 
391  //TR << "PNatAAOptEPositionData::print_score done" << std::endl;
392 
393  return;// ( -1.0 * std::log( numerator / partition ) );
394 }
395 
396 void
398  ScoreTypes const & free_score_list,
399  ScoreTypes const & fixed_score_list,
400  EnergyMap & lower_bound,
401  EnergyMap & upper_bound
402 ) const
403 {
404  for ( Size ii = 1; ii <= free_score_list.size(); ++ii ) {
405  Real ii_min = lower_bound[ free_score_list[ ii ] ];
406  Real ii_max = upper_bound[ free_score_list[ ii ] ];
407  for( PNatAAOptERotamerDataOPs::const_iterator iter = rotamer_data_begin(),
408  e_itr = rotamer_data_end() ; iter != e_itr; ++iter ) {
409  if ( ii_min > (*iter)->data()[ ii ] ) {
410  ii_min = (*iter)->data()[ ii ];
411  }
412  if ( ii_max < (*iter)->data()[ ii ] ) {
413  ii_max = (*iter)->data()[ ii ];
414  }
415  }
416  lower_bound[ free_score_list[ ii ] ] = ii_min;
417  upper_bound[ free_score_list[ ii ] ] = ii_max;
418  }
419 
420  for ( Size ii = 1; ii <= fixed_score_list.size(); ++ii ) {
421  Real ii_min = lower_bound[ fixed_score_list[ ii ] ];
422  Real ii_max = upper_bound[ fixed_score_list[ ii ] ];
423  for( PNatAAOptERotamerDataOPs::const_iterator iter = rotamer_data_begin(),
424  e_itr = rotamer_data_end() ; iter != e_itr; ++iter ) {
425  if ( ii_min > (*iter)->fixed_data()[ ii ] ) {
426  ii_min = (*iter)->fixed_data()[ ii ];
427  }
428  if ( ii_max < (*iter)->fixed_data()[ ii ] ) {
429  ii_max = (*iter)->fixed_data()[ ii ];
430  }
431  }
432  lower_bound[ fixed_score_list[ ii ] ] = ii_min;
433  upper_bound[ fixed_score_list[ ii ] ] = ii_max;
434  }
435 }
436 
437 void
438 PNatAAOptEPositionData::process_rotamers(
439  optimization::Multivec const & vars,
440  Size const num_energy_dofs,
441  EnergyMap const & fixed_terms,
442  ScoreTypes const &,
443  ScoreTypes const & fixed_score_list,
444  Size const ,
445  utility::vector1< Real > const & dummy_set,
446  utility::vector1< Real > & best_energy_by_aa,
447  utility::vector1< utility::vector1< Real > > & unweighted_E_dof,
448  optimization::Multivec & ref_deriv_weight
449 ) const
450 {
451  for( PNatAAOptERotamerDataOPs::const_iterator itr = rotamer_data_begin(), e_itr = rotamer_data_end() ; itr != e_itr; ++itr ) {
452  int const this_aa( (*itr)->this_aa() );
453 
454  Real weighted_energy( 0.0 );
455  // Variable-weighted energy terms
456  for( Size ii = 1; ii <= num_energy_dofs; ++ii ) {
457  weighted_energy += vars[ ii ] * ((**itr)[ ii ]);
458  }
459  // Fixed-weight energy terms
460  for( Size ii = 1; ii <= fixed_score_list.size(); ++ii ) {
461  weighted_energy += fixed_terms[ fixed_score_list[ ii ] ] * (*itr)->fixed_data()[ ii ];
462  }
463  // Reference energy term
464  // Don't count this unless we're definitely using reference energies. If the vars vector has more values in it than the
465  // number of energy dofs, that means reference energies are in use. Prob. a better way to do this, but this should work.
466  if ( vars.size() > num_energy_dofs ) {
467  weighted_energy += vars[ num_energy_dofs + this_aa ];
468  }
469 
470  Real const cutoff( 300.0 );
471  if( weighted_energy > cutoff ) weighted_energy = cutoff;
472  if( weighted_energy < -1.0*cutoff ) weighted_energy = -1.0*cutoff;
473 
474  if( weighted_energy < best_energy_by_aa[ this_aa ] ) {
475 
476  best_energy_by_aa[ this_aa ] = weighted_energy;
477 
478  //if (true) {
479  if( std::abs( weighted_energy ) < cutoff ) {
480  unweighted_E_dof[ this_aa ] = (*itr)->data();
481  ref_deriv_weight[ this_aa ] = 1.0;
482  } else {
483  // derivatives will be zero above and below cutoffs
484  unweighted_E_dof[ this_aa ] = dummy_set;
485  ref_deriv_weight[ this_aa ] = 0.0;
486  }
487  }
488  } // done processing rotamers
489 }
490 
491 
493 PNatAAOptEPositionData::type() const
494 {
495  return prob_native_amino_acid;
496 }
497 
498 
499 void
500 PNatAAOptEPositionData::write_to_file( std::ofstream & outfile ) const
501 {
502  outfile
503  << "position " << position() << " "
504  << "nataa " << native_aa() << " "
505  << "neighbor_count " << neighbor_count() << " "
506  << "nrots " << data_.size() << "\n";
507  for ( PNatAAOptERotamerDataOPs::const_iterator rot( rotamer_data_begin() );
508  rot != rotamer_data_end(); ++rot ) {
509  outfile << *rot << std::endl;
510  }
511 
512 }
513 
514 void
515 PNatAAOptEPositionData::read_from_file( std::ifstream & infile )
516 {
518  using namespace utility;
519 
520  // read first line with position, native aa, neighbor_count, and num_rotamers data
521  std::string line;
522  getline( infile, line );
523  Strings words( string_split( line, ' ' ) );
524  runtime_assert( words[ 1 ] == "position" );
525  position_ = from_string( words[ 2 ], Size( 0 ) );
526  runtime_assert( words[ 3 ] == "nataa" );
527  native_aa_ = chemical::aa_from_name( words[ 4 ] );
528  runtime_assert( words[ 5 ] == "neighbor_count" );
529  neighbor_count_ = from_string( words[ 6 ], Size( 0 ) );
530  runtime_assert( words[ 7] == "nrots" );
531  Size num_rotamers = from_string( words[ 8 ], Size( 0 ) );
532 
533  for ( Size ii = 1; ii <= num_rotamers; ++ii ) {
534  getline( infile, line );
535 
536  // rotamers for existing position: parse, append new OptERotamerDataOP to OptEPositionDataOP
537  Strings sections( string_split( line, ',' ) );
538  // sections:
539  // 0 - rotnum, 1 - aa three-letter code, 2 - energies for fixed terms, 3 - energies for free terms
540  Size rotnum;
541  std::istringstream ss( sections[1] );
542  ss >> rotnum;
543  chemical::AA aa( chemical::aa_from_name( sections[2] ) );
544  utility::vector1< Real > fixed_energies, energies;
545  Strings
546  fixed_vals( string_split( sections[3], ' ' ) ),
547  free_vals( string_split( sections[4], ' ' ) );
548  for ( Strings::iterator fixed_val( fixed_vals.begin() ); fixed_val != fixed_vals.end(); ++fixed_val ) {
549  Real val;
550  std::istringstream ss( *fixed_val );
551  ss >> val;
552  fixed_energies.push_back( val );
553  }
554  for ( Strings::iterator free_val( free_vals.begin() ); free_val != free_vals.end(); ++free_val ) {
555  Real val;
556  std::istringstream ss( *free_val );
557  ss >> val;
558  energies.push_back( val );
559  }
560  runtime_assert( !energies.empty() );
561  PNatAAOptERotamerDataOP new_rot_data = new PNatAAOptERotamerData( aa, rotnum, energies, fixed_energies );
562  add_rotamer_line_data( new_rot_data );
563  }
564 }
565 
566 void
567 PNatAAOptEPositionData::write_to_binary_file( std::ofstream & outfile ) const
568 {
570  typedef Energies::const_iterator Energies_CItr;
571 
572  // compiler wanted these temporary variables instead of calls to class accessor functions,
573  // which produced the error "non-lvalue in unary `&'"
574  //Size const position( (position_ ),
575  // neighbor_count( neighbor_count() );
576  //chemical::AA native_aa( native_aa() );
577  outfile.write( (char*) & position_, sizeof(Size) );
578  outfile.write( (char*) & native_aa_, sizeof(chemical::AA) );
579  outfile.write( (char*) & neighbor_count_, sizeof(Size) );
580 
581  Size const nrotamers( data().size() );
582  outfile.write( (char*) &nrotamers, sizeof(Size) );
583  for ( PNatAAOptERotamerDataOPs::const_iterator rot( data().begin() );
584  rot != data().end(); ++rot ) {
585  chemical::AA this_aa( (*rot)->this_aa() );
586  Size rot_number( (*rot)->rot_number() );
587  outfile.write( (char*) &this_aa, sizeof(chemical::AA) );
588  outfile.write( (char*) &rot_number, sizeof(Size) );
589 
590  Size const nfree( (*rot)->data().size() );
591  outfile.write( (char*) &nfree, sizeof(Size) );
592  for ( Energies_CItr energy( (*rot)->data().begin() );
593  energy != (*rot)->data().end(); ++energy ) {
594  outfile.write( (char*) &(*energy), sizeof(Real) );
595  }
596 
597  Size const nfixed( (*rot)->fixed_data().size() );
598  outfile.write( (char*) &nfixed, sizeof(Size) );
599  for ( Energies_CItr fixed_energy( (*rot)->fixed_data().begin() );
600  fixed_energy != (*rot)->fixed_data().end(); ++fixed_energy ) {
601  outfile.write( (char*) &(*fixed_energy), sizeof(Real) );
602  }
603  }
604 
605 
606 }
607 
608 
609 void
610 PNatAAOptEPositionData::read_from_binary_file( std::ifstream & infile )
611 {
613  typedef Energies::const_iterator Energies_CItr;
614 
615  //Size position(0), neighbor_count(0);
616  //chemical::AA nataa( chemical::aa_unk );
617  infile.read( (char*) & position_, sizeof(Size) );
618  infile.read( (char*) & native_aa_, sizeof(chemical::AA) );
619  infile.read( (char*) & neighbor_count_, sizeof(Size) );
620  //pos_data->set_position( position );
621  //pos_data->set_neighbor_count( neighbor_count );
622  //pos_data->set_native_aa( nataa );
623 
624  Size nrotamers(0);
625  infile.read( (char*) &nrotamers, sizeof(Size) );
626  for ( Size j(1); j <= nrotamers; ++j ) {
627 
628  chemical::AA rot_aa( chemical::aa_unk );
629  Size rot_number(0);
630  infile.read( (char*) &rot_aa, sizeof(chemical::AA) );
631  infile.read( (char*) &rot_number, sizeof(Size) );
632 
633  Energies energies, fixed_energies;
634  Size nfree(0);
635  infile.read( (char*) &nfree, sizeof(Size) );
636  for ( Size k(1); k <= nfree; ++k ) {
637  Real energy(0.0);
638  infile.read( (char*) &energy, sizeof(Real) );
639  energies.push_back( energy );
640  }
641 
642  Size nfixed(0);
643  infile.read( (char*) &nfixed, sizeof(Size) );
644  for ( Size k(1); k <= nfixed; ++k ) {
645  Real fixed_energy(0.0);
646  infile.read( (char*) &fixed_energy, sizeof(Real) );
647  fixed_energies.push_back( fixed_energy );
648  }
649  runtime_assert( !energies.empty() );
650 
651  PNatAAOptERotamerDataOP rot_data =
652  new PNatAAOptERotamerData( rot_aa, rot_number, energies, fixed_energies );
653  add_rotamer_line_data( rot_data );
654  }
655 }
656 
657 Size
658 PNatAAOptEPositionData::memory_use() const
659 {
660  Size total = sizeof( PNatAAOptEPositionData ) +
661  sizeof( PNatAAOptERotamerData ) * data_.size();
662  if ( data_.size() > 0 ) {
663  total += sizeof( Real ) * ( data_[ 1 ]->data().size() + data_[ 1 ]->fixed_data().size() ) * data_.size();
664  }
665  return total;
666 }
667 
668 
669 
670 #ifdef USEMPI
671 
672 void
673 PNatAAOptEPositionData::send_to_node( int const destination_node, int const tag ) const
674 {
675 
676  //TR << "PNatAAOptEPositionData::Sending data to node " << destination_node << std::endl;
677 
678  /// 3. Which position is this?
679  int ii_pos = position();
680  MPI_Send( & ii_pos, 1, MPI_INT, destination_node, tag, MPI_COMM_WORLD );
681 
682  /// 4. What is the native amino acid at this position?
683  int ii_aa = native_aa();
684  MPI_Send( & ii_aa, 1, MPI_INT, destination_node, tag, MPI_COMM_WORLD );
685 
686  /// 5. How many neighbors did this position have?
687  int ii_neighbor_count = neighbor_count();
688  MPI_Send( & ii_neighbor_count, 1, MPI_INT, destination_node, tag, MPI_COMM_WORLD );
689 
690  /// 6. The number of rotamers for this position
691  Size ii_num_rotamers = size();
692  MPI_Send( & ii_num_rotamers, 1, MPI_UNSIGNED_LONG, destination_node, tag, MPI_COMM_WORLD );
693 
694  if ( ii_num_rotamers == 0 ) return;
695 
696  Size free_count = data_[1]->data().size();
697  Size fixed_count = data_[1]->fixed_data().size();
698 
699  /// 6b The size of the free and fixed data, since that context is not available.
700  MPI_Send( & free_count, 1, MPI_UNSIGNED_LONG, destination_node, tag, MPI_COMM_WORLD );
701  MPI_Send( & fixed_count, 1, MPI_UNSIGNED_LONG, destination_node, tag, MPI_COMM_WORLD );
702 
703  int * ii_aa_types = new int[ ii_num_rotamers ];
704  int * ii_rot_nums = new int[ ii_num_rotamers ];
705  Real * free_data = new Real[ ii_num_rotamers * free_count ];
706  Real * fixed_data = new Real[ ii_num_rotamers * fixed_count ];
707  for ( Size jj = 1; jj <= ii_num_rotamers; ++jj ) {
708  ii_aa_types[ jj - 1 ] = data()[ jj ]->this_aa();
709  ii_rot_nums[ jj - 1 ] = data()[ jj ]->rot_number();
710  for ( Size kk = 1; kk <= free_count; ++kk ) {
711  free_data[ ( jj - 1 ) * free_count + kk - 1 ] = data()[ jj ]->data()[ kk ];
712  }
713  for ( Size kk = 1; kk <= fixed_count; ++kk ) {
714  fixed_data[ ( jj - 1 ) * fixed_count + kk - 1 ] = data()[ jj ]->fixed_data()[ kk ];
715  }
716  }
717 
718  /// 7. All the amino acids for all rotamers at this position
719  MPI_Send( ii_aa_types, ii_num_rotamers, MPI_INT, destination_node, tag, MPI_COMM_WORLD );
720 
721  /// 8. All the rotamer indices for all rotamers at this position
722  MPI_Send( ii_rot_nums, ii_num_rotamers, MPI_INT, destination_node, tag, MPI_COMM_WORLD );
723 
724  /// 9. All the free data for all rotamers
725  MPI_Send( free_data, ii_num_rotamers * free_count, MPI_DOUBLE, destination_node, tag, MPI_COMM_WORLD );
726 
727  /// 10. All the fixed data for all rotamers
728  MPI_Send( fixed_data, ii_num_rotamers * fixed_count, MPI_DOUBLE, destination_node, tag, MPI_COMM_WORLD );
729 
730  delete [] ii_aa_types; ii_aa_types = 0;
731  delete [] ii_rot_nums; ii_rot_nums = 0;
732  delete [] free_data; free_data = 0;
733  delete [] fixed_data; fixed_data = 0;
734 
735  //TR << "...data sent to node " << destination_node << std::endl;
736  OptEPositionData::send_to_node( destination_node, tag );
737 }
738 
739 
740 void
741 PNatAAOptEPositionData::receive_from_node( int const source_node, int const tag )
742 {
743  MPI_Status stat;
744 
745  //TR << "Recieving data from node... " << source_node << std::endl;
746 
747  /// 3. Which sequence position is this?
748  int ii_pos;
749  MPI_Recv( & ii_pos, 1, MPI_INT, source_node, tag, MPI_COMM_WORLD, &stat );
750  set_position( ii_pos );
751 
752  /// 4. What is the native amino acid at this position?
753  int ii_aa;
754  MPI_Recv( & ii_aa, 1, MPI_INT, source_node, tag, MPI_COMM_WORLD, &stat );
755  set_native_aa( (chemical::AA) ii_aa );
756 
757  /// 5. How many neighbors did this position have?
758  int ii_neighbor_count;
759  MPI_Recv( & ii_neighbor_count, 1, MPI_INT, source_node, tag, MPI_COMM_WORLD, &stat );
760  set_neighbor_count( ii_neighbor_count );
761 
762  /// 6. The number of rotamers for this position
763  Size ii_num_rotamers;
764  MPI_Recv( & ii_num_rotamers, 1, MPI_UNSIGNED_LONG, source_node, tag, MPI_COMM_WORLD, &stat );
765 
766  if ( ii_num_rotamers == 0 ) return;
767 
768  Size free_count(0);
769  Size fixed_count(0);
770 
771  /// 6b The size of the free and fixed data, since that context is not available.
772  MPI_Recv( & free_count, 1, MPI_UNSIGNED_LONG, source_node, tag, MPI_COMM_WORLD, &stat );
773  MPI_Recv( & fixed_count, 1, MPI_UNSIGNED_LONG, source_node, tag, MPI_COMM_WORLD, &stat );
774 
775 
776  int * ii_aa_types = new int[ ii_num_rotamers ];
777  int * ii_rot_nums = new int[ ii_num_rotamers ];
778  Real * free_data = new Real[ ii_num_rotamers * free_count ];
779  Real * fixed_data = new Real[ ii_num_rotamers * fixed_count ];
780 
781  /// 7. All the amino acids for all rotamers at this position
782  MPI_Recv( ii_aa_types, ii_num_rotamers, MPI_INT, source_node, tag, MPI_COMM_WORLD, &stat );
783 
784  /// 8. All the rotamer indices for all rotamers at this position
785  MPI_Recv( ii_rot_nums, ii_num_rotamers, MPI_INT, source_node, tag, MPI_COMM_WORLD, &stat );
786 
787  /// 9. All the free data for all rotamers
788  MPI_Recv( free_data, ii_num_rotamers * free_count, MPI_DOUBLE, source_node, tag, MPI_COMM_WORLD, &stat );
789 
790  /// 10. All the fixed data for all rotamers
791  MPI_Recv( fixed_data, ii_num_rotamers * fixed_count, MPI_DOUBLE, source_node, tag, MPI_COMM_WORLD, &stat );
792 
793  utility::vector1< Real > free_data_vect( free_count );
794  utility::vector1< Real > fixed_data_vect( fixed_count );
795 
796  for ( Size jj = 1; jj <= ii_num_rotamers; ++jj ) {
797  for ( Size kk = 1; kk <= free_count; ++kk ) {
798  free_data_vect[ kk ] = free_data[ ( jj - 1 ) * free_count + kk - 1 ];
799  }
800  for ( Size kk = 1; kk <= fixed_count; ++kk ) {
801  fixed_data_vect[ kk ] = fixed_data[ ( jj - 1 ) * fixed_count + kk - 1 ];
802  }
803  PNatAAOptERotamerDataOP jj_rotamer_data = new PNatAAOptERotamerData(
804  (chemical::AA ) ii_aa_types[ jj - 1 ],
805  ii_rot_nums[ jj - 1 ],
806  free_data_vect,
807  fixed_data_vect );
808  add_rotamer_line_data( jj_rotamer_data );
809 
810  }
811 
812  delete [] ii_aa_types; ii_aa_types = 0;
813  delete [] ii_rot_nums; ii_rot_nums = 0;
814  delete [] free_data; free_data = 0;
815  delete [] fixed_data; fixed_data = 0;
816 
817  OptEPositionData::receive_from_node( source_node, tag );
818 
819  //TR << "...data received from node " << source_node << std::endl;
820 }
821 
822 #endif
823 
824 
825 //
826 // ------------------- Position Specific Scoring Matrix -----------------------//
827 //
828 
829 PSSMOptEPositionData::PSSMOptEPositionData() {}
830 
831 PSSMOptEPositionData::~PSSMOptEPositionData() {}
832 
833 
834 Real
835 PSSMOptEPositionData::get_score(
836  optimization::Multivec const & component_weights,
837  optimization::Multivec const & vars,
838  optimization::Multivec & dE_dvars,
839  /// Basically, turn over all the private data from OptEMultiFunc
840  Size const num_energy_dofs,
841  int const,
842  int const,
843  EnergyMap const & fixed_terms,
844  ScoreTypes const & score_list,
845  ScoreTypes const & fixed_score_list
846 ) const
847 {
848  using namespace core::optimization;
849  using namespace basic::options;
850  using namespace basic::options::OptionKeys;
851 
852  static Real const inv_kT( option[ optE::inv_kT_nataa ] );
853 
854  Size const aa_range( chemical::num_canonical_aas );
855 
856  utility::vector1< Real > best_energy_by_aa( aa_range, 1000.0 );
857 
858  // cotainers for derivatives
859  Multivec ref_deriv_weight( aa_range, 0.0 );
860  utility::vector1< Real > dummy_set( score_list.size(), 0.0 );
861  utility::vector1< utility::vector1< Real > > unweighted_E_dof( aa_range, dummy_set );
862 
863  process_rotamers(
864  vars, num_energy_dofs, fixed_terms, score_list, fixed_score_list, aa_range, dummy_set,
865  best_energy_by_aa, unweighted_E_dof, ref_deriv_weight );
866 
867  for ( Size ii = 1; ii <= aa_range; ++ii ) {
868  if ( best_energy_by_aa[ ii ] == 1000.0 ) {
869  //std::cerr << "Position " << position() << " with no energy represented for aa: " << chemical::AA( ii ) << std::endl;
870  return 0.0;
871  }
872  }
873 
874  //Real const very_best = utility::min( best_energy_by_aa );
875  //for ( Size ii = 1; ii <= best_energy_by_aa.size(); ++ii ) {
876  // best_energy_by_aa[ ii ] -= very_best;
877  //}
878 
879 
880  optimization::Multivec dpartition( vars.size(), 0.0 );
881  optimization::Multivec dpssm_partition( vars.size(), 0.0 );
882  Real partition( 0.0 ), pssm_partition( 0.0 );
883  if ( option[ optE::sqrt_pssm ].user() ) {
884 
885  utility::vector1< Real > boltz_coeff( aa_range, 0.0 );
886  for ( Size ii = 1; ii <= aa_range; ++ii ) {
887  Real const exp_term( std::exp( -1.0 * inv_kT * best_energy_by_aa[ ii ] ) );
888  partition += exp_term;
889  boltz_coeff[ ii ] = exp_term;
890  }
891  Real const partition2 = partition * partition;
892  Real dot_product = 0;
893  utility::vector1< Real > energy_coeff( num_energy_dofs, 0.0 );
894  //std::cout << "score: " << position() << " ";
895  for ( Size ii = 1; ii <= aa_range; ++ii ) {
896  /// pssm_probabilities_ holds the squareroot of the probabilities
897  dot_product += pssm_probabilities_[ ii ] * std::sqrt( boltz_coeff[ ii ] / partition );
898  //std::cout << "( " << pssm_probabilities_[ ii ] << ", " << std::sqrt( boltz_coeff[ ii ] / partition ) << ") ";
899  for ( Size jj = 1; jj <= num_energy_dofs; ++jj ) {
900  energy_coeff[ jj ] += unweighted_E_dof[ ii ][ jj ] * boltz_coeff[ ii ];
901  }
902 
903  }
904  //std::cout << " total: " << -1.0 * dot_product << std::endl;
905  for ( Size ii = 1; ii <= aa_range; ++ii ) {
906  Real const ii_negsqrt_prob = std::pow( boltz_coeff[ ii ] / partition, -0.5 );
907 
908  for ( Size jj = 1; jj <= num_energy_dofs; ++jj ) {
909  dE_dvars[ jj ] += -0.5 * pssm_probabilities_[ ii ] *
910  ( ii_negsqrt_prob ) * component_weights[ type() ] *
911  ( boltz_coeff[ ii ] * energy_coeff[ jj ] -
912  inv_kT * unweighted_E_dof[ ii ][ jj ] * boltz_coeff[ ii ] * partition ) /
913  ( partition2 );
914  }
915  for ( Size jj = 1; jj <= aa_range; ++jj ) {
916  if ( ii == jj ) {
917  dE_dvars[ num_energy_dofs + jj ] += -0.5 * pssm_probabilities_[ ii ] *
918  ( ii_negsqrt_prob ) * component_weights[ type() ] *
919  ( boltz_coeff[ ii ] * boltz_coeff[ ii ] -
920  inv_kT * boltz_coeff[ ii ] * partition ) / ( partition2 );
921  } else {
922  dE_dvars[ num_energy_dofs + jj ] += -0.5 * pssm_probabilities_[ ii ] *
923  ( ii_negsqrt_prob ) * component_weights[ type() ] *
924  ( inv_kT * boltz_coeff[ ii ] * boltz_coeff[ jj ] ) / ( partition2 );
925  }
926  }
927  }
928  return -1.0 * component_weights[ type() ] * dot_product;
929  } else {
930 
931  for ( Size ii = 1; ii <= aa_range; ++ii ) {
932  Real const exp_term( std::exp( -1.0 * inv_kT * best_energy_by_aa[ ii ] ) );
933  partition += exp_term;
934  pssm_partition += pssm_probabilities_[ ii ] * exp_term;
935 
936  Real const ref_deriv_term( -1.0 * inv_kT * ref_deriv_weight[ ii ] * exp_term );
937  dpartition[ num_energy_dofs + ii ] = ref_deriv_term;
938  dpssm_partition[ num_energy_dofs + ii ] = pssm_probabilities_[ ii ] * ref_deriv_term;
939 
940  for ( Size jj = 1; jj <= num_energy_dofs; ++jj ) {
941  Real e_dof_deriv( -1.0 * inv_kT * unweighted_E_dof[ ii ][ jj ] * exp_term );
942  dpartition[ jj ] += e_dof_deriv;
943  dpssm_partition[ jj ] += pssm_probabilities_[ ii ] * e_dof_deriv;
944  }
945  }
946  for ( Size ii = 1; ii <= vars.size(); ++ii ) {
947  dE_dvars[ ii ] += component_weights[ pssm_data ] * ( dpartition[ ii ] / partition - dpssm_partition[ ii ] / pssm_partition );
948  }
949 
950  //std::cout << "Position data: ";
951  //for ( Size ii = 1; ii <= aa_range; ++ii ) {
952  //Real const exp_term( std::exp( -1.0 * best_energy_by_aa[ ii ] ) );
953  //Real const ii_prob = exp_term / partition;
954  //std::cout << "(" << ii_prob << ", " << pssm_probabilities_[ ii ] << ") ";
955  //}
956  //std::cout << std::endl << "score: " << -1 * std::log( pssm_partition / partition ) << std::endl;
957 
958  return -1 * component_weights[ pssm_data ] * std::log( pssm_partition / partition );
959  }
960 }
961 
962 void
963 PSSMOptEPositionData::print_score(
964  std::ostream & ostr,
965  optimization::Multivec const & component_weights,
966  optimization::Multivec const & vars,
967  optimization::Multivec & dE_dvars,
968  /// Basically, turn over all the private data from OptEMultiFunc
969  Size const num_energy_dofs,
970  int const,
971  int const,
972  EnergyMap const & fixed_terms,
973  ScoreTypes const & score_list,
974  ScoreTypes const & fixed_score_list
975 ) const
976 {
977  using namespace core::optimization;
978  using namespace basic::options;
979  using namespace basic::options::OptionKeys;
980 
981  //TR << "PSSMOptEPositionData::print_score" << std::endl;
982 
983  static Real const inv_kT( option[ optE::inv_kT_nataa ] );
984 
985  Size const aa_range( chemical::num_canonical_aas );
986 
987  utility::vector1< Real > best_energy_by_aa( aa_range, 1000.0 );
988 
989  // cotainers for derivatives
990  Multivec ref_deriv_weight( aa_range, 0.0 );
991  utility::vector1< Real > dummy_set( score_list.size(), 0.0 );
992  utility::vector1< utility::vector1< Real > > unweighted_E_dof( aa_range, dummy_set );
993 
994  process_rotamers(
995  vars, num_energy_dofs, fixed_terms, score_list, fixed_score_list, aa_range, dummy_set,
996  best_energy_by_aa, unweighted_E_dof, ref_deriv_weight );
997 
998  for ( Size ii = 1; ii <= aa_range; ++ii ) {
999  if ( best_energy_by_aa[ ii ] == 1000.0 ) {
1000  //std::cerr << "Position " << position() << " with no energy represented for aa: " << chemical::AA( ii ) << std::endl;
1001  return;// 0.0;
1002  }
1003  }
1004 
1005  optimization::Multivec dpartition( vars.size(), 0.0 );
1006  optimization::Multivec dpssm_partition( vars.size(), 0.0 );
1007  Real partition( 0.0 ), pssm_partition( 0.0 );
1008  if ( option[ optE::sqrt_pssm ].user() ) {
1009 
1010  utility::vector1< Real > boltz_coeff( aa_range, 0.0 );
1011  for ( Size ii = 1; ii <= aa_range; ++ii ) {
1012  Real const exp_term( std::exp( -1.0 * inv_kT * best_energy_by_aa[ ii ] ) );
1013  partition += exp_term;
1014  boltz_coeff[ ii ] = exp_term;
1015  }
1016  Real const partition2 = partition * partition;
1017  Real dot_product = 0;
1018  utility::vector1< Real > energy_coeff( num_energy_dofs, 0.0 );
1019  //std::cout << "score: " << position() << " ";
1020  for ( Size ii = 1; ii <= aa_range; ++ii ) {
1021  /// pssm_probabilities_ holds the squareroot of the probabilities
1022  dot_product += pssm_probabilities_[ ii ] * std::sqrt( boltz_coeff[ ii ] / partition );
1023  //std::cout << "( " << pssm_probabilities_[ ii ] << ", " << std::sqrt( boltz_coeff[ ii ] / partition ) << ") ";
1024  for ( Size jj = 1; jj <= num_energy_dofs; ++jj ) {
1025  energy_coeff[ jj ] += unweighted_E_dof[ ii ][ jj ] * boltz_coeff[ ii ];
1026  }
1027 
1028  }
1029  //std::cout << " total: " << -1.0 * dot_product << std::endl;
1030  for ( Size ii = 1; ii <= aa_range; ++ii ) {
1031  Real const ii_negsqrt_prob = std::pow( boltz_coeff[ ii ] / partition, -0.5 );
1032 
1033  for ( Size jj = 1; jj <= num_energy_dofs; ++jj ) {
1034  dE_dvars[ jj ] += -0.5 * pssm_probabilities_[ ii ] *
1035  ( ii_negsqrt_prob ) *
1036  ( boltz_coeff[ ii ] * energy_coeff[ jj ] -
1037  inv_kT * unweighted_E_dof[ ii ][ jj ] * boltz_coeff[ ii ] * partition ) /
1038  ( partition2 );
1039  }
1040  for ( Size jj = 1; jj <= aa_range; ++jj ) {
1041  if ( ii == jj ) {
1042  dE_dvars[ num_energy_dofs + jj ] += -0.5 * pssm_probabilities_[ ii ] *
1043  ( ii_negsqrt_prob ) *
1044  ( boltz_coeff[ ii ] * boltz_coeff[ ii ] -
1045  inv_kT * boltz_coeff[ ii ] * partition ) / ( partition2 );
1046  } else {
1047  dE_dvars[ num_energy_dofs + jj ] += -0.5 * pssm_probabilities_[ ii ] *
1048  ( ii_negsqrt_prob ) *
1049  ( inv_kT * boltz_coeff[ ii ] * boltz_coeff[ jj ] ) / ( partition2 );
1050  }
1051  }
1052  }
1053 
1054  ostr << "PSSM_SQRT " << native_aa() << " " << (int) native_aa();
1055  ostr << " nneighb: " << neighbor_count() << " dotpr: " << dot_product << " ";
1056  for ( Size ii = 1; ii <= aa_range; ++ii ) {
1057  ostr << "([ " << ii << "] " << pssm_probabilities_[ ii ] << " , " << std::sqrt( boltz_coeff[ ii ] / partition ) << " ) ";
1058  }
1059  ostr << " " << tag() << "\n";
1060 
1061  //TR << "PSSMOptEPositionData::print_score done" << std::endl;
1062 
1063  return;// -1.0 * dot_product;
1064  } else {
1065 
1066  for ( Size ii = 1; ii <= aa_range; ++ii ) {
1067  Real const exp_term( std::exp( -1.0 * inv_kT * best_energy_by_aa[ ii ] ) );
1068  partition += exp_term;
1069  pssm_partition += pssm_probabilities_[ ii ] * exp_term;
1070 
1071  Real const ref_deriv_term( -1.0 * inv_kT * ref_deriv_weight[ ii ] * exp_term );
1072  dpartition[ num_energy_dofs + ii ] = ref_deriv_term;
1073  dpssm_partition[ num_energy_dofs + ii ] = pssm_probabilities_[ ii ] * ref_deriv_term;
1074 
1075  for ( Size jj = 1; jj <= num_energy_dofs; ++jj ) {
1076  Real e_dof_deriv( -1.0 * inv_kT * unweighted_E_dof[ ii ][ jj ] * exp_term );
1077  dpartition[ jj ] += e_dof_deriv;
1078  dpssm_partition[ jj ] += pssm_probabilities_[ ii ] * e_dof_deriv;
1079  }
1080  }
1081  for ( Size ii = 1; ii <= vars.size(); ++ii ) {
1082  dE_dvars[ ii ] += dpartition[ ii ] / partition - dpssm_partition[ ii ] / pssm_partition;
1083  }
1084 
1085  //std::cout << "Position data: ";
1086  //for ( Size ii = 1; ii <= aa_range; ++ii ) {
1087  //Real const exp_term( std::exp( -1.0 * best_energy_by_aa[ ii ] ) );
1088  //Real const ii_prob = exp_term / partition;
1089  //std::cout << "(" << ii_prob << ", " << pssm_probabilities_[ ii ] << ") ";
1090  //}
1091  //std::cout << std::endl << "score: " << -1 * std::log( pssm_partition / partition ) << std::endl;
1092 
1093  ostr << "PSSM_PART " << native_aa() << " " << (int) native_aa();
1094  ostr << " nneighb: " << neighbor_count() << " pssmpart: " << pssm_partition / partition << " ";
1095  ostr << " -lnpssmpart: " << -1.0 * std::log( pssm_partition / partition ) << " ";
1096  ostr << " -compwt_lnpssm " << -1.0 * component_weights[ pssm_data ] * std::log( pssm_partition / partition );
1097  for ( Size ii = 1; ii <= aa_range; ++ii ) {
1098  ostr << "([ " << ii << "] " << pssm_probabilities_[ ii ] << " , " << std::exp( -1.0 * best_energy_by_aa[ ii ] ) / partition << " ) ";
1099  }
1100 
1101  ostr << " " << tag() << "\n";
1102 
1103  //TR << "PSSMOptEPositionData::print_score done" << std::endl;
1104 
1105  return;// -1 * std::log( pssm_partition / partition );
1106  }
1107 }
1108 
1109 
1110 void
1111 PSSMOptEPositionData::set_pssm_probabilities(
1112  utility::vector1< Real > const & pssm_probs
1113 )
1114 {
1115  using namespace basic::options;
1116  using namespace basic::options::OptionKeys;
1117 
1118  /// runtime_assert something like that they sum to 1, or pretty close
1119  /// and that the size = num_canonincal_aas
1120  pssm_probabilities_ = pssm_probs;
1121 
1122  // Store the squareroot of the input probabilities if we're optimizing using the
1123  // dot product of unit vectors.
1124  if ( option[ optE::sqrt_pssm ].user() ) {
1125  for ( Size ii = 1; ii <= pssm_probs.size(); ++ii ) {
1126  pssm_probabilities_[ ii ] = std::sqrt( pssm_probs[ ii ] );
1127  }
1128  }
1129 }
1130 
1132 PSSMOptEPositionData::type() const
1133 {
1134  return pssm_data;
1135 }
1136 
1137 
1138 void
1139 PSSMOptEPositionData::write_to_file( std::ofstream & outfile ) const
1140 {
1141  outfile << pssm_probabilities_.size() << " ";
1142  for ( Size ii = 1; ii <= pssm_probabilities_.size(); ++ii ) {
1143  outfile << pssm_probabilities_[ ii ] << " ";
1144  }
1145  outfile << "\n";
1146  parent::write_to_file( outfile );
1147 }
1148 
1149 
1150 void
1151 PSSMOptEPositionData::read_from_file( std::ifstream & infile )
1152 {
1153  Size nprobs;
1154  infile >> nprobs;
1155  pssm_probabilities_.resize( nprobs );
1156  for ( Size ii = 1; ii <= pssm_probabilities_.size(); ++ii ) {
1157  infile >> pssm_probabilities_[ ii ];
1158  }
1159  parent::read_from_file( infile );
1160 }
1161 
1162 
1163 void
1164 PSSMOptEPositionData::write_to_binary_file( std::ofstream & /*outfile*/ ) const
1165 {}
1166 
1167 
1168 void
1169 PSSMOptEPositionData::read_from_binary_file( std::ifstream & /*infile*/ )
1170 {}
1171 
1172 Size
1173 PSSMOptEPositionData::memory_use() const
1174 {
1175  Size total = pssm_probabilities_.size() * sizeof( Real );
1176  return total + parent::memory_use();
1177 }
1178 
1179 
1180 #ifdef USEMPI
1181 
1182 void
1183 PSSMOptEPositionData::send_to_node( int const destination_node, int const tag ) const
1184 {
1185  //TR << "PSSMOptEPositionData::Sending data to node " << destination_node << std::endl;
1186 
1187  int n_probabilities = pssm_probabilities_.size();
1188  MPI_Send( & n_probabilities, 1, MPI_INT, destination_node, tag, MPI_COMM_WORLD );
1189  if ( n_probabilities != 0 ) {
1190  Real * pssmprobs = new Real[ n_probabilities ];
1191  for ( int ii = 1; ii <= n_probabilities; ++ii ) {
1192  pssmprobs[ ii - 1 ] = pssm_probabilities_[ ii ];
1193  }
1194  MPI_Send( pssmprobs, n_probabilities, MPI_DOUBLE, destination_node, tag, MPI_COMM_WORLD );
1195  delete [] pssmprobs;
1196  }
1197  parent::send_to_node( destination_node, tag );
1198 }
1199 
1200 
1201 void
1202 PSSMOptEPositionData::receive_from_node( int const source_node, int const tag )
1203 {
1204  MPI_Status stat;
1205  int n_probabilities;
1206  MPI_Recv( & n_probabilities, 1, MPI_INT, source_node, tag, MPI_COMM_WORLD, &stat );
1207  if ( n_probabilities != 0 ) {
1208  Real * pssmprobs = new Real[ n_probabilities ];
1209  pssm_probabilities_.resize( n_probabilities );
1210  MPI_Recv( pssmprobs, n_probabilities, MPI_DOUBLE, source_node, tag, MPI_COMM_WORLD, &stat );
1211  for ( int ii = 1; ii <= n_probabilities; ++ii ) {
1212  pssm_probabilities_[ ii ] = pssmprobs[ ii - 1 ];
1213  }
1214  delete [] pssmprobs;
1215  }
1216  parent::receive_from_node( source_node, tag );
1217 
1218 }
1219 
1220 #endif //USEMPI
1221 
1222 
1223 //
1224 // ------------------- P Native Rotamer -----------------------//
1225 //
1226 
1227 PNatRotOptEPositionData::PNatRotOptEPositionData() : phi_(0.0), psi_(0.0) {}
1228 
1230 
1231 Real
1233  optimization::Multivec const & component_weights,
1234  optimization::Multivec const & vars,
1235  optimization::Multivec & dE_dvars,
1236  /// Basically, turn over all the private data from OptEMultiFunc
1237  Size const num_energy_dofs,
1238  int const dummy1,
1239  int const dummy2,
1240  EnergyMap const & fixed_terms,
1241  ScoreTypes const & dummy3 /*free_score_list*/,
1242  ScoreTypes const & fixed_score_list
1243 ) const
1244 {
1245  return process_score(
1246  TR, false, component_weights, vars,
1247  dE_dvars, num_energy_dofs, dummy1, dummy2,
1248  fixed_terms, dummy3, fixed_score_list );
1249 }
1250 
1251 /*
1252 {
1253  using namespace core::optimization;
1254  using namespace utility;
1255  using namespace basic::options;
1256  using namespace basic::options::OptionKeys;
1257 
1258  static Real const inv_kT( option[ optE::inv_kT_natrot ] );
1259 
1260 
1261  utility::vector1< Real > best_energy_by_rotwell( n_wells_, 1000.0 );
1262  utility::vector1< Real > well_is_represented( n_wells_, false );
1263 
1264  // cotainers for derivatives
1265  utility::vector1< Real > dummy_set( score_list.size(), 0.0 );
1266  utility::vector1< utility::vector1< Real > > unweighted_E_dof( n_wells_, dummy_set );
1267 
1268  /// Zero the static data
1269  //for ( Size ii = 1; ii <= unweighted_E_dof.size(); ++ii ) {
1270  // for ( Size jj = 1; jj <= unweighted_E_dof[ii].size(); ++jj ) {
1271  // unweighted_E_dof[ ii ][ jj ] = 0.0;
1272  // }
1273  //}
1274 
1275  Size const natrotwell = rotamer_index_2_well_id( native_rotamer_index_ );
1276 
1277  // HACK below
1278  Real best_energy( 0.0 );
1279  bool best_energy_is_native( false ), first_round( true );
1280 
1281  for( PNatRotOptERotamerDataOPs::const_iterator itr = rotamer_data_begin(),
1282  e_itr = rotamer_data_end() ; itr != e_itr; ++itr ) {
1283  utility::vector1< Size > const & this_rotindex( (*itr)->rotamer_index() );
1284  Size this_rotwell = rotamer_index_2_well_id( this_rotindex );
1285 
1286  if ( this_rotwell != natrotwell && count_rotamer_as_native( *itr ) ) {
1287  this_rotwell = natrotwell;
1288  }
1289 
1290  Real weighted_energy( 0.0 );
1291  // Variable-weighted energy terms
1292  for( Size ii = 1; ii <= num_energy_dofs; ++ii ) {
1293  weighted_energy += vars[ ii ] * ((**itr)[ ii ]);
1294  }
1295  // Fixed-weight energy terms
1296  for( Size ii = 1; ii <= fixed_score_list.size(); ++ii ) {
1297  weighted_energy += fixed_terms[ fixed_score_list[ ii ] ] * (*itr)->fixed_data()[ ii ];
1298  }
1299 
1300  Real const cutoff( 300.0 );
1301  if( weighted_energy > cutoff ) weighted_energy = cutoff;
1302  if( weighted_energy < -1.0*cutoff ) weighted_energy = -1.0*cutoff;
1303 
1304  if ( first_round || weighted_energy < best_energy ) {
1305  best_energy = weighted_energy;
1306  first_round = false;
1307  best_energy_is_native = this_rotwell == natrotwell;
1308  }
1309 
1310  if( weighted_energy < best_energy_by_rotwell[ this_rotwell ] ) {
1311 
1312  best_energy_by_rotwell[ this_rotwell ] = weighted_energy;
1313  well_is_represented[ this_rotwell ] = true;
1314 
1315  if( std::abs( weighted_energy ) < cutoff ) {
1316  unweighted_E_dof[ this_rotwell ] = (*itr)->free_data();
1317  } else {
1318  // derivatives will be zero above and below cutoffs
1319  unweighted_E_dof[ this_rotwell ] = dummy_set;
1320  }
1321  }
1322  } // done processing rotamers
1323  // now do the partition function analysis
1324 
1325  if ( ! well_is_represented[ rotamer_index_2_well_id( native_rotamer_index_ ) ] ) {
1326  /// This shouldn't happen, but it's not disasterous if it does. ... er, it happens from time to time
1327  ///std::cerr << "Skipping score in the absence of the native rotamer!" << std::endl;
1328  return 0.0;
1329  }
1330 
1331  Real numerator(0.0), partition(0.0);
1332  Multivec dpartition( vars.size(), 0.0 ), dnumerator( vars.size(), 0.0 );
1333 
1334  for( LexicographicalIterator iter( rotamer_well_counts_ ); ! iter.at_end(); ++iter ) {
1335  Size const iter_rotwell = rotamer_index_2_well_id( iter );
1336  if ( ! well_is_represented[ iter_rotwell ] ) continue;
1337 
1338  Real const exp_term( std::exp( -1.0 * inv_kT * best_energy_by_rotwell[ iter_rotwell ] ) );
1339  partition += exp_term;
1340  bool const native_rotamer( is_native_rotamer_well( iter ));
1341  if ( native_rotamer ) numerator = exp_term;
1342 
1343  // partitions for energy derivatives
1344  for( Size e_dof(1); e_dof <= num_energy_dofs; ++e_dof ) {
1345  // note for derivatives: d/dw( e^-(E*w+...) ) = -E * e^-(E*w+...)
1346  Real e_dof_deriv( -1.0 * inv_kT * unweighted_E_dof[ iter_rotwell ][ e_dof ] * exp_term );
1347  dpartition[ e_dof ] += e_dof_deriv;
1348  if ( native_rotamer ) dnumerator[ e_dof ] = e_dof_deriv;
1349  }
1350  }
1351 
1352  // accumulate to passed-in derivative sums
1353  for ( Size dof(1); dof <= vars.size(); ++dof ) {
1354  dE_dvars[ dof ] += component_weights[ prob_native_rotamer ] * ( dpartition[ dof ] / partition - dnumerator[ dof ] / numerator );
1355  }
1356 
1357  //return best_energy_is_native ? 0 : 1;
1358  return ( -1.0 * component_weights[ prob_native_rotamer ] * std::log( numerator / partition ) );
1359 
1360 }*/
1361 
1362 void
1364  std::ostream & ostr,
1365  optimization::Multivec const & component_weights,
1366  optimization::Multivec const & vars,
1367  optimization::Multivec & dE_dvars,
1368  /// Basically, turn over all the private data from OptEMultiFunc
1369  Size const num_energy_dofs,
1370  int const dummy1,
1371  int const dummy2,
1372  EnergyMap const & fixed_terms,
1373  ScoreTypes const & dummy3,
1374  ScoreTypes const & fixed_score_list
1375 ) const
1376 {
1377  process_score(
1378  ostr, true, component_weights, vars,
1379  dE_dvars, num_energy_dofs, dummy1, dummy2,
1380  fixed_terms, dummy3, fixed_score_list );
1381 }
1382 
1383 
1384 
1385 Real
1387  std::ostream & ostr,
1388  bool print,
1389  optimization::Multivec const & component_weights,
1390  optimization::Multivec const & vars,
1391  optimization::Multivec & dE_dvars,
1392  /// Basically, turn over all the private data from OptEMultiFunc
1393  Size const num_energy_dofs,
1394  int const,
1395  int const,
1396  EnergyMap const & fixed_terms,
1397  ScoreTypes const & score_list,
1398  ScoreTypes const & fixed_score_list
1399 ) const
1400 {
1401  using namespace core::optimization;
1402  using namespace utility;
1403  using namespace basic::options;
1404  using namespace basic::options::OptionKeys;
1405 
1406  static Real const inv_kT( option[ optE::inv_kT_natrot ] );
1407 
1408  static bool const dun10active( option[ corrections::score::dun10 ] );
1409 
1410  //TR << "PNatRotOptEPositionData::print_score" << std::endl;
1411 
1412  utility::vector1< Real > best_energy_by_rotwell( n_wells_, 1000.0 );
1413  utility::vector1< PNatRotOptERotamerDataOP > best_rotamer_by_rotwell( n_wells_ );
1414  utility::vector1< Real > well_is_represented( n_wells_, false );
1415 
1416  // cotainers for derivatives
1417  utility::vector1< Real > dummy_set( score_list.size(), 0.0 );
1418  utility::vector1< utility::vector1< Real > > unweighted_E_dof( n_wells_, dummy_set );
1419 
1420  /// Zero the static data
1421  //for ( Size ii = 1; ii <= unweighted_E_dof.size(); ++ii ) {
1422  // for ( Size jj = 1; jj <= unweighted_E_dof[ii].size(); ++jj ) {
1423  // unweighted_E_dof[ ii ][ jj ] = 0.0;
1424  // }
1425  //}
1426 
1427  // HACK below
1428  Real best_energyHACK( 0.0 );
1429  bool best_energy_is_native( false ), first_round( true );
1430 
1431  Size const natrotwell = rotamer_index_2_well_id( native_rotamer_index_ );
1432  Size nnearnative( 0 );
1433  Size ndecoys( 0 );
1434 
1435  for( PNatRotOptERotamerDataOPs::const_iterator itr = rotamer_data_begin(),
1436  e_itr = rotamer_data_end() ; itr != e_itr; ++itr ) {
1437  utility::vector1< Size > const & this_rotindex( (*itr)->rotamer_index() );
1438  Size this_rotwell = rotamer_index_2_well_id( this_rotindex );
1439 
1440  bool count_as_native( false );
1441  if ( this_rotwell != natrotwell && count_rotamer_as_native( *itr ) ) {
1442  this_rotwell = natrotwell;
1443  count_as_native = true;
1444  ++nnearnative;
1445  } else {
1446  ++ndecoys;
1447  }
1448 
1449  Real weighted_energy( 0.0 );
1450  if ( count_as_native && dun10active ) {
1451  using namespace core::chemical;
1452  /// Entropy bonus for the native rotamer; the semi-rotameric residues
1453  /// have fewer wells in the '02 library than they do in the '08 library.
1454  switch ( aa_ ) {
1455  case aa_asp : weighted_energy = std::log( 3.0f / 6.0f ); break;
1456  case aa_glu : weighted_energy = std::log( 3.0f / 6.0f ); break;
1457  case aa_phe : weighted_energy = std::log( 2.0f / 6.0f ); break;
1458  case aa_his : weighted_energy = std::log( 3.0f / 12.0f ); break;
1459  case aa_asn : weighted_energy = std::log( 6.0f / 12.0f ); break;
1460  case aa_gln : weighted_energy = std::log( 4.0f / 12.0f ); break;
1461  case aa_tyr : weighted_energy = std::log( 2.0f / 6.0f ); break;
1462  default:
1463  break;
1464  }
1465  ///weighted_energy = 0; // TEMP TEMP TEMP deactivate entropy bonus.
1466  }
1467  // Variable-weighted energy terms
1468  for( Size ii = 1; ii <= num_energy_dofs; ++ii ) {
1469  weighted_energy += vars[ ii ] * ((**itr)[ ii ]);
1470  }
1471  // Fixed-weight energy terms
1472  for( Size ii = 1; ii <= fixed_score_list.size(); ++ii ) {
1473  weighted_energy += fixed_terms[ fixed_score_list[ ii ] ] * (*itr)->fixed_data()[ ii ];
1474  }
1475 
1476  Real const cutoff( 300.0 );
1477  if( weighted_energy > cutoff ) weighted_energy = cutoff;
1478  if( weighted_energy < -1.0*cutoff ) weighted_energy = -1.0*cutoff;
1479 
1480  if ( first_round || weighted_energy < best_energyHACK ) {
1481  best_energyHACK = weighted_energy;
1482  first_round = false;
1483  best_energy_is_native = this_rotwell == natrotwell;
1484  }
1485 
1486  if( weighted_energy < best_energy_by_rotwell[ this_rotwell ] ) {
1487  best_rotamer_by_rotwell[ this_rotwell ] = *itr;
1488  best_energy_by_rotwell[ this_rotwell ] = weighted_energy;
1489  well_is_represented[ this_rotwell ] = true;
1490 
1491  if( std::abs( weighted_energy ) < cutoff ) {
1492  unweighted_E_dof[ this_rotwell ] = (*itr)->free_data();
1493  } else {
1494  // derivatives will be zero above and below cutoffs
1495  unweighted_E_dof[ this_rotwell ] = dummy_set;
1496  }
1497  }
1498  } // done processing rotamers
1499  // now do the partition function analysis
1500 
1501 
1502  Real numerator(0.0), partition(0.0);
1503  Multivec dpartition( vars.size(), 0.0 ), dnumerator( vars.size(), 0.0 );
1504  static Real const SENTINEL = 1234;
1505  Real best_energy( SENTINEL ); Size best_rotind( 0 );
1506  utility::vector1< Size > best_rotwell( rotamer_well_counts_.size(), 0 );
1507  utility::vector1< Size > native_rotwell( rotamer_well_counts_.size(), 0 );
1508 
1509 
1510  for( LexicographicalIterator iter( rotamer_well_counts_ ); ! iter.at_end(); ++iter ) {
1511  Size const iter_rotwell = rotamer_index_2_well_id( iter );
1512  if ( ! well_is_represented[ iter_rotwell ] ) continue;
1513 
1514  Real const exp_term( std::exp( -1.0 * inv_kT * best_energy_by_rotwell[ iter_rotwell ] ) );
1515  partition += exp_term;
1516  bool const native_rotamer( is_native_rotamer_well( iter ));
1517  if ( native_rotamer ) numerator = exp_term;
1518 
1519  if ( best_energy == SENTINEL || best_energy > best_energy_by_rotwell[ iter_rotwell ] ) {
1520  best_energy = best_energy_by_rotwell[ iter_rotwell ];
1521  best_rotind = iter_rotwell;
1522  for ( Size ii = 1; ii <= rotamer_well_counts_.size(); ++ii ) {
1523  best_rotwell[ ii ] = iter[ ii ];
1524  }
1525  }
1526 
1527  if ( native_rotamer ) {
1528  for ( Size ii = 1; ii <= rotamer_well_counts_.size(); ++ii ) {
1529  native_rotwell[ ii ] = iter[ ii ];
1530  }
1531  }
1532  // partitions for energy derivatives
1533  for( Size e_dof(1); e_dof <= num_energy_dofs; ++e_dof ) {
1534  // note for derivatives: d/dw( e^-(E*w+...) ) = -E * e^-(E*w+...)
1535  Real e_dof_deriv( -1.0 * inv_kT * unweighted_E_dof[ iter_rotwell ][ e_dof ] * exp_term );
1536  dpartition[ e_dof ] += e_dof_deriv;
1537  if ( native_rotamer ) dnumerator[ e_dof ] = e_dof_deriv;
1538  }
1539  }
1540 
1541 
1542  if ( ! well_is_represented[ rotamer_index_2_well_id( native_rotamer_index_ ) ] ) {
1543  /// This shouldn't happen, but it's not disasterous if it does. ... er, it happens from time to time
1544  /// std::cerr << "Skipping score in the absence of the native rotamer!" << std::endl;
1545  /// CHANGE OF HEART. If the library has not built a near-native rotamer, assign a penalty!
1546  /// 100 seems like a decent penalty.
1547  if ( print ) {
1548  ostr << "PNATROT-NO-NEAR-NATIVE nnat:" << nnearnative << " ndec: " << ndecoys << " p: " << 0.0 << " -lnp: ";
1549  ostr << 100;
1550  ostr << " compwt_lnp: " << 100;
1551  ostr << " n<d? " << 0 << " " << tag() << " " << rotamer_well_counts_.size() << " n:";
1552 
1553  for ( Size ii = 1; ii <= rotamer_well_counts_.size(); ++ii ) ostr << " " << native_rotwell[ ii ] << " " << native_chi_[ ii ];
1554  ostr << " phi/psi:" << phi_ << " " << psi_ << "\n";
1555 
1556  for( PNatRotOptERotamerDataOPs::const_iterator itr = rotamer_data_begin(),
1557  e_itr = rotamer_data_end() ; itr != e_itr; ++itr ) {
1558 
1559  ostr << "NON-NATIVE-ROT " << tag() << " ";
1560  for ( Size ii = 1; ii <= (*itr)->rotamer_index().size(); ++ii ) {
1561  ostr << (*itr)->rotamer_index()[ ii ] << " "<< (*itr)->chi()[ ii ] << " ";
1562  }
1563  ostr << "\n";
1564  }
1565  }
1566 
1567 
1568  return 100;// 0.0;
1569  }
1570 
1571 
1572  // accumulate to passed-in derivative sums
1573  for ( Size dof(1); dof <= vars.size(); ++dof ) {
1574  dE_dvars[ dof ] += dpartition[ dof ] / partition - dnumerator[ dof ] / numerator;
1575  }
1576 
1577  if ( print ) {
1578  ostr << "PNATROT nnat:" << nnearnative << " ndec: " << ndecoys << " p: " << numerator / partition << " -lnp: ";
1579  ostr << -1.0 * std::log( numerator / partition );
1580  ostr << " compwt_lnp: " << -1.0 * component_weights[ prob_native_rotamer ] * std::log( numerator / partition );
1581  ostr << " n<d? " << best_energy_is_native << " " << tag() << " " << rotamer_well_counts_.size() << " n:";
1582 
1583  for ( Size ii = 1; ii <= rotamer_well_counts_.size(); ++ii ) ostr << " " << native_rotwell[ ii ] << " " << native_chi_[ ii ];
1584  ostr << " b:";
1585  for ( Size ii = 1; ii <= rotamer_well_counts_.size(); ++ii ) {
1586  ostr << " " << best_rotwell[ ii ] << " " << best_rotamer_by_rotwell[ best_rotind ]->chi()[ ii ] ;
1587  }
1588  ostr << " phi/psi:" << phi_ << " " << psi_ << "\n";
1589  }
1590 
1591  //TR << "PNatRotOptEPositionData::print_score done" << std::endl;
1592 
1593  return ( -1.0 * component_weights[ prob_native_rotamer ] * std::log( numerator / partition ) );
1594 
1595 }
1596 
1597 void
1599  ScoreTypes const & free_score_list,
1600  ScoreTypes const & fixed_score_list,
1601  EnergyMap & lower_bound,
1602  EnergyMap & upper_bound
1603 ) const
1604 {
1605  for ( Size ii = 1; ii <= free_score_list.size(); ++ii ) {
1606  Real ii_min = lower_bound[ free_score_list[ ii ] ];
1607  Real ii_max = upper_bound[ free_score_list[ ii ] ];
1608  for( PNatRotOptERotamerDataOPs::const_iterator iter = rotamer_data_begin(),
1609  e_itr = rotamer_data_end() ; iter != e_itr; ++iter ) {
1610  if ( ii_min > (*iter)->free_data()[ ii ] ) {
1611  ii_min = (*iter)->free_data()[ ii ];
1612  }
1613  if ( ii_max < (*iter)->free_data()[ ii ] ) {
1614  ii_max = (*iter)->free_data()[ ii ];
1615  }
1616  }
1617  lower_bound[ free_score_list[ ii ] ] = ii_min;
1618  upper_bound[ free_score_list[ ii ] ] = ii_max;
1619  }
1620 
1621  for ( Size ii = 1; ii <= fixed_score_list.size(); ++ii ) {
1622  Real ii_min = lower_bound[ fixed_score_list[ ii ] ];
1623  Real ii_max = upper_bound[ fixed_score_list[ ii ] ];
1624  for( PNatRotOptERotamerDataOPs::const_iterator iter = rotamer_data_begin(),
1625  e_itr = rotamer_data_end() ; iter != e_itr; ++iter ) {
1626  if ( ii_min > (*iter)->fixed_data()[ ii ] ) {
1627  ii_min = (*iter)->fixed_data()[ ii ];
1628  }
1629  if ( ii_max < (*iter)->fixed_data()[ ii ] ) {
1630  ii_max = (*iter)->fixed_data()[ ii ];
1631  }
1632  }
1633  lower_bound[ fixed_score_list[ ii ] ] = ii_min;
1634  upper_bound[ fixed_score_list[ ii ] ] = ii_max;
1635  }
1636 }
1637 
1638 
1639 
1640 Size
1642 {
1643  return data_.size();
1644 }
1645 
1646 
1649 {
1650  return prob_native_rotamer;
1651 }
1652 
1653 
1654 void
1655 PNatRotOptEPositionData::write_to_file( std::ofstream & /*outfile*/ ) const
1656 {}
1657 
1658 
1659 void
1660 PNatRotOptEPositionData::read_from_file( std::ifstream & /*infile*/ )
1661 {}
1662 
1663 
1664 void
1665 PNatRotOptEPositionData::write_to_binary_file( std::ofstream & /*outfile*/ ) const
1666 {}
1667 
1668 
1669 void
1671 {}
1672 
1673 Size
1675 {
1676  Size total = sizeof( PNatRotOptEPositionData ) +
1677  sizeof( PNatRotOptERotamerData ) * data_.size() +
1678  sizeof( Size ) * native_rotamer_index_.size() +
1679  sizeof( Size ) * rotamer_well_counts_.size();
1680  if ( data_.size() > 0 ) {
1681  total += sizeof( Real ) * ( data_[ 1 ]->free_data().size() + data_[ 1 ]->fixed_data().size() ) * data_.size();
1682  total += sizeof( Size ) * data_[ 1 ]->rotamer_index().size() * data_.size();
1683  }
1684  return total;
1685 }
1686 
1687 
1688 #ifdef USEMPI
1689 void
1690 PNatRotOptEPositionData::send_to_node( int const destination_node, int const tag ) const
1691 {
1692  //MPI_Status stat;
1693 
1694  //TR << "PNatRotOptEPositionData:: Sending data to node... " << destination_node << std::endl;
1695 
1696  /// 3. How many chi angles
1697  int n_chi( data_[ 1 ]->rotamer_index().size() );
1698  MPI_Send( & n_chi, 1, MPI_INT, destination_node, tag, MPI_COMM_WORLD);
1699 
1700  {
1701  /// 4. How many chi wells
1702  int * rotamer_well_counts = new int[ n_chi ];
1703  for ( int ii = 1; ii <= n_chi; ++ii ) {
1704  rotamer_well_counts[ ii - 1 ] = rotamer_well_counts_[ ii ];
1705  }
1706  MPI_Send( rotamer_well_counts, n_chi, MPI_INT, destination_node, tag, MPI_COMM_WORLD );
1707  delete [] rotamer_well_counts;
1708  }
1709 
1710  {
1711  /// 5. What is the native rotamer at this position?
1712  int * native_rotamer = new int[ n_chi ];
1713  for ( int ii = 1; ii <= n_chi; ++ii ) {
1714  native_rotamer[ ii -1 ] = native_rotamer_index_[ ii ];
1715  }
1716  MPI_Send( native_rotamer, n_chi, MPI_INT, destination_node, tag, MPI_COMM_WORLD );
1717  delete [] native_rotamer;
1718  }
1719 
1720  /// 6. The number of rotamers for this position
1721  Size ii_num_rotamers = data_.size();
1722  MPI_Send( & ii_num_rotamers, 1, MPI_UNSIGNED_LONG, destination_node, tag, MPI_COMM_WORLD );
1723 
1724  if ( ii_num_rotamers == 0 ) return;
1725 
1726  Size free_count( data_[ 1 ]->free_data().size() );
1727  Size fixed_count( data_[ 1 ]->fixed_data().size() );
1728 
1729  /// 7 The size of the free and fixed data.
1730  MPI_Send( & free_count, 1, MPI_UNSIGNED_LONG, destination_node, tag, MPI_COMM_WORLD );
1731  MPI_Send( & fixed_count, 1, MPI_UNSIGNED_LONG, destination_node, tag, MPI_COMM_WORLD );
1732 
1733 
1734  Size * ii_rot_indices = new Size[ ii_num_rotamers * n_chi ];
1735  Real * chi = new Real[ ii_num_rotamers * n_chi ];
1736  Real * free_data = new Real[ ii_num_rotamers * free_count ];
1737  Real * fixed_data = new Real[ ii_num_rotamers * fixed_count ];
1738 
1739  for ( Size jj = 1; jj <= ii_num_rotamers; ++jj ) {
1740  utility::vector1< Size > const & rotamer_index_vect( data_[ jj ]->rotamer_index() );
1741  utility::vector1< Real > const & chi_vect( data_[ jj ]->chi() );
1742  utility::vector1< Real > const & free_data_vect( data_[ jj ]->free_data() );
1743  utility::vector1< Real > const & fixed_data_vect( data_[ jj ]->fixed_data() );
1744 
1745  for ( int kk = 1; kk <= n_chi; ++kk ) {
1746  ii_rot_indices[ ( jj - 1 ) * n_chi + kk - 1 ] = rotamer_index_vect[ kk ];
1747  chi[ ( jj - 1 ) * n_chi + kk - 1 ] = chi_vect[ kk ];
1748  }
1749  for ( Size kk = 1; kk <= free_count; ++kk ) {
1750  free_data[ ( jj - 1 ) * free_count + kk - 1 ] = free_data_vect[ kk ];
1751  }
1752  for ( Size kk = 1; kk <= fixed_count; ++kk ) {
1753  fixed_data[ ( jj - 1 ) * fixed_count + kk - 1 ] = fixed_data_vect[ kk ];
1754  }
1755 
1756  }
1757  /// 8. All the amino acids for all rotamers at this position
1758  MPI_Send( ii_rot_indices, ii_num_rotamers * n_chi, MPI_UNSIGNED_LONG, destination_node, tag, MPI_COMM_WORLD );
1759  MPI_Send( chi, ii_num_rotamers * n_chi, MPI_DOUBLE, destination_node, tag, MPI_COMM_WORLD );
1760 
1761  /// 9. All the free data for all rotamers
1762  MPI_Send( free_data, ii_num_rotamers * free_count, MPI_DOUBLE, destination_node, tag, MPI_COMM_WORLD );
1763 
1764  /// 10. All the fixed data for all rotamers
1765  MPI_Send( fixed_data, ii_num_rotamers * fixed_count, MPI_DOUBLE, destination_node, tag, MPI_COMM_WORLD );
1766 
1767 
1768  delete [] ii_rot_indices; ii_rot_indices = 0;
1769  delete [] chi; chi = 0;
1770  delete [] free_data; free_data = 0;
1771  delete [] fixed_data; fixed_data = 0;
1772 
1773  /// 11. Native chi data
1774  Size nnative_chi = native_chi_.size();
1775  MPI_Send( & nnative_chi, 1, MPI_UNSIGNED_LONG, destination_node, tag, MPI_COMM_WORLD );
1776  if ( nnative_chi != 0 ) {
1777  Real * native_chi = new Real[ nnative_chi ];
1778  for ( Size ii = 1; ii <= nnative_chi; ++ii ) native_chi[ ii - 1 ] = native_chi_[ ii ];
1779  MPI_Send( native_chi, nnative_chi, MPI_DOUBLE, destination_node, tag, MPI_COMM_WORLD );
1780  delete [] native_chi;
1781  }
1782 
1783  /// 12. Native chi periodicity data
1784  Size nnative_chi_periodicity = native_chi_periodicity_.size();
1785  MPI_Send( & nnative_chi_periodicity, 1, MPI_UNSIGNED_LONG, destination_node, tag, MPI_COMM_WORLD );
1786  if ( nnative_chi_periodicity != 0 ) {
1787  Real * native_chi_periodicity = new Real[ nnative_chi_periodicity ];
1788  for ( Size ii = 1; ii <= nnative_chi_periodicity; ++ii ) native_chi_periodicity[ ii - 1 ] = native_chi_periodicity_[ ii ];
1789  MPI_Send( native_chi_periodicity, nnative_chi_periodicity, MPI_DOUBLE, destination_node, tag, MPI_COMM_WORLD );
1790  delete [] native_chi_periodicity;
1791  }
1792 
1793  /// 13. phi/psi
1794  Real phi( phi_ ), psi( psi_ );
1795  MPI_Send( & phi, 1, MPI_DOUBLE, destination_node, tag, MPI_COMM_WORLD );
1796  MPI_Send( & psi, 1, MPI_DOUBLE, destination_node, tag, MPI_COMM_WORLD );
1797 
1798  /// 14. aa_
1799  int aa( aa_ );
1800  MPI_Send( & aa, 1, MPI_INT, destination_node, tag, MPI_COMM_WORLD );
1801 
1802 
1803  //TR << "... sent data to node " << destination_node << std::endl;
1804  OptEPositionData::send_to_node( destination_node, tag );
1805 }
1806 
1807 
1808 void
1809 PNatRotOptEPositionData::receive_from_node( int const source_node, int const tag )
1810 {
1811  MPI_Status stat;
1812 
1813  //TR << "PNatRotOptEPositionData::Recieving data from node... " << source_node << std::endl;
1814 
1815  /// 3. How many chi angles
1816  int n_chi;
1817  MPI_Recv( & n_chi, 1, MPI_INT, source_node, tag, MPI_COMM_WORLD, &stat );
1818 
1819  //TR << "PNatRotOptEPositionData:: received nchi = " << n_chi << std::endl;
1820 
1821  runtime_assert( n_chi > 0 );
1822 
1823  { // scope
1824  /// 4. How many chi wells
1825  int * rotamer_well_counts = new int[ n_chi ];
1826  MPI_Recv( rotamer_well_counts, n_chi, MPI_INT, source_node, tag, MPI_COMM_WORLD, &stat );
1827  utility::vector1< Size > rotamer_well_counts_v( n_chi );
1828  for ( int ii = 1; ii <= n_chi; ++ii ) {
1829  rotamer_well_counts_v[ ii ] = rotamer_well_counts[ ii - 1 ];
1830  //TR << "PNatRotOptEPositionData:: received rotamer_well_counts[ " << ii << "] " << rotamer_well_counts[ ii - 1 ] << std::endl;
1831  }
1832  delete [] rotamer_well_counts;
1833  set_rotamer_well_counts( rotamer_well_counts_v );
1834  }
1835 
1836  { // scope
1837  /// 5. What is the native rotamer at this position?
1838  int * native_rotamer = new int[ n_chi ];
1839  MPI_Recv( native_rotamer, n_chi, MPI_INT, source_node, tag, MPI_COMM_WORLD, &stat );
1840  utility::vector1< Size > native_rotamer_v( n_chi );
1841  for ( int ii = 1; ii <= n_chi; ++ii ) {
1842  native_rotamer_v[ ii ] = native_rotamer[ ii -1 ];
1843  //TR << "PNatRotOptEPositionData:: received native_rotamer[ " << ii << "] " << native_rotamer[ ii - 1 ] << std::endl;
1844  }
1845  set_native_rotamer_index( native_rotamer_v );
1846  delete [] native_rotamer;
1847  }
1848 
1849  /// 6. The number of rotamers for this position
1850  Size ii_num_rotamers;
1851  MPI_Recv( & ii_num_rotamers, 1, MPI_UNSIGNED_LONG, source_node, tag, MPI_COMM_WORLD, &stat );
1852  //TR << "PNatRotOptEPositionData:: received ii_num_rotamers " << ii_num_rotamers << std::endl;
1853 
1854  if ( ii_num_rotamers == 0 ) return;
1855 
1856  Size free_count(0);
1857  Size fixed_count(0);
1858 
1859  /// 7 The size of the free and fixed data.
1860  MPI_Recv( & free_count, 1, MPI_UNSIGNED_LONG, source_node, tag, MPI_COMM_WORLD, &stat );
1861  MPI_Recv( & fixed_count, 1, MPI_UNSIGNED_LONG, source_node, tag, MPI_COMM_WORLD, &stat );
1862 
1863 
1864  Size * ii_rot_indices = new Size[ ii_num_rotamers * n_chi ];
1865  Real * chi = new Real[ ii_num_rotamers * n_chi ];
1866  Real * free_data = new Real[ ii_num_rotamers * free_count ];
1867  Real * fixed_data = new Real[ ii_num_rotamers * fixed_count ];
1868 
1869  /// 8. All the amino acids for all rotamers at this position
1870  MPI_Recv( ii_rot_indices, ii_num_rotamers * n_chi, MPI_UNSIGNED_LONG, source_node, tag, MPI_COMM_WORLD, &stat );
1871  MPI_Recv( chi, ii_num_rotamers * n_chi, MPI_DOUBLE, source_node, tag, MPI_COMM_WORLD, &stat );
1872 
1873  /// 9. All the free data for all rotamers
1874  MPI_Recv( free_data, ii_num_rotamers * free_count, MPI_DOUBLE, source_node, tag, MPI_COMM_WORLD, &stat );
1875 
1876  /// 10. All the fixed data for all rotamers
1877  MPI_Recv( fixed_data, ii_num_rotamers * fixed_count, MPI_DOUBLE, source_node, tag, MPI_COMM_WORLD, &stat );
1878 
1879  utility::vector1< Size > rotamer_index_vect( n_chi );
1880  utility::vector1< Real > chi_vect( n_chi );
1881  utility::vector1< Real > free_data_vect( free_count );
1882  utility::vector1< Real > fixed_data_vect( fixed_count );
1883 
1884  for ( Size jj = 1; jj <= ii_num_rotamers; ++jj ) {
1885  for ( int kk = 1; kk <= n_chi; ++kk ) {
1886  rotamer_index_vect[ kk ] = ii_rot_indices[ ( jj - 1 ) * n_chi + kk - 1 ];
1887  chi_vect[ kk ] = chi[ ( jj - 1 ) * n_chi + kk - 1 ];
1888  }
1889  for ( Size kk = 1; kk <= free_count; ++kk ) {
1890  free_data_vect[ kk ] = free_data[ ( jj - 1 ) * free_count + kk - 1 ];
1891  }
1892  for ( Size kk = 1; kk <= fixed_count; ++kk ) {
1893  fixed_data_vect[ kk ] = fixed_data[ ( jj - 1 ) * fixed_count + kk - 1 ];
1894  }
1895  PNatRotOptERotamerDataOP jj_rotamer_data = new PNatRotOptERotamerData(
1896  rotamer_index_vect,
1897  chi_vect,
1898  free_data_vect,
1899  fixed_data_vect );
1900  add_rotamer_line_data( jj_rotamer_data );
1901 
1902  }
1903 
1904  delete [] ii_rot_indices; ii_rot_indices = 0;
1905  delete [] chi; chi = 0;
1906  delete [] free_data; free_data = 0;
1907  delete [] fixed_data; fixed_data = 0;
1908 
1909  /// 11. Native chi data
1910  Size nnative_chi;
1911  MPI_Recv( & nnative_chi, 1, MPI_UNSIGNED_LONG, source_node, tag, MPI_COMM_WORLD, &stat );
1912  if ( nnative_chi != 0 ) {
1913  native_chi_.resize( nnative_chi );
1914  Real * native_chi = new Real[ nnative_chi ];
1915  MPI_Recv( native_chi, nnative_chi, MPI_DOUBLE, source_node, tag, MPI_COMM_WORLD, &stat );
1916  for ( Size ii = 1; ii <= nnative_chi; ++ii ) native_chi_[ ii ] = native_chi[ ii - 1 ];
1917  delete [] native_chi;
1918  }
1919 
1920  /// 12. Native chi periodicity data
1921  Size nnative_chi_periodicity = native_chi_periodicity_.size();
1922  MPI_Recv( & nnative_chi_periodicity, 1, MPI_UNSIGNED_LONG, source_node, tag, MPI_COMM_WORLD, &stat );
1923  if ( nnative_chi_periodicity != 0 ) {
1924  Real * native_chi_periodicity = new Real[ nnative_chi_periodicity ];
1925  MPI_Recv( native_chi_periodicity, nnative_chi_periodicity, MPI_DOUBLE, source_node, tag, MPI_COMM_WORLD, &stat );
1926  native_chi_periodicity_.resize( nnative_chi_periodicity );
1927  for ( Size ii = 1; ii <= nnative_chi_periodicity; ++ii ) native_chi_periodicity_[ ii ] = native_chi_periodicity[ ii -1 ];
1928  delete [] native_chi_periodicity;
1929  }
1930 
1931  /// 13. phi/psi
1932  Real phi, psi;
1933  MPI_Recv( & phi, 1, MPI_DOUBLE, source_node, tag, MPI_COMM_WORLD, &stat );
1934  MPI_Recv( & psi, 1, MPI_DOUBLE, source_node, tag, MPI_COMM_WORLD, &stat );
1935  phi_ = phi;
1936  psi_ = psi;
1937 
1938  /// 14. aa_
1939  int aa;
1940  MPI_Recv( & aa, 1, MPI_INT, source_node, tag, MPI_COMM_WORLD, &stat );
1941  aa_ = core::chemical::AA( aa );
1942 
1943  //TR << "... received data from node " << source_node << std::endl;
1944  OptEPositionData::receive_from_node( source_node, tag );
1945 
1946 }
1947 #endif
1948 
1949 void
1951  utility::vector1< Size > const & native_rotamer_index
1952 )
1953 {
1954  runtime_assert( rotamer_well_counts_.size() != 0 ); // set well counts before native rotamer
1955  runtime_assert( native_rotamer_index.size() == rotamer_well_counts_.size() );
1956  native_rotamer_index_ = native_rotamer_index;
1957  for ( Size ii = 1; ii <= rotamer_well_counts_.size(); ++ii ) {
1958  runtime_assert( native_rotamer_index_[ ii ] > 0 );
1959  runtime_assert( native_rotamer_index_[ ii ] <= rotamer_well_counts_[ ii ] );
1960  }
1961 }
1962 
1963 void
1965  utility::vector1< Real > const & native_chi
1966 )
1967 {
1968  native_chi_ = native_chi;
1969 }
1970 
1971 void
1973  utility::vector1< Real > const & native_chi_periodicity
1974 )
1975 {
1976  native_chi_periodicity_ = native_chi_periodicity;
1977 }
1978 
1979 bool
1981 {
1982  static Real const TOLERANCE = 40.0;
1983  for ( Size ii = 1; ii <= rotamer_well_counts_.size(); ++ii ) {
1984  if ( std::abs( numeric::mod( rotamer->chi()[ ii ] - native_chi_[ ii ], native_chi_periodicity_[ ii ] )) > TOLERANCE ) {
1985  return false;
1986  }
1987  }
1988  //std::cout << "Counting as native:";
1989  //for ( Size ii = 1; ii <= rotamer_well_counts_.size(); ++ii ) {
1990  // std::cout << " ( " << rotamer->chi()[ ii ] << " " << native_chi_[ ii ] << " " << native_chi_periodicity_[ ii ] << " )";
1991  //}
1992  //std::cout << std::endl;
1993  return true;
1994 }
1995 
1996 void
1998  utility::vector1< Size > const & rotamer_well_counts
1999 )
2000 {
2001  runtime_assert( rotamer_well_counts_.size() == 0 );
2002  runtime_assert( rotamer_well_counts.size() > 0 );
2003  rotamer_well_counts_ = rotamer_well_counts;
2004  n_wells_ = 1;
2005  for ( Size ii = 1; ii <= rotamer_well_counts_.size(); ++ii ) {
2006  n_wells_ *= rotamer_well_counts_[ ii ];
2007  }
2008 }
2009 
2010 void
2012 {
2013  data_.push_back( rot_in );
2014 }
2015 
2018 {
2019  return data_;
2020 }
2021 
2024 {
2025  return data_;
2026 }
2027 
2028 PNatRotOptERotamerDataOPs::const_iterator
2030 {
2031  return data_.begin();
2032 }
2033 PNatRotOptERotamerDataOPs::const_iterator
2035 {
2036  return data_.end();
2037 }
2038 
2041 
2046 
2047 
2048 Size
2050  utility::vector1< Size > const & rotamer_index
2051 ) const
2052 {
2053  if ( rotamer_well_counts_.size() == 0 ) return 0;
2054  Size well_id = rotamer_index[ 1 ] - 1;
2055  for ( Size ii = 2; ii <= rotamer_well_counts_.size(); ++ii ) {
2056  well_id *= rotamer_well_counts_[ ii ];
2057  well_id += rotamer_index[ ii ] - 1;
2058  }
2059  return well_id + 1;
2060 }
2061 
2062 Size
2064  utility::LexicographicalIterator const & lexiter
2065 ) const
2066 {
2067  if ( rotamer_well_counts_.size() == 0 ) return 0;
2068  Size well_id = lexiter[ 1 ] - 1;
2069  for ( Size ii = 2; ii <= rotamer_well_counts_.size(); ++ii ) {
2070  well_id *= rotamer_well_counts_[ ii ];
2071  well_id += lexiter[ ii ] - 1;
2072  }
2073  return well_id + 1;
2074 }
2075 
2076 bool
2078  utility::vector1< Size > const & rotamer_index
2079 ) const
2080 {
2081  for ( Size ii = 1; ii <= native_rotamer_index_.size(); ++ii ) {
2082  if ( rotamer_index[ ii ] != native_rotamer_index_[ ii ] ) return false;
2083  }
2084  return true;
2085 }
2086 
2087 bool
2089  utility::LexicographicalIterator const & lexiter
2090 ) const
2091 {
2092  for ( Size ii = 1; ii <= native_rotamer_index_.size(); ++ii ) {
2093  if ( lexiter[ ii ] != native_rotamer_index_[ ii ] ) return false;
2094  }
2095  return true;
2096 }
2097 
2098 
2099 //
2100 // ------------------- PNatStructureOptEData-----------------------//
2101 //
2102 
2104 Real PNatStructureOptEData::nativeness_rms_low_( 1.0 ); // Above this rms, nativeness starts to decline
2105 Real PNatStructureOptEData::nativeness_rms_high_( 2.5 ); // Above this rms, nativeness is zero
2106 
2107 
2109 :
2110  total_residue_( 0 ),
2111  n_top_natives_to_score_( 1 ),
2112  n_high_entropy_decoys_( 0 ),
2113  normalize_decoy_stddev_( false ),
2114  initial_decoy_stddev_( 1.0 ),
2115  nativeness_sum_( 0.0 )
2116 {}
2117 
2119 {}
2120 
2121 
2122 Real
2124  optimization::Multivec const & component_weights,
2125  optimization::Multivec const & vars,
2126  optimization::Multivec & dE_dvars,
2127  /// Basically, turn over all the private data from OptEMultiFunc
2128  Size const num_energy_dofs,
2129  int const dummy1,
2130  int const dummy2,
2131  EnergyMap const & fixed_terms,
2132  ScoreTypes const & dummy3 /*free_score_list*/,
2133  ScoreTypes const & fixed_score_list
2134 ) const
2135 {
2136  return process_score(
2137  TR, false, component_weights, vars,
2138  dE_dvars, num_energy_dofs, dummy1, dummy2,
2139  fixed_terms, dummy3, fixed_score_list );
2140 }
2141 
2142 //{
2143 // using namespace core::optimization;
2144 // using namespace utility;
2145 // using namespace basic::options;
2146 // using namespace basic::options::OptionKeys;
2147 //
2148 // static Real const inv_kT( option[ optE::inv_kT_natstruct ] );
2149 // Real score_factor = option[ optE::approximate_decoy_entropy ].user() ? 1 : total_residue_;
2150 //
2151 // if ( decoys_.size() == 0 || natives_.size() == 0 ) return 0.0;
2152 //
2153 // Real const ln_nhighentropy_decoys = n_high_entropy_decoys_ > 0 ? std::log( (Real) n_high_entropy_decoys_ ) : 0;
2154 //
2155 // utility::vector1< Real > decoy_energies( decoys_.size(), 0.0 );
2156 // utility::vector1< Real > native_energies( natives_.size(), 0.0 );
2157 // for ( Size ii = 1; ii <= num_energy_dofs; ++ii ) {
2158 // for ( Size jj = 1; jj <= natives_.size(); ++jj ) {
2159 // native_energies[ jj ] += vars[ ii ] * natives_[ jj ]->free_data()[ ii ];
2160 // }
2161 // for ( Size jj = 1; jj <= decoys_.size(); ++jj ) {
2162 // decoy_energies[ jj ] += vars[ ii ] * decoys_[ jj ]->free_data()[ ii ];
2163 // }
2164 // }
2165 // for ( Size ii = 1; ii <= fixed_score_list.size(); ++ii ) {
2166 // for ( Size jj = 1; jj <= natives_.size(); ++jj ) {
2167 // native_energies[ jj ] += fixed_terms[ fixed_score_list[ ii ] ] * natives_[ jj ]->fixed_data()[ ii ];
2168 // }
2169 // for ( Size jj = 1; jj <= decoys_.size(); ++jj ) {
2170 // decoy_energies[ jj ] += fixed_terms[ fixed_score_list[ ii ] ] * decoys_[ jj ]->fixed_data()[ ii ];
2171 // }
2172 // }
2173 //
2174 // utility::vector1< Size > top_natives( n_top_natives_to_score_, 0 );
2175 // if ( n_top_natives_to_score_ == 1 ) {
2176 // top_natives[ 1 ] = arg_min( native_energies );
2177 // } else {
2178 // arg_least_several( native_energies, top_natives );
2179 // }
2180 // /*if ( top_natives.size() == 0 ) {
2181 // std::cerr << "No top natives?! "<< tag() << std::endl << "E:";
2182 // for ( Size ii = 1; ii <= native_energies.size(); ++ii ) {
2183 // std::cerr << " " << native_energies[ ii ];
2184 // }
2185 // std::cerr << std::endl;
2186 // }*/
2187 //
2188 // if ( normalize_decoy_stddev_ ) {
2189 //
2190 // Real sd = numeric::statistics::std_dev( decoy_energies.begin(), decoy_energies.end(), Real( 0.0 ));
2191 //
2192 // /// Avoid dividing by zero -- but what is the appropriate scale factor if the SD is measured 0?
2193 // Real const scaling_factor = sd == 0.0 ? 1 : initial_decoy_stdev_ < sd : initial_decoy_stddev_ / sd : 1.0; /// APL TEMP -- do not prevent the compression of decoy stdev; only prevent the expansion.
2194 // for ( Size jj = 1; jj <= decoy_energies.size(); ++jj ) {
2195 // decoy_energies[ jj ] *= scaling_factor;
2196 // }
2197 // for ( Size jj = 1; jj <= native_energies.size(); ++jj ) {
2198 // native_energies[ jj ] *= scaling_factor;
2199 // }
2200 // }
2201 //
2202 // /// Alpha is the expansion factor of conformation space as a function of the number of residues.
2203 // /// num states ~ alpha ^ N
2204 // /// therefore the entropy scales as N log alpha.
2205 // if ( option[ optE::approximate_decoy_entropy ].user() ) {
2206 // /// assume alpha constant over the course of an optE run
2207 // static Real const neg_lnalpha = -std::log( option[ optE::approximate_decoy_entropy ] );
2208 // Real const energy_offset = neg_lnalpha * total_residue_ + ln_nhighentropy_decoys;
2209 // Real const offset = ( energy_offset < 0 ) ? energy_offset : 0;
2210 // for ( Size jj = 1; jj <= decoys_.size(); ++jj ) {
2211 // if ( decoys_[ jj ]->rms() > high_entropy_rms_cutoff_ ) {
2212 // decoy_energies[ jj ] += offset;
2213 // }
2214 // }
2215 // }
2216 //
2217 // /// Now normalize for numerical stability by setting the best native or decoy to have an energy of 0
2218 // /// and set everything else to be a delta from there.
2219 // Real best_native_energy = native_energies[ top_natives[ 1 ] ];
2220 // Real const best_decoy_energy = min( decoy_energies );
2221 // Real const best_energy = best_native_energy < best_decoy_energy ? best_native_energy : best_decoy_energy;
2222 //
2223 // for ( Size ii = 1; ii <= top_natives.size(); ++ii ) {
2224 // native_energies[ top_natives[ ii ] ] -= best_energy;
2225 // }
2226 // for ( Size ii = 1; ii <= decoys_.size(); ++ii ) {
2227 // decoy_energies[ ii ] -= best_energy;
2228 // }
2229 //
2230 //
2231 // Real numerator(0.0), partition(0.0);
2232 // Multivec dpartition( vars.size(), 0.0 ), dnumerator( vars.size(), 0.0 );
2233 //
2234 // for ( Size ii = 1; ii <= top_natives.size(); ++ii ) {
2235 // Real exp_term( std::exp( -1.0 * inv_kT * native_energies[ top_natives[ ii ] ] ) );
2236 // // iwd Limit the improbability of each native to 1 in a million
2237 // // This prevents numerator ~ 0, which causes NANs and INFs in the derivatives
2238 // // It also limits the "force" that any one structure can exert on the minimization.
2239 // exp_term = std::max( 1e-6, exp_term );
2240 //
2241 // partition += exp_term;
2242 // numerator += exp_term;
2243 // // partitions for energy derivatives
2244 // for( Size e_dof(1); e_dof <= num_energy_dofs; ++e_dof ) {
2245 // // note for derivatives: d/dw( e^-(E*w+...) ) = -E * e^-(E*w+...)
2246 // Real e_dof_deriv( -1.0 * inv_kT * score_factor * natives_[ top_natives[ ii ] ]->free_data()[ e_dof ] * exp_term );
2247 // dpartition[ e_dof ] += e_dof_deriv;
2248 // dnumerator[ e_dof ] += e_dof_deriv;
2249 // }
2250 // }
2251 //
2252 // for( Size ii(1); ii <= decoys_.size(); ++ii ) {
2253 //
2254 // Real const exp_term( std::exp( -1.0 * inv_kT * decoy_energies[ ii ] ) );
2255 // partition += exp_term;
2256 //
2257 // // partitions for energy derivatives
2258 // for( Size e_dof(1); e_dof <= num_energy_dofs; ++e_dof ) {
2259 // // note for derivatives: d/dw( e^{-(E*w+...)/kT} ) = -E/kT * e^-(E*w+...)
2260 // Real e_dof_deriv( -1.0 * inv_kT * score_factor * decoys_[ ii ]->free_data()[ e_dof ] * exp_term );
2261 // dpartition[ e_dof ] += e_dof_deriv;
2262 // }
2263 // }
2264 //
2265 // // accumulate to passed-in derivative sums -- excludes reference energies
2266 // //std::cout << "vars (dvars): ";
2267 // for ( Size dof(1); dof <= num_energy_dofs; ++dof ) {
2268 // dE_dvars[ dof ] += component_weights[ prob_native_structure ] * (dpartition[ dof ] / partition - dnumerator[ dof ] / numerator);
2269 // //std::cout << " " << vars[ dof ] << "(" << dpartition[ dof ] / partition - dnumerator[ dof ] / numerator << ")";
2270 // }
2271 //
2272 // //std::cout << "struct score: " << best_native << " " << best_native_energy << " " ;
2273 // //std::cout << nat_exp_term << " " << partition << " : " << ( -1.0 * total_residue_ * std::log( numerator / partition ) ) << std::endl;
2274 //
2275 //
2276 // /*if ( partition == 0 ) {
2277 // std::cerr << tag() << " partition of zero: inv_kT " << inv_kT;
2278 // for ( Size ii = 1; ii <= decoys_.size(); ++ii ) {
2279 // std::cerr << " d: " << decoy_energies[ ii ] << " " << std::exp( -1.0 * inv_kT * decoy_energies[ ii ] ) << " ";
2280 // for ( Size jj = 1; jj <= num_energy_dofs; ++jj ) {
2281 // std::cerr << free_score_list[ jj ] << ": " << decoys_[ ii ]->free_data()[ jj ] << " ";
2282 // }
2283 // std::cerr << std::endl;
2284 // }
2285 // for ( Size ii = 1; ii <= top_natives.size(); ++ii ) {
2286 // std::cerr << " top nat: " << native_energies[ top_natives[ ii ] ] << " " << std::exp( -1.0 * inv_kT * native_energies[ top_natives[ ii ] ] ) << " ";
2287 // for ( Size jj = 1; jj <= num_energy_dofs; ++jj ) {
2288 // std::cerr << free_score_list[ jj ] << ": " << natives_[ top_natives[ ii ] ]->free_data()[ jj ] << " ";
2289 // }
2290 // std::cerr << std::endl;
2291 // }
2292 // std::cerr << std::endl;
2293 // for ( Size ii = 1; ii <= num_energy_dofs; ++ii ) {
2294 // std::cerr << " " << free_score_list[ ii ] << ": " << vars[ ii ] << std::endl;
2295 // }
2296 // return 0.0;
2297 // }*/
2298 //
2299 //
2300 // return ( -1.0 * component_weights[ prob_native_structure ] * score_factor * std::log( numerator / partition ) );
2301 //}
2302 
2303 
2304 void
2306  std::ostream & ostr,
2307  optimization::Multivec const & component_weights,
2308  optimization::Multivec const & vars,
2309  optimization::Multivec & dE_dvars,
2310  /// Basically, turn over all the private data from OptEMultiFunc
2311  Size const num_energy_dofs,
2312  int const dummy1,
2313  int const dummy2,
2314  EnergyMap const & fixed_terms,
2315  ScoreTypes const & dummy3,
2316  ScoreTypes const & fixed_score_list
2317 ) const
2318 {
2319  process_score(
2320  ostr, true, component_weights, vars,
2321  dE_dvars, num_energy_dofs, dummy1, dummy2,
2322  fixed_terms, dummy3, fixed_score_list );
2323 }
2324 
2325 Real
2327  std::ostream & ostr,
2328  bool print,
2329  optimization::Multivec const & component_weights,
2330  optimization::Multivec const & vars,
2331  optimization::Multivec & dE_dvars,
2332  /// Basically, turn over all the private data from OptEMultiFunc
2333  Size const num_energy_dofs,
2334  int const,
2335  int const,
2336  EnergyMap const & fixed_terms,
2337  ScoreTypes const &,
2338  ScoreTypes const & fixed_score_list
2339 ) const
2340 {
2341  using namespace core::optimization;
2342  using namespace utility;
2343  using namespace basic::options;
2344  using namespace basic::options::OptionKeys;
2345 
2346  static Real const inv_kT( option[ optE::inv_kT_natstruct ] );
2347  Real score_factor = option[ optE::approximate_decoy_entropy ].user() ? 1 : total_residue_;
2348 
2349  if ( decoys_.size() == 0 || natives_.size() == 0 ) {
2350  if ( print ) {
2351  ostr << "PNATSTRUCT " << total_residue_ << " nnat: " << natives_.size() << " ndec: " << decoys_.size() << tag() << "\n";
2352  }
2353  return 0.0; // wtf?
2354  }
2355 
2356  //TR << "PNatStructureOptEData::print_score" << std::endl;
2357 
2358  /// Compute the energies for natives and decoys given the set of input weights;
2359  utility::vector1< Real > decoy_energies( decoys_.size(), 0.0 );
2360  utility::vector1< Real > native_energies( natives_.size(), 0.0 );
2361  for ( Size ii = 1; ii <= num_energy_dofs; ++ii ) {
2362  for ( Size jj = 1; jj <= natives_.size(); ++jj ) {
2363  native_energies[ jj ] += vars[ ii ] * natives_[ jj ]->free_data()[ ii ];
2364  }
2365  for ( Size jj = 1; jj <= decoys_.size(); ++jj ) {
2366  decoy_energies[ jj ] += vars[ ii ] * decoys_[ jj ]->free_data()[ ii ];
2367  }
2368  }
2369  for ( Size ii = 1; ii <= fixed_score_list.size(); ++ii ) {
2370  for ( Size jj = 1; jj <= natives_.size(); ++jj ) {
2371  native_energies[ jj ] += fixed_terms[ fixed_score_list[ ii ] ] * natives_[ jj ]->fixed_data()[ ii ];
2372  }
2373  for ( Size jj = 1; jj <= decoys_.size(); ++jj ) {
2374  decoy_energies[ jj ] += fixed_terms[ fixed_score_list[ ii ] ] * decoys_[ jj ]->fixed_data()[ ii ];
2375  }
2376  }
2377 
2378 
2379  // avoid allocating these arrays if you're not going to use them;
2380  utility::vector1< Real > noentropy_decoy_energies;
2381  utility::vector1< Real > noentropy_native_energies;
2382  if ( print ) {
2383  noentropy_decoy_energies = decoy_energies;
2384  noentropy_native_energies = native_energies;
2385 
2386  //// Normalize the "noentropy" energies
2387  Real const noentropy_best_native_energy = min( noentropy_native_energies );
2388  Real const noentropy_best_decoy_energy = min( noentropy_decoy_energies );
2389  bool const noentropy_native_beats_decoys( noentropy_best_native_energy < noentropy_best_decoy_energy );
2390  Real const noentropy_best_energy = noentropy_native_beats_decoys ? noentropy_best_native_energy : noentropy_best_decoy_energy;
2391 
2392  for ( Size ii = 1; ii <= native_energies.size(); ++ii ) {
2393  noentropy_native_energies[ ii ] -= noentropy_best_energy;
2394  }
2395  for ( Size ii = 1; ii <= decoys_.size(); ++ii ) {
2396  noentropy_decoy_energies[ ii ] -= noentropy_best_energy;
2397  }
2398 
2399  }
2400 
2401  if ( normalize_decoy_stddev_ ) {
2402 
2403  Real sd = numeric::statistics::std_dev( decoy_energies.begin(), decoy_energies.end(), Real( 0.0 ));
2404 
2405  /// Avoid dividing by zero -- but what is the appropriate scale factor if the SD is measured 0?
2406  Real const scaling_factor = sd == 0.0 ? 1 : initial_decoy_stddev_ / sd;
2407  for ( Size jj = 1; jj <= decoy_energies.size(); ++jj ) {
2408  decoy_energies[ jj ] *= scaling_factor;
2409  }
2410  for ( Size jj = 1; jj <= native_energies.size(); ++jj ) {
2411  native_energies[ jj ] *= scaling_factor;
2412  }
2413  }
2414 
2415  /// Alpha is the expansion factor of conformation space as a function of the number of residues.
2416  /// num states ~= alpha ^ N
2417  /// therefore the entropy scales as N log( alpha ).
2418 
2419  if ( option[ optE::approximate_decoy_entropy ].user() ) {
2420  /// assume alpha is constant over the course of an optE run
2421  static Real const neg_lnalpha = -std::log( option[ optE::approximate_decoy_entropy ] );
2422 
2423  Real const energy_offset = neg_lnalpha * total_residue_ + std::log( (Real)n_high_entropy_decoys_ );
2424  Real const offset = ( energy_offset < 0 ) ? energy_offset : 0;
2425  for ( Size jj = 1; jj <= decoys_.size(); ++jj ) {
2426  if ( decoys_[ jj ]->rms() > high_entropy_rms_cutoff_ ) {
2427  decoy_energies[ jj ] += offset;
2428  }
2429  }
2430  }
2431 
2432  if ( option[ optE::ramp_nativeness ] ) {
2433  Real native_entropy_penalty = std::log( nativeness_sum_ );
2434  for ( Size jj = 1; jj <= native_energies.size(); ++jj ) {
2435  native_energies[ jj ] += native_entropy_penalty;
2436  }
2437  }
2438 
2440  if ( n_top_natives_to_score_ == 1 ) {
2441  top_natives[ 1 ] = arg_min( native_energies );
2442  } else if ( option[ optE::approximate_decoy_entropy ].user() ) {
2443  /// ALL nativish structures are getting scored; it's only important
2444  /// that the best native structure is in position 1 of the top_natives array.
2445  top_natives[ 1 ] = arg_min( native_energies );
2446  for ( Size ii = 2; ii <= n_top_natives_to_score_; ++ii ) top_natives[ ii ] = ii;
2447  top_natives[ top_natives[ 1 ] ] = 1;
2448  } else {
2449  arg_least_several( native_energies, top_natives );
2450  }
2451 
2452  /// Normalize the scores so that the energy of the best structure
2453  /// is zero, and all other energies are positive.
2454  Real best_native_energy = native_energies[ top_natives[ 1 ] ];
2455  Real const best_decoy_energy = min( decoy_energies );
2456  bool const native_beats_decoys( best_native_energy < best_decoy_energy );
2457  Real const best_energy = native_beats_decoys ? best_native_energy : best_decoy_energy;
2458 
2459  for ( Size ii = 1; ii <= native_energies.size(); ++ii ) native_energies[ ii ] -= best_energy;
2460  for ( Size ii = 1; ii <= decoys_.size(); ++ii ) decoy_energies[ ii ] -= best_energy;
2461 
2462 
2463  Real numerator(0.0), partition(0.0);
2464  Multivec dpartition( vars.size(), 0.0 ), dnumerator( vars.size(), 0.0 );
2465 
2466  for ( Size ii = 1; ii <= top_natives.size(); ++ii ) {
2467  Real exp_term( std::exp( -1.0 * inv_kT * native_energies[ top_natives[ ii ] ] ) );
2468  // iwd Limit the improbability of each native to 1 in a million
2469  // This prevents numerator ~ 0, which causes NANs and INFs in the derivatives
2470  // It also limits the "force" that any one structure can exert on the minimization.
2471  exp_term = std::max( 1e-6, exp_term );
2472 
2473  Real iinativeness = nativeness( natives_[ top_natives[ ii ] ]->rms() );
2474  partition += exp_term;
2475  numerator += exp_term * iinativeness;
2476  // partitions for energy derivatives
2477  for( Size e_dof(1); e_dof <= num_energy_dofs; ++e_dof ) {
2478  // note for derivatives: d/dw( e^-(E*w+...) ) = -E * e^-(E*w+...)
2479  Real e_dof_deriv( -1.0 * inv_kT * score_factor * natives_[ top_natives[ ii ] ]->free_data()[ e_dof ] * exp_term );
2480  dpartition[ e_dof ] += e_dof_deriv;
2481  dnumerator[ e_dof ] += iinativeness * e_dof_deriv ;
2482  }
2483  }
2484 
2485  for( Size ii(1); ii <= decoys_.size(); ++ii ) {
2486 
2487  Real const exp_term( std::exp( -1.0 * inv_kT * decoy_energies[ ii ] ) );
2488  partition += exp_term;
2489 
2490  // partitions for energy derivatives
2491  for( Size e_dof(1); e_dof <= num_energy_dofs; ++e_dof ) {
2492  // note for derivatives: d/dw( e^{-(E*w+...)/kT} ) = -E/kT * e^-(E*w+...)
2493  Real e_dof_deriv( -1.0 * inv_kT * score_factor * decoys_[ ii ]->free_data()[ e_dof ] * exp_term );
2494  dpartition[ e_dof ] += e_dof_deriv;
2495  }
2496  }
2497 
2498  // accumulate to passed-in derivative sums -- excludes reference energies
2499  //std::cout << "vars (dvars): ";
2500  for ( Size dof(1); dof <= num_energy_dofs; ++dof ) {
2501  dE_dvars[ dof ] += dpartition[ dof ] / partition - dnumerator[ dof ] / numerator;
2502  }
2503 
2504  if ( print ) {
2505  ostr << "PNATSTRUCT " << total_residue_ << " nnat: " << natives_.size() << " ndec: " << decoys_.size();
2506  ostr << " n<d? " << native_beats_decoys << " p: " << numerator / partition;
2507  ostr << " -lnp: " << -1 * std::log( numerator / partition ) << " -wlnp " << -1.0 * score_factor * std::log( numerator / partition );
2508  ostr << " -compwt_lnp " << component_weights[ prob_native_structure ] * -1.0 * score_factor * std::log( numerator / partition );
2509  ostr << " " << tag() << "\n";
2510 
2511  for ( Size ii = 1; ii <= natives_.size(); ++ii ) {
2512  ostr << "DECDISCRIM NATIVE " << tag() << " rms: " << natives_[ ii ]->rms() << " sc(w/o_etropy): " << noentropy_native_energies[ ii ] << " sc(w/entropy): " << native_energies[ ii ] << " " << natives_[ ii ]->tag() << "\n";
2513  }
2514  for ( Size ii = 1; ii <= decoys_.size(); ++ii ) {
2515  ostr << "DECDISCRIM DECOY " << tag() << " rms: " << decoys_[ ii ]->rms() << " sc(w/o_entropy): " << noentropy_decoy_energies[ ii ] << " sc(w/entropy): " << decoy_energies[ ii ] << " " << decoys_[ ii ]->tag() << "\n";
2516  }
2517  }
2518  return ( -1.0 * component_weights[ prob_native_structure ] * score_factor * std::log( numerator / partition ) );
2519 }
2520 
2521 
2522 void
2524  ScoreTypes const & free_score_list,
2525  ScoreTypes const & fixed_score_list,
2526  EnergyMap & lower_bound,
2527  EnergyMap & upper_bound
2528 ) const
2529 {
2530  for ( Size jj = 1; jj <= natives_.size(); ++jj ) {
2531  update_range( natives_[ jj ], free_score_list, fixed_score_list, lower_bound, upper_bound );
2532  }
2533  for ( Size jj = 1; jj <= decoys_.size(); ++jj ) {
2534  update_range( decoys_[ jj ], free_score_list, fixed_score_list, lower_bound, upper_bound );
2535  }
2536 }
2537 
2538 Size
2540 {
2541  return natives_.size() + decoys_.size();
2542 }
2543 
2544 
2547 {
2548  return prob_native_structure;
2549 }
2550 
2551 
2552 void
2553 PNatStructureOptEData::write_to_file( std::ofstream & /*outfile*/ ) const
2554 {}
2555 
2556 
2557 void
2558 PNatStructureOptEData::read_from_file( std::ifstream & /*infile*/ )
2559 {}
2560 
2561 
2562 void
2563 PNatStructureOptEData::write_to_binary_file( std::ofstream & /*outfile*/ ) const
2564 {}
2565 
2566 
2567 void
2569 {}
2570 
2571 
2572 Size
2574 {
2575  Size total = sizeof( PNatStructureOptEData ) +
2576  sizeof( SingleStructureData ) * natives_.size() +
2577  sizeof( SingleStructureData ) * decoys_.size();
2578  if ( natives_.size() > 0 ) {
2579  total += sizeof( Real ) * ( natives_[ 1 ]->free_data().size() + natives_[ 1 ]->fixed_data().size() ) * natives_.size();
2580  }
2581  if ( decoys_.size() > 0 ) {
2582  total += sizeof( Real ) * ( decoys_[ 1 ]->free_data().size() + decoys_[ 1 ]->fixed_data().size() ) * decoys_.size();
2583  }
2584  return total;
2585 }
2586 
2587 
2588 #ifdef USEMPI
2589 
2590 void
2591 PNatStructureOptEData::send_to_node( int const destination_node, int const tag ) const
2592 {
2593  //std::cout << "sending total_residue to node " << destination_node << std::endl;
2594  /// 1. total residue
2595  Size total_residue = total_residue_;
2596  MPI_Send( & total_residue, 1, MPI_UNSIGNED_LONG, destination_node, tag, MPI_COMM_WORLD );
2597 
2598  /// 1b. n_top_natives_to_score_
2599  Size n_top = n_top_natives_to_score_;
2600  MPI_Send( & n_top, 1, MPI_UNSIGNED_LONG, destination_node, tag, MPI_COMM_WORLD );
2601 
2602  // 2a. n natives
2603  //std::cout << "sending nnatives to node " << destination_node << std::endl;
2604  Size nnatives = natives_.size();
2605  MPI_Send( & nnatives, 1, MPI_UNSIGNED_LONG, destination_node, tag, MPI_COMM_WORLD );
2606 
2607  /// 2b. n decoys
2608  //std::cout << "sending ndecoys to node " << destination_node << std::endl;
2609  Size ndecoys = decoys_.size();
2610  MPI_Send( & ndecoys, 1, MPI_UNSIGNED_LONG, destination_node, tag, MPI_COMM_WORLD );
2611 
2612  /// 2c. n_high_entropy_decoys_
2613  //std::cout << "sending ndecoys to node " << destination_node << std::endl;
2614  Size n_high_entropy_decoys = n_high_entropy_decoys_;
2615  MPI_Send( & n_high_entropy_decoys, 1, MPI_UNSIGNED_LONG, destination_node, tag, MPI_COMM_WORLD );
2616 
2617  /// 2d. normalize_decoy_stddev_
2618  int normalize_decoy_stddev = static_cast< int > (normalize_decoy_stddev_);
2619  MPI_Send( & normalize_decoy_stddev, 1, MPI_INT, destination_node, tag, MPI_COMM_WORLD );
2620 
2621  /// 2e. initial_decoy_stddev_
2622  Real initial_decoy_stddev = initial_decoy_stddev_;
2623  MPI_Send( & initial_decoy_stddev, 1, MPI_DOUBLE, destination_node, tag, MPI_COMM_WORLD );
2624 
2625  /// 2f. nativeness_sum_
2626  Real nativeness_sum( nativeness_sum_ );
2627  MPI_Send( & nativeness_sum, 1, MPI_DOUBLE, destination_node, tag, MPI_COMM_WORLD );
2628 
2629 
2630  if ( nnatives == 0 || ndecoys == 0 ) {
2631  OptEPositionData::send_to_node( destination_node, tag );
2632  return;
2633  }
2634 
2635  /// 3. n free
2636  Size n_free = decoys_[ 1 ]->free_data().size();
2637  //std::cout << "sending n_free to node " << destination_node << " " << n_free << std::endl;
2638  MPI_Send( & n_free, 1, MPI_UNSIGNED_LONG, destination_node, tag, MPI_COMM_WORLD );
2639 
2640  /// 4. n fixed
2641  Size n_fixed = decoys_[ 1 ]->fixed_data().size();
2642  //std::cout << "sending n_fixed to node " << destination_node << " " << n_fixed << std::endl;
2643  MPI_Send( & n_fixed, 1, MPI_UNSIGNED_LONG, destination_node, tag, MPI_COMM_WORLD );
2644 
2645  /// Send natives, then send decoys
2646  Real * rms = new Real[ nnatives ];
2647  Real * free_data = new Real[ n_free * nnatives ];
2648  Real * fixed_data = new Real[ n_fixed * nnatives ];
2649  for ( Size ii = 1; ii <= nnatives; ++ ii ) {
2650  rms[ (ii-1) ] = natives_[ ii ]->rms();
2651  for ( Size jj = 1; jj <= n_free; ++jj ) {
2652  free_data[ ( ii - 1 ) * n_free + ( jj - 1 ) ] = natives_[ ii ]->free_data()[ jj ];
2653  }
2654  for ( Size jj = 1; jj <= n_fixed; ++jj ) {
2655  fixed_data[ ( ii - 1 ) * n_fixed + ( jj - 1 ) ] = natives_[ ii ]->fixed_data()[ jj ];
2656  }
2657  }
2658 
2659  MPI_Send( rms, nnatives, MPI_DOUBLE, destination_node, tag, MPI_COMM_WORLD );
2660 
2661  //std::cout << "sending native free_data to node " << destination_node << " " << free_data << std::endl;
2662  /// 5. native free data
2663  MPI_Send( free_data, nnatives * n_free, MPI_DOUBLE, destination_node, tag, MPI_COMM_WORLD );
2664 
2665  //std::cout << "sending native fixed_data to node " << destination_node << " " << fixed_data << std::endl;
2666  /// 6. fixed data
2667  MPI_Send( fixed_data, nnatives * n_fixed, MPI_DOUBLE, destination_node, tag, MPI_COMM_WORLD );
2668 
2669  //std::cout << "Sent -- about to delete data" << std::endl;
2670 
2671  /// now send decoys
2672  Real * decoy_rms = new Real[ ndecoys ];
2673  Real * decoy_free_data = new Real[ n_free * ndecoys ];
2674  Real * decoy_fixed_data = new Real[ n_fixed * ndecoys ];
2675  for ( Size ii = 1; ii <= ndecoys; ++ ii ) {
2676  decoy_rms[ (ii-1) ] = decoys_[ ii ]->rms();
2677  for ( Size jj = 1; jj <= n_free; ++jj ) {
2678  decoy_free_data[ ( ii - 1 ) * n_free + ( jj - 1 ) ] = decoys_[ ii ]->free_data()[ jj ];
2679  }
2680  for ( Size jj = 1; jj <= n_fixed; ++jj ) {
2681  decoy_fixed_data[ ( ii - 1 ) * n_fixed + ( jj - 1 ) ] = decoys_[ ii ]->fixed_data()[ jj ];
2682  }
2683  }
2684 
2685  MPI_Send( decoy_rms, ndecoys, MPI_DOUBLE, destination_node, tag, MPI_COMM_WORLD );
2686 
2687  /// 7. decoy free data
2688  //std::cout << "sending decoy free_data to node " << destination_node << std::endl;
2689  MPI_Send( decoy_free_data, ndecoys * n_free, MPI_DOUBLE, destination_node, tag, MPI_COMM_WORLD );
2690 
2691  /// 8. decoy fixed data
2692  //std::cout << "sending decoy fixed_data to node " << destination_node << std::endl;
2693  MPI_Send( decoy_fixed_data, ndecoys * n_fixed, MPI_DOUBLE, destination_node, tag, MPI_COMM_WORLD );
2694 
2695  delete [] rms;
2696  delete [] free_data;
2697  delete [] fixed_data;
2698 
2699  delete [] decoy_rms;
2700  delete [] decoy_free_data;
2701  delete [] decoy_fixed_data;
2702 
2703  /// 9. structure tags
2704  /// 9a. natives
2705  for ( Size ii = 1; ii <= natives_.size(); ++ii ) {
2706  IterativeOptEDriver::send_string_to_node( destination_node, natives_[ ii ]->tag() );
2707  }
2708  /// 9b. decoys
2709  for ( Size ii = 1; ii <= decoys_.size(); ++ii ) {
2710  IterativeOptEDriver::send_string_to_node( destination_node, decoys_[ ii ]->tag() );
2711  }
2712 
2713  OptEPositionData::send_to_node( destination_node, tag );
2714 
2715 }
2716 
2717 void
2718 PNatStructureOptEData::receive_from_node( int const source_node, int const tag )
2719 {
2720  MPI_Status stat;
2721  //TR << "PNatStructureOptEData::Recieving data from node... " << source_node << std::endl;
2722 
2723  /// 1. total residue
2724  Size total_residue( 0 );
2725  MPI_Recv( & total_residue, 1, MPI_UNSIGNED_LONG, source_node, tag, MPI_COMM_WORLD, &stat );
2726  total_residue_ = total_residue;
2727 
2728  /// 1b. n_top_natives_to_score_
2729  Size n_top;
2730  MPI_Recv( & n_top, 1, MPI_UNSIGNED_LONG, source_node, tag, MPI_COMM_WORLD, &stat );
2731  n_top_natives_to_score_ = n_top;
2732 
2733  /// 2a. n natives
2734  Size nnatives( 0 );
2735  MPI_Recv( & nnatives, 1, MPI_UNSIGNED_LONG, source_node, tag, MPI_COMM_WORLD, &stat );
2736 
2737  /// 2b. n decoys
2738  Size ndecoys( 0 );
2739  MPI_Recv( & ndecoys, 1, MPI_UNSIGNED_LONG, source_node, tag, MPI_COMM_WORLD, &stat );
2740 
2741  /// 2c. n_high_entropy_decoys_
2742  //std::cout << "sending ndecoys to node " << destination_node << std::endl;
2743  Size n_high_entropy_decoys( 0 );
2744  MPI_Recv( & n_high_entropy_decoys, 1, MPI_UNSIGNED_LONG, source_node, tag, MPI_COMM_WORLD, &stat );
2745  n_high_entropy_decoys_ = n_high_entropy_decoys;
2746 
2747  /// 2d. normalize_decoy_stddev_
2748  int normalize_decoy_stddev( 0 );
2749  MPI_Recv( & normalize_decoy_stddev, 1, MPI_INT, source_node, tag, MPI_COMM_WORLD, &stat );
2750  normalize_decoy_stddev_ = static_cast< bool > (normalize_decoy_stddev);
2751 
2752  /// 2e. initial_decoy_stddev_
2753  Real initial_decoy_stddev( 1.0 );
2754  MPI_Recv( & initial_decoy_stddev, 1, MPI_DOUBLE, source_node, tag, MPI_COMM_WORLD, &stat );
2755  initial_decoy_stddev_ = initial_decoy_stddev;
2756 
2757  /// 2f. nativeness_sum_
2758  Real nativeness_sum( 0.0 );
2759  MPI_Recv( & nativeness_sum, 1, MPI_DOUBLE, source_node, tag, MPI_COMM_WORLD, &stat );
2760  nativeness_sum_ = nativeness_sum;
2761 
2762  if ( nnatives == 0 || ndecoys == 0 ) {
2763  OptEPositionData::receive_from_node( source_node, tag );
2764  return;
2765  }
2766  natives_.reserve( nnatives );
2767  decoys_.reserve( ndecoys );
2768 
2769  /// 3. n free
2770  Size n_free( 0 );
2771  MPI_Recv( & n_free, 1, MPI_UNSIGNED_LONG, source_node, tag, MPI_COMM_WORLD, &stat );
2772 
2773  /// 4. n fixed
2774  Size n_fixed( 0 );
2775  MPI_Recv( & n_fixed, 1, MPI_UNSIGNED_LONG, source_node, tag, MPI_COMM_WORLD, &stat );
2776 
2777  /// Recieve native data first, then decoys
2778  Real * rms = new Real[ nnatives ];
2779  Real * free_data = new Real[ n_free * nnatives ];
2780  Real * fixed_data = new Real[ n_fixed * nnatives ];
2781 
2782  MPI_Recv( rms, nnatives, MPI_DOUBLE, source_node, tag, MPI_COMM_WORLD, &stat );
2783 
2784  /// 5. free data
2785  MPI_Recv( free_data, nnatives * n_free, MPI_DOUBLE, source_node, tag, MPI_COMM_WORLD, &stat );
2786 
2787  /// 6. fixed data
2788  MPI_Recv( fixed_data, nnatives * n_fixed, MPI_DOUBLE, source_node, tag, MPI_COMM_WORLD, &stat );
2789 
2790  utility::vector1< Real > free_data_v( n_free );
2791  utility::vector1< Real > fixed_data_v( n_fixed );
2792  for ( Size ii = 1; ii <= nnatives; ++ ii ) {
2793  for ( Size jj = 1; jj <= n_free; ++jj ) {
2794  free_data_v[ jj ] = free_data[ ( ii - 1 ) * n_free + ( jj - 1 ) ];
2795  }
2796  for ( Size jj = 1; jj <= n_fixed; ++jj ) {
2797  fixed_data_v[ jj ] = fixed_data[ ( ii - 1 ) * n_fixed + ( jj - 1 ) ];
2798  }
2799  natives_.push_back( new SingleStructureData( free_data_v, fixed_data_v ) );
2800  natives_[ ii ]->rms( rms[ ii-1 ] );
2801  //std::cout << "recieved native with rms: " << rms[ (ii-1) ] << std::endl;
2802  }
2803 
2804  delete [] rms; rms = 0;
2805  delete [] free_data; free_data = 0;
2806  delete [] fixed_data; fixed_data = 0;
2807 
2808  //// Now receive decoy data
2809  rms = new Real[ ndecoys ];
2810  free_data = new Real[ n_free * ndecoys ];
2811  fixed_data = new Real[ n_fixed * ndecoys ];
2812 
2813  MPI_Recv( rms, ndecoys, MPI_DOUBLE, source_node, tag, MPI_COMM_WORLD, &stat );
2814 
2815  /// 5. free data
2816  MPI_Recv( free_data, ndecoys * n_free, MPI_DOUBLE, source_node, tag, MPI_COMM_WORLD, &stat );
2817 
2818  /// 6. fixed data
2819  MPI_Recv( fixed_data, ndecoys * n_fixed, MPI_DOUBLE, source_node, tag, MPI_COMM_WORLD, &stat );
2820 
2821  for ( Size ii = 1; ii <= ndecoys; ++ ii ) {
2822  for ( Size jj = 1; jj <= n_free; ++jj ) {
2823  free_data_v[ jj ] = free_data[ ( ii - 1 ) * n_free + ( jj - 1 ) ];
2824  }
2825  for ( Size jj = 1; jj <= n_fixed; ++jj ) {
2826  fixed_data_v[ jj ] = fixed_data[ ( ii - 1 ) * n_fixed + ( jj - 1 ) ];
2827  }
2828  decoys_.push_back( new SingleStructureData( free_data_v, fixed_data_v ) );
2829  decoys_[ ii ]->rms( rms[ ii - 1 ] );
2830  //std::cout << "recieved decoy with rms: " << rms[ (ii-1) ] << std::endl;
2831  }
2832 
2833 
2834  delete [] rms;
2835  delete [] free_data;
2836  delete [] fixed_data;
2837 
2838  /// 9. structure tags
2839  /// 9a. natives
2840  for ( Size ii = 1; ii <= natives_.size(); ++ii ) {
2841  natives_[ ii ]->tag( IterativeOptEDriver::receive_string_from_node( source_node ));
2842  }
2843  /// 9b. decoys
2844  for ( Size ii = 1; ii <= decoys_.size(); ++ii ) {
2845  decoys_[ ii ]->tag( IterativeOptEDriver::receive_string_from_node( source_node ));
2846  }
2847 
2848 
2849  OptEPositionData::receive_from_node( source_node, tag );
2850 
2851 }
2852 #endif
2853 
2854 
2855 void
2857 {
2858  natives_.push_back( native );
2859  if ( basic::options::option[ basic::options::OptionKeys::optE::ramp_nativeness ] ) {
2860  nativeness_sum_ += nativeness( native->rms() );
2862  }
2863 }
2864 
2865 void
2867 {
2868  decoys_.push_back( decoy );
2869  if ( decoy->rms() > high_entropy_rms_cutoff_ ) {
2871  }
2872 }
2873 
2874 void
2876  total_residue_ = total_residue;
2877  //total_residue_ = 1; // This line removes the total-residue reweighting.
2878 }
2879 
2880 void
2882 {
2883  if ( n_top < 1 ) {
2884  std::cerr << "ERROR: PNatStructureOptEData will not score fewer than one top native!" << std::endl;
2885  utility_exit();
2886  }
2887  n_top_natives_to_score_ = n_top;
2888 }
2889 
2890 Size
2892 {
2893  return n_top_natives_to_score_;
2894 }
2895 
2896 void
2898 {
2899  normalize_decoy_stddev_ = setting;
2900 }
2901 
2902 void
2904 {
2905  initial_decoy_stddev_ = setting;
2906 }
2907 
2908 Real
2910 {
2911  static bool ramp_nativeness( basic::options::option[ basic::options::OptionKeys::optE::ramp_nativeness ] );
2912  return ! ramp_nativeness ? 1.0 :
2913  rms < nativeness_rms_low_ ? 1.0 : ( rms > nativeness_rms_high_ ? 0.0 :
2915 }
2916 
2917 void
2919 {
2920  nativeness_rms_low_ = nativeness_rms_low;
2921 }
2922 
2923 void
2925 {
2926  nativeness_rms_high_= nativeness_rms_high;
2927 
2928 }
2929 
2930 Real
2932 {
2933  return nativeness_rms_low_;
2934 }
2935 
2936 Real
2938 {
2939  return nativeness_rms_high_;
2940 }
2941 
2942 
2943 /////////////////////////////////////////////
2944 //// ConstraintedOptimizationWeightFunc /////
2945 /////////////////////////////////////////////
2946 
2948 
2950  ScoreTypes const & score_list
2951 )
2952 :
2953  free_terms_( score_list ),
2954  free_term_constraints_( score_list.size() )
2955 {
2956 
2957 }
2958 
2960 {}
2961 
2962 
2963 /// @details Constraint input file format:
2964 /// ON <score_type> <min_val> <max_val> <spring_constant>
2965 /// OFF <score_type>
2966 /// Where score_type is a string; min_val, max_val, and spring_constant are reals
2967 void
2969 {
2970  std::string on_off;
2971  std::string term_name;
2972  ScoreType term( ScoreType(1) );
2973  Real min_val;
2974  Real max_val;
2975  Real spring_constant;
2976 
2977  utility::vector1< bool > score_types_seen( core::scoring::n_score_types, false );
2978  while ( infile ) {
2979  infile >> on_off;
2980  if ( ! infile ) break;
2981 
2982  infile >> term_name;
2985  } else {
2986  std::cerr << "ERROR reading '" << term_name << "' in weight-constraint input file as a ScoreType." << std::endl;
2987  utility_exit();
2988  }
2989 
2990  if ( score_types_seen[ term ] ) {
2991  std::cerr << "ERROR initializing weight-constraints from file: term '" << term_name << "' repeated in input file" << std::endl;
2992  utility_exit();
2993  }
2994 
2995  score_types_seen[ term ] = true;
2996  Size term_index( 0 );
2997  for ( Size ii = 1; ii <= free_terms_.size(); ++ii ) {
2998  if ( free_terms_[ ii ] == term ) {
2999  term_index = ii;
3000  break;
3001  }
3002  }
3003 
3004  if ( term_index == 0 ) {
3005  std::cerr << "Error initializing constraints for term: " << term_name << " which does not appear in the free_terms_ list";
3006  continue;
3007  }
3008 
3009  if ( on_off == "OFF" ) {
3010  free_term_constraints_[ term_index ].active_ = false;
3011  } else if ( on_off == "ON" ) {
3012  infile >> min_val >> max_val >> spring_constant;
3013  free_term_constraints_[ term_index ].active_ = true;
3014  free_term_constraints_[ term_index ].min_weight_ = min_val;
3015  free_term_constraints_[ term_index ].max_weight_ = max_val;
3016  free_term_constraints_[ term_index ].spring_constant_ = spring_constant;
3017  } else {
3018  std::cerr << "ERROR: In weight constraint file, expected 'ON' or 'OFF' but read '" << on_off << "' instead." << std::endl;
3019  utility_exit();
3020  }
3021  }
3022 }
3023 
3024 Real
3026  optimization::Multivec const & component_weights,
3027  optimization::Multivec const & vars,
3028  optimization::Multivec & dE_dvars,
3029  /// Basically, turn over all the private data from OptEMultiFunc
3030  Size const num_energy_dofs,
3031  int const,
3032  int const,
3033  EnergyMap const &,
3034  ScoreTypes const &,
3035  ScoreTypes const &
3036 ) const
3037 {
3038  using namespace core::optimization;
3039  Real total( 0 );
3040  for ( Size ii = 1; ii <= num_energy_dofs; ++ii ) {
3041  if ( ! free_term_constraints_[ ii ].active_ ) continue;
3042 
3044 
3045  if ( vars[ ii ] > wrc.max_weight_ ) {
3046  total += ( vars[ ii ] - wrc.max_weight_ )*( vars[ ii ] - wrc.max_weight_ ) * wrc.spring_constant_;
3047  dE_dvars[ ii ] += 2 * component_weights[ constrained_optimization_weight_func ] *
3048  ( vars[ ii ] - wrc.max_weight_ ) * wrc.spring_constant_;
3049  } else if ( vars[ ii ] < wrc.min_weight_ ) {
3050  total += ( wrc.min_weight_ - vars[ ii ] )*( wrc.min_weight_ - vars[ ii ] ) * wrc.spring_constant_;
3051  dE_dvars[ ii ] += -2 * component_weights[ constrained_optimization_weight_func ] *
3052  ( wrc.min_weight_ - vars[ ii ] ) * wrc.spring_constant_;
3053  }
3054  }
3055  return component_weights[ constrained_optimization_weight_func ] * total;
3056 }
3057 
3058 void
3060  std::ostream & ostr,
3061  optimization::Multivec const & /*component_weights*/,
3062  optimization::Multivec const & vars,
3064  /// Basically, turn over all the private data from OptEMultiFunc
3065  Size const num_energy_dofs,
3066  int const,
3067  int const,
3068  EnergyMap const &,
3069  ScoreTypes const & score_list,
3070  ScoreTypes const &
3071 ) const
3072 {
3073  using namespace core::optimization;
3074  ostr << "CONSTR ";
3075  Real total( 0.0 );
3076  std::ostringstream sstr;
3077  for ( Size ii = 1; ii <= num_energy_dofs; ++ii ) {
3078 
3079  if ( ! free_term_constraints_[ ii ].active_ ) continue;
3080 
3082 
3083  if ( vars[ ii ] > wrc.max_weight_ ) {
3084  Real const pen( ( vars[ ii ] - wrc.max_weight_ )*( vars[ ii ] - wrc.max_weight_ ) * wrc.spring_constant_ );
3085  total += pen;
3086  sstr << score_list[ ii ] << ": " << vars[ ii ] << ", " << pen << "; ";
3087  } else if ( vars[ ii ] < wrc.min_weight_ ) {
3088  Real const pen( ( wrc.min_weight_ - vars[ ii ] )*( wrc.min_weight_ - vars[ ii ] ) * wrc.spring_constant_ );
3089  total += pen;
3090  sstr << score_list[ ii ] << " " << vars[ ii ] << ", " << pen << "; ";
3091  }
3092  }
3093  ostr << " total: " << total << " " << sstr.str() << "\n";
3094  return;
3095 }
3096 
3097 
3098 void
3100  ScoreTypes const & ,
3101  ScoreTypes const & ,
3102  EnergyMap & ,
3103  EnergyMap &
3104 ) const
3105 {
3106 }
3107 
3108 Size
3110  return 1;
3111 }
3112 
3113 
3114 
3117 {
3119 }
3120 
3121 
3122 void
3123 ConstraintedOptimizationWeightFunc::write_to_file( std::ofstream & /*outfile*/ ) const
3124 {}
3125 
3126 
3127 void
3129 {}
3130 
3131 
3132 void
3134 {}
3135 
3136 
3137 void
3139 {}
3140 
3141 
3142 Size
3144 {
3145  Size total = sizeof( ConstraintedOptimizationWeightFunc );
3146  return total;
3147 }
3148 
3149 
3150 #ifdef USEMPI
3151 
3152 void
3153 ConstraintedOptimizationWeightFunc::send_to_node( int const /*destination_node*/, int const /*tag*/ ) const
3154 {
3155  /// Stubbed out -- so far, ConstraintedOptimizationWeightFuncs are only used by node 0 and don't
3156  /// have to be passed around...
3157 
3158  utility_exit();
3159  //std::cout << "sending total_residue to node " << destination_node << std::endl;
3160  /// 1. max_weight_
3161  //double max_weight = max_weight_;
3162  //MPI_Send( & max_weight, 1, MPI_DOUBLE, destination_node, tag, MPI_COMM_WORLD );
3163 
3164  /// 2. min_weight_
3165  //double min_weight = min_weight_;
3166  //MPI_Send( & min_weight, 1, MPI_DOUBLE, destination_node, tag, MPI_COMM_WORLD );
3167 
3168  /// 3. spring_constant_
3169  //double spring_constant = spring_constant_;
3170  //MPI_Send( & spring_constant, 1, MPI_DOUBLE, destination_node, tag, MPI_COMM_WORLD );
3171 
3172  //OptEPositionData::send_to_node( destination_node, tag );
3173 
3174 }
3175 
3176 void
3177 ConstraintedOptimizationWeightFunc::receive_from_node( int const /*source_node*/, int const /*tag*/ )
3178 {
3179  utility_exit();
3180  //TR << "ConstraintedOptimizationWeightFunc::Recieving data from node... " << source_node << std::endl;
3181 
3182  //MPI_Status stat;
3183 
3184  /// 1. max_weight_
3185  //double max_weight;
3186  //MPI_Recv( & max_weight, 1, MPI_DOUBLE, source_node, tag, MPI_COMM_WORLD, &stat );
3187  //max_weight_ = max_weight;
3188 
3189  /// 2. min_weight_
3190  //double min_weight;
3191  //MPI_Recv( & min_weight, 1, MPI_DOUBLE, source_node, tag, MPI_COMM_WORLD, &stat );
3192  //min_weight_ = min_weight;
3193 
3194  /// 3. spring_constant_
3195  //double spring_constant;
3196  //MPI_Recv( & spring_constant, 1, MPI_DOUBLE, source_node, tag, MPI_COMM_WORLD, &stat );
3197  //spring_constant_ = spring_constant;
3198 
3199  //OptEPositionData::receive_from_node( source_node, tag );
3200 
3201 }
3202 #endif
3203 
3204 
3205 //
3206 // ------------------- DDGMutationOptEData-----------------------//
3207 //
3208 
3210 :
3211  experimental_ddG_( 0 ),
3212  wt_aa_( core::chemical::aa_ala ),
3213  mut_aa_( core::chemical::aa_ala )
3214 {}
3215 
3217 {}
3218 
3219 Real
3221  optimization::Multivec const & component_weights,
3222  optimization::Multivec const & vars,
3223  optimization::Multivec & dE_dvars,
3224  /// Basically, turn over all the private data from OptEMultiFunc
3225  Size const num_energy_dofs,
3226  int const num_ref_dofs,
3227  int const num_total_dofs,
3228  EnergyMap const & fixed_terms,
3229  ScoreTypes const & free_score_list,
3230  ScoreTypes const & fixed_score_list
3231 ) const
3232 {
3233  return process_score(
3234  TR, false, component_weights, vars,
3235  dE_dvars, num_energy_dofs, num_ref_dofs, num_total_dofs,
3236  fixed_terms, free_score_list, fixed_score_list );
3237 }
3238 
3239 
3240 /*
3241 Real
3242 DDGMutationOptEData::get_score(
3243  optimization::Multivec const & component_weights,
3244  optimization::Multivec const & vars,
3245  optimization::Multivec & dE_dvars,
3246  /// Basically, turn over all the private data from OptEMultiFunc
3247  Size const num_energy_dofs,
3248  int const num_ref_dofs,
3249  int const,
3250  EnergyMap const & fixed_terms,
3251  ScoreTypes const &,
3252  ScoreTypes const & fixed_score_list
3253 ) const
3254 {
3255  using namespace core::optimization;
3256  using namespace utility;
3257 
3258  // if there are no structures to go through, return immediately
3259  if ( muts_.size() == 0 || wts_.size() == 0 ) return 0.0;
3260 
3261  // these vectors are sized to the number of structures there are for a wt name and mutant name;
3262  // they'll be used to determine which structure has the best energy
3263  utility::vector1< Real > wt_energies( wts_.size(), 0.0 );
3264  utility::vector1< Real > mut_energies( muts_.size(), 0.0 );
3265 
3266  // go through and come up with a total score for each structure in the wts_ and muts_ list
3267  for ( Size ii = 1; ii <= num_energy_dofs; ++ii ) {
3268  for ( Size jj = 1; jj <= wts_.size(); ++jj ) {
3269  wt_energies[ jj ] += vars[ ii ] * wts_[ jj ]->free_data()[ ii ];
3270  }
3271  for ( Size jj = 1; jj <= muts_.size(); ++jj ) {
3272  mut_energies[ jj ] += vars[ ii ] * muts_[ jj ]->free_data()[ ii ];
3273  }
3274  }
3275  for ( Size ii = 1; ii <= fixed_score_list.size(); ++ii ) {
3276  for ( Size jj = 1; jj <= wts_.size(); ++jj ) {
3277  wt_energies[ jj ] += fixed_terms[ fixed_score_list[ ii ] ] * wts_[ jj ]->fixed_data()[ ii ];
3278  }
3279  for ( Size jj = 1; jj <= muts_.size(); ++jj ) {
3280  mut_energies[ jj ] += fixed_terms[ fixed_score_list[ ii ] ] * muts_[ jj ]->fixed_data()[ ii ];
3281  }
3282  }
3283 
3284  // I presume these are the reference energies that are being added in?
3285  // num_energy_dofs is the number of free, non-reference energy parameters in the run -ronj
3286  if ( num_ref_dofs != 0 ) {
3287  for ( Size jj = 1; jj <= wts_.size(); ++jj ) {
3288  wt_energies[ jj ] += vars[ num_energy_dofs + wt_aa_ ];
3289  }
3290  for ( Size jj = 1; jj <= muts_.size(); ++jj ) {
3291  mut_energies[ jj ] += vars[ num_energy_dofs + mut_aa_ ];
3292  }
3293  }
3294 
3295  // Identify which wt and mut structure in the lists have the best energy
3296  // arg_min returns the index of the smallest value in a vector
3297  Size const best_wt = arg_min( wt_energies );
3298  Size const best_mut = arg_min( mut_energies );
3299 
3300  Real const best_wt_energy = wt_energies[ best_wt ];
3301  Real const best_mut_energy = mut_energies[ best_mut ];
3302 
3303  Real const predicted_ddG = best_mut_energy - best_wt_energy;
3304  Real const ddG_diff = predicted_ddG - experimental_ddG_;
3305 
3306  for( Size e_dof(1); e_dof <= num_energy_dofs; ++e_dof ) {
3307  dE_dvars[ e_dof ] += 2 * component_weights[ ddG_mutation_correlation ] * ddG_diff * ( muts_[ best_mut ]->free_data()[ e_dof ] - wts_[ best_wt ]->free_data()[ e_dof ] );
3308  }
3309 
3310  if ( num_ref_dofs != 0 ) {
3311  dE_dvars[ num_energy_dofs + mut_aa_ ] += 2 * component_weights[ ddG_mutation_correlation ] * ddG_diff;
3312  dE_dvars[ num_energy_dofs + wt_aa_ ] -= 2 * component_weights[ ddG_mutation_correlation ] * ddG_diff;
3313  }
3314 
3315  //TR << "DDGMutationOptEData::get_score(): predicted: " << ObjexxFCL::fmt::F(4,2,predicted_ddG)
3316  // << ", experimental: " << experimental_ddG_ << ", ddG_diff^2: " << ObjexxFCL::fmt::F(6,3,ddG_diff * ddG_diff)
3317  // << ", tag: " << tag() << std::endl;
3318  return component_weights[ ddG_mutation_correlation ] * ddG_diff * ddG_diff;
3319 }*/
3320 
3321 void
3323  std::ostream & ostr,
3324  optimization::Multivec const & component_weights,
3325  optimization::Multivec const & vars,
3326  optimization::Multivec & dE_dvars,
3327  /// Basically, turn over all the private data from OptEMultiFunc
3328  Size const num_energy_dofs,
3329  int const num_ref_dofs,
3330  int const num_total_dofs,
3331  EnergyMap const & fixed_terms,
3332  ScoreTypes const & free_score_list,
3333  ScoreTypes const & fixed_score_list
3334 ) const
3335 {
3336  process_score(
3337  ostr, true, component_weights, vars,
3338  dE_dvars, num_energy_dofs, num_ref_dofs, num_total_dofs,
3339  fixed_terms, free_score_list, fixed_score_list );
3340 }
3341 
3342 Real
3344  std::ostream & ostr,
3345  bool print,
3346  optimization::Multivec const & component_weights,
3347  optimization::Multivec const & vars,
3348  optimization::Multivec & dE_dvars,
3349  /// Basically, turn over all the private data from OptEMultiFunc
3350  Size const num_energy_dofs,
3351  int const num_ref_dofs,
3352  int const,
3353  EnergyMap const & fixed_terms,
3354  ScoreTypes const & score_list,
3355  ScoreTypes const & fixed_score_list
3356 ) const
3357 {
3358  using namespace core::optimization;
3359  using namespace basic::options;
3360  using namespace basic::options::OptionKeys;
3361  using namespace utility;
3362 
3363  // if there are no structures to go through, return immediately
3364  if ( muts_.size() == 0 || wts_.size() == 0 ) return 0.0;
3365 
3366  // these vectors are sized to the number of structures there are for a wt name and mutant name;
3367  // they'll be used to determine which structure has the best energy
3368  utility::vector1< Real > wt_energies( wts_.size(), 0.0 );
3369  utility::vector1< Real > mut_energies( muts_.size(), 0.0 );
3370 
3371  utility::vector1< utility::vector1< Real > > wt_dG_energies( 20, utility::vector1 < Real > ( num_energy_dofs + fixed_score_list.size(), 0.0 ) );
3372  utility::vector1< utility::vector1< Real > > mut_dG_energies( 20, utility::vector1 < Real > ( num_energy_dofs + fixed_score_list.size(), 0.0 ) );
3373 
3374  #define CAP_FA_REP 1
3375 
3376  // go through and come up with a total score for each structure in the wts_ and muts_ list
3377  for ( Size ii = 1; ii <= num_energy_dofs; ++ii ) {
3378  for ( Size jj = 1; jj <= wts_.size(); ++jj ) {
3379 
3380  // cap the fa_rep term at some value - this at least keeps it around for most of the mutants
3381  #ifdef CAP_FA_REP
3382  if ( ( score_list[ ii ] == fa_rep ) && ( vars[ ii ] * wts_[ jj ]->free_data()[ ii ] > 10 ) ) { wt_energies[ jj ] += 10; }
3383  else
3384  #endif
3385  wt_energies[ jj ] += vars[ ii ] * wts_[ jj ]->free_data()[ ii ];
3386 
3387  wt_dG_energies[ jj ][ ii ] = vars[ ii ] * wts_[ jj ]->free_data()[ ii ];
3388  }
3389  for ( Size jj = 1; jj <= muts_.size(); ++jj ) {
3390  // cap the fa_rep term at some value - this at least keeps it around for most of the mutants
3391  #ifdef CAP_FA_REP
3392  if ( ( score_list[ ii ] == fa_rep ) && ( vars[ ii ] * muts_[ jj ]->free_data()[ ii ] > 10 ) ) { mut_energies[ jj ] += 10; }
3393  else
3394  #endif
3395  mut_energies[ jj ] += vars[ ii ] * muts_[ jj ]->free_data()[ ii ];
3396 
3397  mut_dG_energies[ jj ][ ii ] = vars[ ii ] * muts_[ jj ]->free_data()[ ii ];
3398  }
3399  }
3400  for ( Size ii = 1; ii <= fixed_score_list.size(); ++ii ) {
3401  for ( Size jj = 1; jj <= wts_.size(); ++jj ) {
3402  #ifdef CAP_FA_REP
3403  if ( ( fixed_score_list[ ii ] == fa_rep ) && ( fixed_terms[ fixed_score_list[ ii ] ] * wts_[ jj ]->fixed_data()[ ii ] > 10 ) ) { wt_energies[ jj ] += 10; }
3404  else
3405  #endif
3406  wt_energies[ jj ] += fixed_terms[ fixed_score_list[ ii ] ] * wts_[ jj ]->fixed_data()[ ii ];
3407 
3408  wt_dG_energies[ jj ][ num_energy_dofs + ii ] = fixed_terms[ fixed_score_list[ ii ] ] * wts_[ jj ]->fixed_data()[ ii ];
3409  }
3410  for ( Size jj = 1; jj <= muts_.size(); ++jj ) {
3411  #ifdef CAP_FA_REP
3412  if ( ( fixed_score_list[ ii ] == fa_rep ) && ( fixed_terms[ fixed_score_list[ ii ] ] * muts_[ jj ]->fixed_data()[ ii ] > 10 ) ) { mut_energies[ jj ] += 10; }
3413  else
3414  #endif
3415  mut_energies[ jj ] += fixed_terms[ fixed_score_list[ ii ] ] * muts_[ jj ]->fixed_data()[ ii ];
3416 
3417  mut_dG_energies[ jj ][ num_energy_dofs + ii ] = fixed_terms[ fixed_score_list[ ii ] ] * muts_[ jj ]->fixed_data()[ ii ];
3418  }
3419  }
3420 
3421  // I presume these are the reference energies that are being added in?
3422  // num_energy_dofs is the number of free, non-reference energy parameters in the run -ronj
3423  if ( num_ref_dofs != 0 ) {
3424  for ( Size jj = 1; jj <= wts_.size(); ++jj ) {
3425  wt_energies[ jj ] += vars[ num_energy_dofs + wt_aa_ ];
3426  }
3427  for ( Size jj = 1; jj <= muts_.size(); ++jj ) {
3428  mut_energies[ jj ] += vars[ num_energy_dofs + mut_aa_ ];
3429  }
3430  }
3431 
3432  //if ( print ) {
3433  // for ( Size jj = 1; jj <= wts_.size(); ++jj ) {
3434  // ostr << "EXTRA " << tag() << " structure " << jj << " ddG by term: [ ";
3435  // for ( Size ii = 1; ii <= num_energy_dofs; ++ii )
3436  // ostr << name_from_score_type( score_list[ ii ] ) << ": " << ( mut_dG_energies[ jj ][ ii ] - wt_dG_energies[ jj ][ ii ] ) << ", ";
3437  // for ( Size ii = 1; ii <= fixed_score_list.size(); ++ii )
3438  // ostr << name_from_score_type( fixed_score_list[ ii ] ) << ": " << ( mut_dG_energies[ jj ][ num_energy_dofs + ii ] - wt_dG_energies[ jj ][ num_energy_dofs + ii ] ) << ", ";
3439  // ostr << "]" << std::endl;
3440  // }
3441  //}
3442 
3443 
3444  Real predicted_ddG( 0.0 );
3445  Real ddG_diff( 0.0 );
3446 
3447  // This is where we branch on how the score is calculated. The simplest approach is to take the minimum energy
3448  // of all the wts and all the muts and subtract them to get the ddG. The mean-based approach use the difference
3449  // of the average of all muts and average of all wts. Finally, the boltzmann approach calculates a boltzmann
3450  // probability for the wts and muts to get a score.
3451  if ( option[ optE::optimize_ddGmutation_straight_mean ] ) {
3452 
3453  Real const wt_avg_energy = numeric::statistics::mean( wt_energies.begin(), wt_energies.end(), Real( 0.0 ) );
3454  Real const mut_avg_energy= numeric::statistics::mean( mut_energies.begin(), mut_energies.end(), Real( 0.0 ) );
3455 
3456  predicted_ddG = mut_avg_energy - wt_avg_energy;
3457  ddG_diff = predicted_ddG - experimental_ddG_;
3458 
3459  if ( print ) {
3460  ostr << "DDGMutationOptEData pred: " << predicted_ddG << " exp: " << experimental_ddG_;
3461  ostr << " err: " << ddG_diff * ddG_diff << " cmptwt_err: ";
3462  ostr << component_weights[ ddG_mutation_correlation ] * ddG_diff * ddG_diff;
3463  ostr << " " << tag() << "\n";
3464  } else {
3465  Real const inv_nmuts = 1.0 / muts_.size();
3466  Real const inv_nwts = 1.0 / wts_.size();
3467  for( Size e_dof(1); e_dof <= num_energy_dofs; ++e_dof ) {
3468  for ( Size jj = 1; jj <= muts_.size(); ++jj ) {
3469  dE_dvars[ e_dof ] += inv_nmuts * 2 * component_weights[ ddG_mutation_correlation ] * ddG_diff * muts_[ jj ]->free_data()[ e_dof ];
3470  }
3471  for ( Size jj = 1; jj <= wts_.size(); ++jj ) {
3472  dE_dvars[ e_dof ] += -1 * inv_nwts * 2 * component_weights[ ddG_mutation_correlation ] * ddG_diff * wts_[ jj ]->free_data()[ e_dof ];
3473  }
3474  }
3475 
3476  if ( num_ref_dofs != 0 ) {
3477  dE_dvars[ num_energy_dofs + mut_aa_ ] += 2 * component_weights[ ddG_mutation_correlation ] * ddG_diff;
3478  dE_dvars[ num_energy_dofs + wt_aa_ ] -= 2 * component_weights[ ddG_mutation_correlation ] * ddG_diff;
3479  }
3480  }
3481 
3482  } else if ( option[ optE::optimize_ddGmutation_boltzman_average ] ) {
3483 
3484  static Real const inv_kT( option[ optE::inv_kT_nataa ] ); // temp hack
3485 
3486  /// First normalize the energies of both the mutants and the wild type structures.
3487  Real best_wt = utility::min( wt_energies );
3488  Real best_mut = utility::min( mut_energies );
3489  Real best_of_best = std::min( best_wt, best_mut );
3490  for ( Size ii = 1; ii <= wt_energies.size(); ++ii ) wt_energies[ ii ] -= best_of_best;
3491  for ( Size ii = 1; ii <= mut_energies.size(); ++ii ) mut_energies[ ii ] -= best_of_best;
3492 
3493  /// Now compute the boltzman probabilities of each of the structures.
3494 
3495  Real wt_denom(0.0);
3496  Real mut_denom(0.0);
3497  utility::vector1< Real > wt_partition( wts_.size(), 0.0 );
3498  utility::vector1< Real > mut_partition( muts_.size(), 0.0 );
3499  for ( Size ii = 1; ii <= wt_partition.size(); ++ii ) wt_denom += wt_partition[ ii ] = std::exp( -1 * wt_energies[ ii ] * inv_kT );
3500  for ( Size ii = 1; ii <= mut_partition.size(); ++ii ) mut_denom += mut_partition[ ii ] = std::exp( -1 * mut_energies[ ii ] * inv_kT );
3501 
3502  Real wt_avg_energy( 0.0 ), mut_avg_energy( 0.0 );
3503  for ( Size ii = 1; ii <= wt_partition.size(); ++ii ) wt_avg_energy += wt_partition[ ii ] * wt_energies[ ii ];
3504  for ( Size ii = 1; ii <= mut_partition.size(); ++ii ) mut_avg_energy += mut_partition[ ii ] * mut_energies[ ii ];
3505  wt_avg_energy /= wt_denom;
3506  mut_avg_energy /= mut_denom;
3507 
3508  predicted_ddG = mut_avg_energy - wt_avg_energy;
3509  ddG_diff = predicted_ddG - experimental_ddG_;
3510 
3511  if ( print ) {
3512  ostr << "DDGMutationOptEData pred: " << predicted_ddG << " exp: " << experimental_ddG_;
3513  ostr << " err: " << ddG_diff * ddG_diff << " cmptwt_err: ";
3514  ostr << component_weights[ ddG_mutation_correlation ] * ddG_diff * ddG_diff;
3515  ostr << " " << tag() << "\n";
3516  } else {
3517 
3518  for( Size e_dof(1); e_dof <= num_energy_dofs; ++e_dof ) {
3519  /// quotient rule: d/dx f/g == (f'g - g'f)/(g*g).
3520  Real fmut(0.0), fprimemut(0.0), gmut( mut_denom ), gprimemut(0.0);
3521  for ( Size jj = 1; jj <= muts_.size(); ++jj ) {
3522  fmut += mut_partition[ jj ] * mut_energies[ jj ];
3523  fprimemut += -1 * muts_[ jj ]->free_data()[ e_dof ] * inv_kT * mut_partition[ jj ] + muts_[ jj ]->free_data()[ e_dof ] * mut_partition[ jj ];
3524  gprimemut += -1 * muts_[ jj ]->free_data()[ e_dof ] * inv_kT * mut_partition[ jj ];
3525  }
3526  dE_dvars[ e_dof ] += 2 * component_weights[ ddG_mutation_correlation ] * ddG_diff * ( fprimemut * gmut - gprimemut * fmut ) / (gmut*gmut);
3527 
3528  Real fwt(0.0), fprimewt(0.0), gwt( wt_denom ), gprimewt(0.0);
3529  for ( Size jj = 1; jj <= wts_.size(); ++jj ) {
3530  fwt += wt_partition[ jj ] * wt_energies[ jj ];
3531  fprimewt += -1 * wts_[ jj ]->free_data()[ e_dof ] * inv_kT * wt_partition[ jj ] + wts_[ jj ]->free_data()[ e_dof ] * wt_partition[ jj ];
3532  gprimewt += -1 * wts_[ jj ]->free_data()[ e_dof ] * inv_kT * wt_partition[ jj ];
3533  }
3534  dE_dvars[ e_dof ] -= 2 * component_weights[ ddG_mutation_correlation ] * ddG_diff * ( fprimewt * gwt - gprimewt * fwt ) / (gwt*gwt);
3535  }
3536 
3537  if ( num_ref_dofs != 0 ) {
3538  dE_dvars[ num_energy_dofs + mut_aa_ ] += 2 * component_weights[ ddG_mutation_correlation ] * ddG_diff;
3539  dE_dvars[ num_energy_dofs + wt_aa_ ] -= 2 * component_weights[ ddG_mutation_correlation ] * ddG_diff;
3540  }
3541  }
3542 
3543 
3544  } else {
3545  Size const best_wt = arg_min( wt_energies );
3546  Size const best_mut = arg_min( mut_energies );
3547 
3548  Real const best_wt_energy = wt_energies[ best_wt ];
3549  Real const best_mut_energy = mut_energies[ best_mut ];
3550 
3551  predicted_ddG = best_mut_energy - best_wt_energy;
3552  ddG_diff = predicted_ddG - experimental_ddG_;
3553 
3554  if ( print ) {
3555 
3556  ostr << "DDGMutationOptEData pred: " << predicted_ddG << " exp: " << experimental_ddG_;
3557  ostr << " err: " << ddG_diff * ddG_diff << " cmptwt_err: ";
3558  ostr << component_weights[ ddG_mutation_correlation ] * ddG_diff * ddG_diff;
3559  ostr << " " << tag() << "\n";
3560 
3561  } else {
3562 
3563  for( Size e_dof(1); e_dof <= num_energy_dofs; ++e_dof ) {
3564  if ( ( score_list[ e_dof ] == fa_rep ) && ( muts_[ best_mut ]->free_data()[ e_dof ] - wts_[ best_wt ]->free_data()[ e_dof ] ) > 10 )
3565  dE_dvars[ e_dof ] += 2 * component_weights[ ddG_mutation_correlation ] * ddG_diff * 10;
3566  else
3567  dE_dvars[ e_dof ] += 2 * component_weights[ ddG_mutation_correlation ] * ddG_diff * ( muts_[ best_mut ]->free_data()[ e_dof ] - wts_[ best_wt ]->free_data()[ e_dof ] );
3568  }
3569 
3570  if ( num_ref_dofs != 0 ) {
3571  dE_dvars[ num_energy_dofs + mut_aa_ ] += 2 * component_weights[ ddG_mutation_correlation ] * ddG_diff;
3572  dE_dvars[ num_energy_dofs + wt_aa_ ] -= 2 * component_weights[ ddG_mutation_correlation ] * ddG_diff;
3573  }
3574 
3575  }
3576 
3577  }
3578 
3579  return component_weights[ ddG_mutation_correlation ] * ddG_diff * ddG_diff;
3580 }
3581 
3582 
3583 /*
3584 void
3585 DDGMutationOptEData::print_score(
3586  std::ostream & ostr,
3587  optimization::Multivec const & component_weights,
3588  optimization::Multivec const & vars,
3589  optimization::Multivec &,
3590  /// Basically, turn over all the private data from OptEMultiFunc
3591  Size const num_energy_dofs,
3592  int const num_ref_dofs,
3593  int const,
3594  EnergyMap const & fixed_terms,
3595  ScoreTypes const &,
3596  ScoreTypes const & fixed_score_list
3597 ) const
3598 {
3599  using namespace core::optimization;
3600  using namespace utility;
3601 
3602  if ( muts_.size() == 0 || wts_.size() == 0 ) return;
3603 
3604  utility::vector1< Real > wt_energies( wts_.size(), 0.0 );
3605  utility::vector1< Real > mut_energies( muts_.size(), 0.0 );
3606  for ( Size ii = 1; ii <= num_energy_dofs; ++ii ) {
3607  for ( Size jj = 1; jj <= wts_.size(); ++jj ) {
3608  wt_energies[ jj ] += vars[ ii ] * wts_[ jj ]->free_data()[ ii ];
3609  }
3610  for ( Size jj = 1; jj <= muts_.size(); ++jj ) {
3611  mut_energies[ jj ] += vars[ ii ] * muts_[ jj ]->free_data()[ ii ];
3612  }
3613  }
3614  for ( Size ii = 1; ii <= fixed_score_list.size(); ++ii ) {
3615  for ( Size jj = 1; jj <= wts_.size(); ++jj ) {
3616  wt_energies[ jj ] += fixed_terms[ fixed_score_list[ ii ] ] * wts_[ jj ]->fixed_data()[ ii ];
3617  }
3618  for ( Size jj = 1; jj <= muts_.size(); ++jj ) {
3619  mut_energies[ jj ] += fixed_terms[ fixed_score_list[ ii ] ] * muts_[ jj ]->fixed_data()[ ii ];
3620  }
3621  }
3622 
3623  if ( num_ref_dofs != 0 ) {
3624  for ( Size jj = 1; jj <= wts_.size(); ++jj ) {
3625  wt_energies[ jj ] += vars[ num_energy_dofs + wt_aa_ ];
3626  }
3627  for ( Size jj = 1; jj <= muts_.size(); ++jj ) {
3628  mut_energies[ jj ] += vars[ num_energy_dofs + mut_aa_ ];
3629  }
3630  }
3631 
3632  Size const best_wt = arg_min( wt_energies );
3633  Size const best_mut = arg_min( mut_energies );
3634 
3635  Real const best_wt_energy = wt_energies[ best_wt ];
3636  Real const best_mut_energy = mut_energies[ best_mut ];
3637 
3638  Real const predicted_ddG = best_mut_energy - best_wt_energy;
3639  Real const ddG_diff = predicted_ddG - experimental_ddG_;
3640 
3641  TR << "DDGMutationOptEData::print_score(): predicted: " << predicted_ddG << ", experimental: " << experimental_ddG_
3642  << ", ddG_diff^2: " << ddG_diff * ddG_diff << ", tag: " << tag() << std::endl;
3643 
3644  ostr << "DDGMutationOptEData pred: " << predicted_ddG << " exp: " << experimental_ddG_;
3645  ostr << " err: " << ddG_diff * ddG_diff << " cmptwt_err: ";
3646  ostr << component_weights[ ddG_mutation_correlation ] * ddG_diff * ddG_diff;
3647  ostr << " " << tag() << "\n";
3648 
3649  //ostr << "DDGMutRaw: " << best_wt << " " << best_wt_energy << " " << best_mut << " " << best_mut_energy << " : ";
3650  //for ( Size ii = 1; ii <= wts_[ best_wt ]->free_data().size(); ++ii ) {
3651  // ostr << " ( " << wts_[ best_wt ]->free_data()[ ii ] << " , " << muts_[ best_mut ]->free_data()[ ii ] << " ) ";
3652  //}
3653  //ostr << "\n";
3654 
3655  return;
3656 }*/
3657 
3658 void
3660  ScoreTypes const & free_score_list,
3661  ScoreTypes const & fixed_score_list,
3662  EnergyMap & lower_bound,
3663  EnergyMap & upper_bound
3664 ) const
3665 {
3666  for ( Size jj = 1; jj <= wts_.size(); ++jj ) {
3667  update_range( wts_[ jj ], free_score_list, fixed_score_list, lower_bound, upper_bound );
3668  }
3669  for ( Size jj = 1; jj <= muts_.size(); ++jj ) {
3670  update_range( muts_[ jj ], free_score_list, fixed_score_list, lower_bound, upper_bound );
3671  }
3672 }
3673 
3674 Size
3676 {
3677  return wts_.size() + muts_.size();
3678 }
3679 
3680 
3683 {
3684  return ddG_mutation_correlation;
3685 }
3686 
3687 
3688 void
3689 DDGMutationOptEData::write_to_file( std::ofstream & /*outfile*/ ) const
3690 {}
3691 
3692 
3693 void
3694 DDGMutationOptEData::read_from_file( std::ifstream & /*infile*/ )
3695 {}
3696 
3697 
3698 void
3699 DDGMutationOptEData::write_to_binary_file( std::ofstream & /*outfile*/ ) const
3700 {}
3701 
3702 
3703 void
3704 DDGMutationOptEData::read_from_binary_file( std::ifstream & /*infile*/ )
3705 {}
3706 
3707 
3708 Size
3710 {
3711  Size total = sizeof( DDGMutationOptEData ) +
3712  sizeof( SingleStructureData ) * wts_.size() +
3713  sizeof( SingleStructureData ) * muts_.size();
3714  if ( wts_.size() > 0 ) {
3715  total += sizeof( Real ) * ( wts_[ 1 ]->free_data().size() + wts_[ 1 ]->fixed_data().size() ) * wts_.size();
3716  }
3717  if ( muts_.size() > 0 ) {
3718  total += sizeof( Real ) * ( muts_[ 1 ]->free_data().size() + muts_[ 1 ]->fixed_data().size() ) * muts_.size();
3719  }
3720  return total;
3721 }
3722 
3723 
3724 #ifdef USEMPI
3725 
3726 void
3727 DDGMutationOptEData::send_to_node( int const destination_node, int const tag ) const
3728 {
3729  /// 1. Experimental DDG, wt_aa, mut_aa
3730  int wt_aa( wt_aa_ ), mut_aa( mut_aa_ );
3731  Real experimental_ddG = experimental_ddG_; // stupid const pointer
3732  MPI_Send( & experimental_ddG, 1, MPI_DOUBLE, destination_node, tag, MPI_COMM_WORLD );
3733  MPI_Send( & wt_aa, 1, MPI_INT, destination_node, tag, MPI_COMM_WORLD );
3734  MPI_Send( & mut_aa, 1, MPI_INT, destination_node, tag, MPI_COMM_WORLD );
3735 
3736  // 2a. n natives
3737  //std::cout << "sending nwts to node " << destination_node << std::endl;
3738  Size nwts = wts_.size();
3739  MPI_Send( & nwts, 1, MPI_UNSIGNED_LONG, destination_node, tag, MPI_COMM_WORLD );
3740 
3741  /// 2b. n decoys
3742  //std::cout << "sending nmuts to node " << destination_node << std::endl;
3743  Size nmuts = muts_.size();
3744  MPI_Send( & nmuts, 1, MPI_UNSIGNED_LONG, destination_node, tag, MPI_COMM_WORLD );
3745 
3746  if ( nwts == 0 || nmuts == 0 ) return;
3747 
3748  /// 3. n free
3749  Size n_free = muts_[ 1 ]->free_data().size();
3750  //std::cout << "sending n_free to node " << destination_node << " " << n_free << std::endl;
3751  MPI_Send( & n_free, 1, MPI_UNSIGNED_LONG, destination_node, tag, MPI_COMM_WORLD );
3752 
3753  /// 4. n fixed
3754  Size n_fixed = muts_[ 1 ]->fixed_data().size();
3755  //std::cout << "sending n_fixed to node " << destination_node << " " << n_fixed << std::endl;
3756  MPI_Send( & n_fixed, 1, MPI_UNSIGNED_LONG, destination_node, tag, MPI_COMM_WORLD );
3757 
3758  /// Send natives, then send decoys
3759  Real * free_data = new Real[ n_free * nwts ];
3760  Real * fixed_data = new Real[ n_fixed * nwts ];
3761  for ( Size ii = 1; ii <= nwts; ++ ii ) {
3762  for ( Size jj = 1; jj <= n_free; ++jj ) {
3763  free_data[ ( ii - 1 ) * n_free + ( jj - 1 ) ] = wts_[ ii ]->free_data()[ jj ];
3764  }
3765  for ( Size jj = 1; jj <= n_fixed; ++jj ) {
3766  fixed_data[ ( ii - 1 ) * n_fixed + ( jj - 1 ) ] = wts_[ ii ]->fixed_data()[ jj ];
3767  }
3768  }
3769 
3770  //std::cout << "sending native free_data to node " << destination_node << " " << free_data << std::endl;
3771  /// 5. native free data
3772  MPI_Send( free_data, nwts * n_free, MPI_DOUBLE, destination_node, tag, MPI_COMM_WORLD );
3773 
3774  //std::cout << "sending native fixed_data to node " << destination_node << " " << fixed_data << std::endl;
3775  /// 6. fixed data
3776  MPI_Send( fixed_data, nwts * n_fixed, MPI_DOUBLE, destination_node, tag, MPI_COMM_WORLD );
3777 
3778  //std::cout << "Sent -- about to delete data" << std::endl;
3779 
3780  /// now send decoys
3781  Real * decoy_free_data = new Real[ n_free * nmuts ];
3782  Real * decoy_fixed_data = new Real[ n_fixed * nmuts ];
3783  for ( Size ii = 1; ii <= nmuts; ++ ii ) {
3784  for ( Size jj = 1; jj <= n_free; ++jj ) {
3785  decoy_free_data[ ( ii - 1 ) * n_free + ( jj - 1 ) ] = muts_[ ii ]->free_data()[ jj ];
3786  }
3787  for ( Size jj = 1; jj <= n_fixed; ++jj ) {
3788  decoy_fixed_data[ ( ii - 1 ) * n_fixed + ( jj - 1 ) ] = muts_[ ii ]->fixed_data()[ jj ];
3789  }
3790  }
3791  /// 7. decoy free data
3792  //std::cout << "sending decoy free_data to node " << destination_node << std::endl;
3793  MPI_Send( decoy_free_data, nmuts * n_free, MPI_DOUBLE, destination_node, tag, MPI_COMM_WORLD );
3794 
3795  /// 8. decoy fixed data
3796  //std::cout << "sending decoy fixed_data to node " << destination_node << std::endl;
3797  MPI_Send( decoy_fixed_data, nmuts * n_fixed, MPI_DOUBLE, destination_node, tag, MPI_COMM_WORLD );
3798 
3799  delete [] free_data;
3800  delete [] fixed_data;
3801 
3802  delete [] decoy_free_data;
3803  delete [] decoy_fixed_data;
3804 
3805  OptEPositionData::send_to_node( destination_node, tag );
3806 
3807 }
3808 
3809 void
3810 DDGMutationOptEData::receive_from_node( int const source_node, int const tag )
3811 {
3812  MPI_Status stat;
3813  //TR << "PNatStructureOptEData::Recieving data from node... " << source_node << std::endl;
3814 
3815  /// 1. Experimental DDG, wt_aa, mut_aa
3816  int wt_aa( 0 ), mut_aa(0);
3817  MPI_Recv( & experimental_ddG_, 1, MPI_DOUBLE, source_node, tag, MPI_COMM_WORLD, &stat );
3818  MPI_Recv( & wt_aa, 1, MPI_INT, source_node, tag, MPI_COMM_WORLD, &stat );
3819  MPI_Recv( & mut_aa, 1, MPI_INT, source_node, tag, MPI_COMM_WORLD, &stat );
3820  wt_aa_ = static_cast< AA > ( wt_aa );
3821  mut_aa_ = static_cast< AA > ( mut_aa );
3822 
3823  /// 2a. n wts
3824  Size nwts( 0 );
3825  MPI_Recv( & nwts, 1, MPI_UNSIGNED_LONG, source_node, tag, MPI_COMM_WORLD, &stat );
3826 
3827  /// 2b. n decoys
3828  Size nmuts( 0 );
3829  MPI_Recv( & nmuts, 1, MPI_UNSIGNED_LONG, source_node, tag, MPI_COMM_WORLD, &stat );
3830 
3831  if ( nwts == 0 || nmuts == 0 ) return;
3832  wts_.reserve( nwts );
3833  muts_.reserve( nmuts );
3834 
3835  /// 3. n free
3836  Size n_free( 0 );
3837  MPI_Recv( & n_free, 1, MPI_UNSIGNED_LONG, source_node, tag, MPI_COMM_WORLD, &stat );
3838 
3839  /// 4. n fixed
3840  Size n_fixed( 0 );
3841  MPI_Recv( & n_fixed, 1, MPI_UNSIGNED_LONG, source_node, tag, MPI_COMM_WORLD, &stat );
3842 
3843  /// Recieve native data first, then decoys
3844  Real * free_data = new Real[ n_free * nwts ];
3845  Real * fixed_data = new Real[ n_fixed * nwts ];
3846 
3847  /// 5. free data
3848  MPI_Recv( free_data, nwts * n_free, MPI_DOUBLE, source_node, tag, MPI_COMM_WORLD, &stat );
3849 
3850  /// 6. fixed data
3851  MPI_Recv( fixed_data, nwts * n_fixed, MPI_DOUBLE, source_node, tag, MPI_COMM_WORLD, &stat );
3852 
3853  utility::vector1< Real > free_data_v( n_free );
3854  utility::vector1< Real > fixed_data_v( n_fixed );
3855  for ( Size ii = 1; ii <= nwts; ++ ii ) {
3856  for ( Size jj = 1; jj <= n_free; ++jj ) {
3857  free_data_v[ jj ] = free_data[ ( ii - 1 ) * n_free + ( jj - 1 ) ];
3858  }
3859  for ( Size jj = 1; jj <= n_fixed; ++jj ) {
3860  fixed_data_v[ jj ] = fixed_data[ ( ii - 1 ) * n_fixed + ( jj - 1 ) ];
3861  }
3862  wts_.push_back( new SingleStructureData( free_data_v, fixed_data_v ) );
3863  }
3864 
3865 
3866  delete [] free_data; free_data = 0;
3867  delete [] fixed_data; fixed_data = 0;
3868 
3869  //// Now receive decoy data
3870  free_data = new Real[ n_free * nmuts ];
3871  fixed_data = new Real[ n_fixed * nmuts ];
3872 
3873  /// 5. free data
3874  MPI_Recv( free_data, nmuts * n_free, MPI_DOUBLE, source_node, tag, MPI_COMM_WORLD, &stat );
3875 
3876  /// 6. fixed data
3877  MPI_Recv( fixed_data, nmuts * n_fixed, MPI_DOUBLE, source_node, tag, MPI_COMM_WORLD, &stat );
3878 
3879  for ( Size ii = 1; ii <= nmuts; ++ ii ) {
3880  for ( Size jj = 1; jj <= n_free; ++jj ) {
3881  free_data_v[ jj ] = free_data[ ( ii - 1 ) * n_free + ( jj - 1 ) ];
3882  }
3883  for ( Size jj = 1; jj <= n_fixed; ++jj ) {
3884  fixed_data_v[ jj ] = fixed_data[ ( ii - 1 ) * n_fixed + ( jj - 1 ) ];
3885  }
3886  muts_.push_back( new SingleStructureData( free_data_v, fixed_data_v ) );
3887  }
3888 
3889 
3890  delete [] free_data;
3891  delete [] fixed_data;
3892 
3893  OptEPositionData::receive_from_node( source_node, tag );
3894 
3895 }
3896 #endif
3897 
3898 
3899 void
3901 {
3902  wt_aa_ = wt_aa;
3903 }
3904 
3905 void
3907 {
3908  mut_aa_ = mut_aa;
3909 }
3910 
3911 void
3913 {
3914  experimental_ddG_ = ddg;
3915 }
3916 
3917 
3918 void
3920 {
3921  wts_.push_back( wt );
3922 }
3923 
3924 void
3926 {
3927  muts_.push_back( mut );
3928 }
3929 
3930 
3931 //
3932 // ------------------- OptEData-----------------------//
3933 //
3934 
3935 core::Size
3937 {
3938  core::Size num_rots(0);
3939  for ( OptEPositionDataOPs::const_iterator pos( data_.begin() );
3940  pos != data_.end(); ++pos ) {
3941  num_rots += (*pos)->size();
3942  }
3943  return num_rots;
3944 }
3945 
3946 
3947 ///@begin OptEData::read_from_file
3948 ///@brief slow
3949 ///@author ashworth
3950 void
3952 {
3953  runtime_assert( data_.empty() );
3954  data_.clear();
3955  ScoreTypes fixed_terms, free_terms;
3956  std::ifstream infile( filename.c_str() );
3957  std::string line;
3958 
3960  using utility::string_split;
3961 
3962  // first read the header to get the get list of fixed and free terms
3963  while( getline( infile, line ) ) {
3964  Strings words( string_split( line, ' ' ) );
3965  if ( line.substr(0,12) == "fixed terms:" ) {
3966  for ( Strings::iterator term( words.begin()+2 ); term != words.end(); ++term ) {
3967  fixed_terms.push_back( score_type_from_name( *term ) );
3968  }
3969  } else if ( line.substr(0,11) == "free terms:" ) {
3970  for ( Strings::iterator term( words.begin()+2 ); term != words.end(); ++term ) {
3971  free_terms.push_back( score_type_from_name( *term ) );
3972  }
3973  break; // (free terms expected to come after fixed terms)
3974  }
3975  }
3976  // assign fixed and free terms
3977  runtime_assert( !free_terms.empty() );
3978  runtime_assert( ( fixed_terms == fixed_energy_terms_ ) || fixed_energy_terms_.empty() );
3979  runtime_assert( ( free_terms == energy_terms_ ) || energy_terms_.empty() );
3980  fixed_energy_terms_ = fixed_terms;
3981  energy_terms_ = free_terms;
3982 
3983  while ( getline( infile, line ) ) {
3984  Strings words( string_split( line, ' ' ) );
3985 
3986  if ( words.size() == 0 ) { utility_exit_with_message("Bad line from optE data file"); }
3987  if ( words[ 1 ] != "optE_position_data_type" ) { utility_exit_with_message("Bad line from optE data file"); }
3988 
3989  OptEPositionDataType postype = (OptEPositionDataType) utility::from_string( words[2], int( 0 ) /* dummy */ );
3991  new_position_data->read_from_file( infile );
3992  add_position_data( new_position_data );
3993  }
3994 
3995  infile.close();
3996  TR << "Read in " << num_rotamers() << " rotamers at "
3997  << num_positions() << " positions from file " << filename << std::endl;
3998 }
3999 
4000 ///@begin OptEData::write_to_file
4001 ///@brief human-readable
4002 ///@author ashworth
4003 void
4005 {
4006  std::ofstream outfile( filename.c_str() );
4007  // write explanatory header
4008  outfile << "# data line format:" << std::endl << "# rot_number, this_aa,"
4009  << " [ energies for fixed terms ], [ energies for free terms ]"
4010  << "\n";
4011 
4012  outfile << "fixed terms:";
4013  for ( ScoreTypes::const_iterator et( fixed_energy_terms_.begin() );
4014  et != fixed_energy_terms_.end(); ++et ) {
4015  outfile << " " << name_from_score_type( *et );
4016  }
4017  outfile << "\n";
4018 
4019  outfile << "free terms:";
4020  for ( ScoreTypes::const_iterator et( energy_terms_.begin() );
4021  et != energy_terms_.end(); ++et ) {
4022  outfile << " " << name_from_score_type( *et );
4023  }
4024  outfile << "\n";
4025 
4026  // write data
4027  for ( OptEPositionDataOPs::const_iterator pos( position_data_begin() );
4028  pos != position_data_end(); ++pos ) {
4029  outfile << "optE_position_data_type " << (*pos)->type() << "\n";
4030  (*pos)->write_to_file( outfile );
4031  }
4032  outfile.close();
4033  TR << "Wrote " << num_rotamers() << " rotamers at "
4034  << num_positions() << " positions to file " << filename << std::endl;
4035 }
4036 
4037 
4038 ///@begin OptEData::write_to_binary_file
4039 ///@brief writes out the optE data to a binary file
4040 ///@author ashworth
4041 void
4043 {
4044  std::ofstream outfile( filename.c_str(), std::ios::out | std::ios::binary );
4045  Size const npositions( data_.size() );
4046  outfile.write( (char*) &npositions, sizeof(Size) );
4047  for ( OptEPositionDataOPs::const_iterator pos( data_.begin() ); pos != data_.end(); ++pos ) {
4048  OptEPositionDataType pos_data_type = (*pos)->type();
4049  outfile.write( (char*) & pos_data_type, sizeof(OptEPositionDataType) );
4050  (*pos)->write_to_binary_file( outfile );
4051  }
4052  outfile.close();
4053  TR << "Wrote " << num_rotamers() << " rotamers at "
4054  << num_positions() << " positions to binary file " << filename << std::endl;
4055 
4056 }
4057 
4058 ///@begin OptEData::read_from_binary_file
4059 ///@brief binary I/O should be faster
4060 ///@author ashworth
4061 void
4063 {
4064 
4065  std::ifstream infile( filename.c_str(), std::ios::in | std::ios::binary );
4066  Size npositions(0);
4067  // this while loop allows concatenation of multiple optE output files
4068  while ( infile.read( (char*) &npositions, sizeof(Size) ) ) {
4069  for ( Size i(1); i <= npositions; ++i ) {
4070  OptEPositionDataType pos_data_type;
4071  infile.read( (char*) &pos_data_type, sizeof( OptEPositionDataType ) );
4073  pos_data->read_from_binary_file( infile );
4074  add_position_data( pos_data );
4075  }
4076  npositions = 0;
4077  }
4078  infile.close();
4079  TR << "Read in " << num_rotamers() << " rotamers at "
4080  << num_positions() << " positions from binary file " << filename << std::endl;
4081 
4082 }
4083 
4084 
4085 /// Initializers for static data
4087 
4090 
4091 std::map< std::string, OptEPositionDataType >
4093 
4096 {
4097  switch ( type ) {
4098  case prob_native_amino_acid :
4099  return new PNatAAOptEPositionData;
4102  case pssm_data :
4103  return new PSSMOptEPositionData;
4104  case prob_native_rotamer :
4105  return new PNatRotOptEPositionData;
4106  case prob_native_structure :
4107  return new PNatStructureOptEData;
4109  return new PNatLigPoseOptEData;
4110  case dG_binding_correlation :
4111  return new DGBindOptEData;
4113  return new DDGMutationOptEData;
4116  case ddG_bind_correlation :
4117  return new DDGBindOptEData;
4120  }
4121  return 0;
4122 }
4123 
4124 
4125 
4126 std::string const &
4128 {
4129  initialize_optE_type_name_map();
4130  runtime_assert( type > 0 && type <= n_optE_data_types );
4131  return optE_type_2_optE_type_name_[ type ];
4132 }
4133 
4134 bool
4136 {
4137  initialize_optE_type_name_map();
4138  return optE_type_name_map_.find( name ) != optE_type_name_map_.end();
4139 }
4140 
4143 {
4144  initialize_optE_type_name_map();
4145  runtime_assert( is_optE_type_name( name ));
4146  return optE_type_name_map_[ name ];
4147 }
4148 
4149 
4150 void
4152 {
4153  if ( optE_type_name_map_initialized_ ) return;
4154 
4155  optE_type_name_map_initialized_ = true;
4156 
4157  optE_type_2_optE_type_name_.resize( n_optE_data_types );
4158  optE_type_2_optE_type_name_[ prob_native_amino_acid ] = "prob_native_amino_acid";
4159  optE_type_2_optE_type_name_[ prob_native_amino_acid_with_unfolded_energy ] = "prob_native_amino_acid/unfolded_energy_scorefxn";
4160  optE_type_2_optE_type_name_[ pssm_data ] = "pssm_data";
4161  optE_type_2_optE_type_name_[ prob_native_rotamer ] = "prob_native_rotamer";
4162  optE_type_2_optE_type_name_[ prob_native_structure ] = "prob_native_structure";
4163  optE_type_2_optE_type_name_[ prob_native_ligand_pose ] = "prob_native_ligand_pose";
4164  optE_type_2_optE_type_name_[ dG_binding_correlation ] = "dG_binding_correlation";
4165  optE_type_2_optE_type_name_[ ddG_mutation_correlation ] = "ddG_mutation_correlation";
4166  optE_type_2_optE_type_name_[ ddG_mutation_correlation_with_unfolded_energy ] = "ddG_mutation_correlation/unfolded_energy_scorefxn";
4167  optE_type_2_optE_type_name_[ ddG_bind_correlation ] = "ddG_bind_correlation";
4168  optE_type_2_optE_type_name_[ constrained_optimization_weight_func ] = "constrained_optimization_weight_func";
4169 
4170  for ( Size ii = 1; ii <= n_optE_data_types; ++ii ) {
4171  optE_type_name_map_[ optE_type_2_optE_type_name_[ ii ] ] = static_cast< OptEPositionDataType > ( ii );
4172  }
4173 }
4174 
4175 
4176 
4177 }
4178 }