Rosetta 3.5
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
DecoySetEvaluation.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
11 /// @brief
12 /// @author smart money says oliver
13 
14 
18 
19 #include <core/types.hh>
20 
21 #include <core/pose/Pose.hh>
22 #include <core/pose/util.hh>
24 
26 // AUTO-REMOVED #include <core/scoring/constraints/ConstraintIO.hh>
31 
32 #include <protocols/loops/Loop.hh>
33 #include <protocols/loops/Loops.hh>
35 
36 // ObjexxFCL Headers
37 #include <ObjexxFCL/FArray3D.hh>
38 #include <ObjexxFCL/FArray2D.hh>
39 #include <ObjexxFCL/format.hh>
40 
41 // Utility headers
42 #include <basic/Tracer.hh>
43 #include <utility/exit.hh>
44 #include <utility/excn/Exceptions.hh>
45 #include <numeric/model_quality/rms.hh>
46 #include <basic/options/option_macros.hh>
47 
48 //// C++ headers
49 #include <string>
50 #include <iostream>
51 #include <cstdio>
52 
53 #include <core/id/NamedStubID.hh>
54 #include <utility/vector1.hh>
55 
56 OPT_1GRP_KEY( Real, dist_cst, max_dist )
57 OPT_1GRP_KEY( Real, dist_cst, sd )
58 OPT_1GRP_KEY( Real, dist_cst, ub_fact )
59 OPT_1GRP_KEY( Real, dist_cst, lb_fact )
60 OPT_1GRP_KEY( Real, dist_cst, min_ub )
61 OPT_1GRP_KEY( Real, dist_cst, grow_fact )
62 OPT_1GRP_KEY( Real, dist_cst, grow_fact_lb )
63 OPT_1GRP_KEY( Real, dist_cst, max_spread )
64 OPT_1GRP_KEY( Real, dist_cst, min_spread )
65 OPT_1GRP_KEY( File, dist_cst, excl_rigid )
66 OPT_1GRP_KEY( Boolean, dist_cst, median )
67 OPT_1GRP_KEY( Integer, dist_cst, min_seq_sep )
68 OPT_1GRP_KEY( File, dist_cst, dump )
69 
70 
71 bool protocols::toolbox::DecoySetEvaluation::options_registered_( false );
72 
73 void protocols::toolbox::DecoySetEvaluation::register_options() {
74  if ( !options_registered_ ) {
75  options_registered_ = true;
76  NEW_OPT( dist_cst::max_dist, "only use distances whose average distance is less than", 10 );
77  NEW_OPT( dist_cst::sd, "curvature for BoundFunc after ub is reached",1 );
78  NEW_OPT( dist_cst::ub_fact, "multiply this to sqrt of distance variance to get upper bound", 0.05 );
79  NEW_OPT( dist_cst::lb_fact, "multiply this to sqrt of distance variance to get lower bound", 0.02 );
80  NEW_OPT( dist_cst::grow_fact, "grow IN (positive) or OUTWARD( negative ) by grow_fact*(ub-lb)", -0.05 );
81  NEW_OPT( dist_cst::max_spread, "omit constraints with more than X between ub and lb (suggest: 5-7A) ", 5.0 );
82  NEW_OPT( dist_cst::min_spread, "enforce minimum flat bottom of X ", 2.0 );
83  NEW_OPT( dist_cst::min_ub, "make upper bound at least " , 0.0);
84  NEW_OPT( dist_cst::grow_fact_lb, "on top of grow_fact also grow_fact_lb only for the lb side", 0.00 );
85  NEW_OPT( dist_cst::min_seq_sep, "only constraints if residues are x apart", 4 );
86  NEW_OPT( dist_cst::median, "base bounds on sorted distances", false );
87  NEW_OPT( dist_cst::dump, "put all dists into this file to play around in matlab or R", "coords.dat" );
88  NEW_OPT( dist_cst::excl_rigid, "exclude constraints between residues that are in rigid core", "core.rigid" );
89  }
90 }
91 
92 namespace protocols {
93 namespace toolbox {
94 
95 using namespace ObjexxFCL;
96 
97 static basic::Tracer tr("protocols.toolbox.DecoySetEvaluation",basic::t_info);
98 
99 using namespace core;
100 using namespace numeric::model_quality; //for rms functions
101 
102 typedef core::Real matrix[3][3];
103 typedef core::Real rvec[3];
104 
105 
106 DecoySetEvaluation::DecoySetEvaluation() : COM( 3 ),n_decoys_( 0 ), n_atoms_( 0 ), n_decoys_max_( 0 )
107 {}
108 
110 
112  if ( n_resize == n_decoys_max_ ) return;
113  n_decoys_max_ = n_resize;
114  if ( n_atoms_ ) coords_.redimension( 3, n_atoms_, n_decoys_max_ );
115 }
116 
118  if ( n_decoys_ == 0 ) {
119  n_atoms_ = nres;
120  coords_.dimension( 3, n_atoms_, n_decoys_max_ );
121  weights_.dimension( n_atoms_, 1.0 );
122  ref_structure_.dimension( 3, n_atoms_ );
123  } else {
124  if ( n_atoms_ != nres ) {
125  utility_exit_with_message( "can't insert poses with varying sizes into DecoySetEvaluation" );
126  }
127  }
128 
129  if ( n_decoys_ >= n_decoys_max_ ) {
130  // we could also just resize... but I want the user to know.. because he should keep track which decoy is which...
131  throw utility::excn::EXCN_RangeError( "you can't add any more decoys to DecoySetEvaluation ");
132  }
133  ++n_decoys_;
134 }
135 
137  //count residues with CA
138  Size nres=0;
139  for ( core::Size i = 1; i <= pose.total_residue(); i++ ) {
140  if ( !pose.residue_type( i ).is_protein() ) break;
141  ++nres;
142  }
143 
144  prepare_push_back( nres );
145 
146  // fill coords
147  for ( core::Size i = 1; i <= nres; i++ ) {
148  id::NamedAtomID idCA( "CA", i );
149  PointPosition const& xyz = pose.xyz( idCA );
150  for ( core::Size d = 1; d<=3; ++d ) {
151  coords_( d, i, n_decoys_ ) = xyz[ d-1 ];
152  }
153  }
154 
155  if ( n_decoys_ == 1 ) {
156  ref_pose_ = pose;
157  }
158 
159 }
160 
161 
162 void DecoySetEvaluation::push_back_CA_xyz( ObjexxFCL::FArray2_double const& xyz, core::Size nres ) {
163  prepare_push_back( nres ); //increments n_decoys_
164 
165  // fill coords
166  for ( core::Size i = 1; i <= nres; i++ ) {
167  for ( core::Size d = 1; d<=3; ++d ) {
168  coords_( d, i, n_decoys_ ) = xyz( d, i );
169  }
170  }
171 }
172 
173 /*
174 void DecoySetEvaluation::push_back_CA_xyz( ObjexxFCL::FArray2D< core::Real > const& xyz, core::Size nres ) {
175  prepare_push_back( nres );
176 
177  // fill coords
178  for ( core::Size i = 1; i <= n_atoms_; i++ ) {
179  for ( core::Size d = 1; d<=3; ++d ) {
180  coords_( d, i, n_decoys_ ) = xyz( d, i );
181  }
182  }
183 }
184 */
185 
187  //erases last decoy of decoy_set
188  std::cerr << "DSE erasing the last decoy in the set: " << n_decoys_ << std::endl;
189  n_decoys_--;
190  std::cerr << "DSE now has " << n_decoys_ << std::endl;
191  std::cerr << "DSE redimensioning: old dimension: " << coords_.u1() << " " << coords_.u2() << " " << coords_.u3() << std::endl;
192  coords_.redimension( 3, (n_atoms_*n_decoys_) , n_decoys_ );
193  std::cerr << "DSE new dimensions : " << coords_.u1() << " " << coords_.u2() << " " << coords_.u3() << std::endl;
194 }
195 
197  Size const n_new_decoys( sfd.size() );
198  push_back_CA_xyz_from_silent_file( n_new_decoys, sfd.begin(), sfd.end(), store_energies );
199 }
200 
202  if ( n_atoms() ) tr.Warning << "Overriding n_atom in DecoySetEvaluation " << std::endl;
203  n_atoms_ = natoms;
204 }
205 
207  FArray1D_double const weights( n_atoms_, 1.0 );
208  superimpose( weights, icenter );
209 }
210 
211 void DecoySetEvaluation::set_weights( ObjexxFCL::FArray1_double const& weights ) {
212  for ( Size i=1; i<=n_atoms_; ++i ) weights_( i ) = weights( i );
213 }
214 
215 core::Real DecoySetEvaluation::rmsd( FArray1_double const& weights, FArray2_double& xx_ref, FArray2_double& xx ) const {
216  FArray1D_double transvec( 3 );
217  reset_x( n_atoms_, xx_ref, weights, transvec );
218  reset_x( n_atoms_, xx, weights, transvec );
219  Matrix R;
220  // FArray2P_double xx_ref( coords_( 1, 1, n ), 3, n_atoms_ ); //proxy array provides view to coords_
221  fit_centered_coords( n_atoms_, weights, xx_ref, xx, R );
222  Real rmsd( 0.0 );
223  Real invn( 1.0/n_atoms() );
224  for ( Size n = 1; n <= n_atoms(); n++) {
225  for ( Size d = 1; d<=3; ++d ) {
226  rmsd += ( xx( d, n ) - xx_ref( d, n ) ) * ( xx( d, n ) - xx_ref( d, n ) ) * invn * weights_( n );
227  }
228  }
229  return rmsd = sqrt( rmsd );
230 }
231 
232 void DecoySetEvaluation::superimpose( FArray1_double const& weights, Size icenter ) {
233  if ( n_decoys() == 0 ) return;
234  FArray2P_double xx_ref( coords_( 1, 1, icenter ), 3, n_atoms_ ); //proxy array provides view to coords_
235  tr.Debug << "superimpose with " << n_decoys() << " with " << icenter << " as reference structure " << std::endl;
236  Size go_around( icenter + n_decoys_ - 1 );
237  Size offset( 0 );
238  for ( Size ni = icenter; ni <= go_around; ++ni ) {
239  Size n( ni - offset );
240  if ( n > n_decoys_ ) {
241  offset = n_decoys_;
242  n = 1;
243  }
244  FArray2P_double xx( coords_( 1, 1, n ), 3, n_atoms_ ); //proxy array provides view to coords_
245 // FArray1D_double transvec( 3 );
246 // reset_x( n_atoms_, xx, weights, transvec );
247  center_structure( n, weights );
248 
249  //fit
250  if ( n != icenter ) {
251  Matrix R;
252  // FArray2P_double xx2( coords_( 1, 1, n ), 3, n_atoms_ ); //proxy array provides view to coords_
253  fit_centered_coords( n_atoms_, weights, xx_ref, xx, R );
254  }
255  } // for ni
256 }
257 
259  FArray1D_double const weights( n_atoms_, 1.0 );
260  center_structure( i, weights );
261 }
262 
263 void DecoySetEvaluation::center_structure( core::Size i, FArray1_double const& weights ) {
264  FArray2P_double xx( coords_( 1, 1, i ), 3, n_atoms_ ); //proxy array provides view to coords_
265  FArray1D_double transvec( 3 );
266  reset_x( n_atoms_, xx, weights, transvec );
267 }
268 
269 void DecoySetEvaluation::center_all( FArray1_double const& weights ) {
270  for ( Size n = 1; n <= n_decoys_; ++n ) {
271  center_structure( n, weights );
272  }
273 }
274 
275 //only makes sense after "superimpose"
276 void DecoySetEvaluation::compute_average_structure( FArray2_double& average_structure ) const {
277  for ( Size n = 1; n<= n_decoys_; ++n ) {
278  for ( Size d = 1; d<=3; ++d ) {
279  for ( Size iatom = 1; iatom<=n_atoms_; ++iatom ) {
280  average_structure( d, iatom ) += coords_( d, iatom, n )/n_decoys_;
281  }
282  }
283  }
284 }
285 
286 Size DecoySetEvaluation::find_closest_to_average( FArray2_double& average_structure ) const {
287  Real best_dist( 100000000 );
288  Size closest_structure( 1 );
289 
290  for ( Size n = 1; n<=n_decoys_; ++n ) {
291  Real dist2( 0 );
292  for ( Size iatom = 1; iatom <=n_atoms_; ++iatom ) {
293  for ( Size d=1; d<=3; ++d ) {
294  dist2 += (average_structure( d, iatom ) - coords_( d, iatom, n ))*(average_structure( d, iatom ) - coords_( d, iatom, n ));
295  }
296  }
297  tr.Trace << "dist to average " << dist2 << std::endl;
298  if ( dist2 < (best_dist - 0.01) ) { //make sure it is a significant improvement in distance
299  best_dist = dist2;
300  closest_structure = n;
301  }
302  }
303  return closest_structure;
304 }
305 
307  //Real rms( 0 );
308  Vector rmsd_x( 0.0 );
309  Vector rmsd_av( 0.0 );
310  Real invn( 1.0 /n_decoys() );
311  for ( Size idecoy = 1; idecoy <= n_decoys(); ++idecoy ) {
312  for ( Size d = 1; d<=3; ++d ) {
313  Real dx = coords_( d, pos, idecoy );
314  rmsd_x( d ) += dx * dx * invn;
315  rmsd_av( d ) += dx * invn;
316  }
317  }
318  Real rms( 0 );
319  for ( Size d = 1; d<=3; ++d ) {
320  rms += rmsd_x( d ) - rmsd_av( d )*rmsd_av( d );
321  }
322  return sqrt( rms );
323 }
324 
326  result.clear();
327  result.reserve( n_atoms_ );
328 
329  for ( Size pos = 1; pos <= n_atoms_; ++pos ) {
330  result.push_back( rmsf( pos ) );
331  }
332 }
333 
334 void DecoySetEvaluation::rmsf( FArray1_double& result ) {
335  for ( Size pos = 1; pos <= n_atoms_; ++pos ) {
336  result( pos ) = rmsf( pos );
337  }
338 }
339 
340 //return icenter
341 Size DecoySetEvaluation::wRMSD( Real sigma2, Real tolerance, ObjexxFCL::FArray1_double& weights ) {
342  if ( n_decoys() == 0 || n_atoms_ == 0 ) return 0;
343  //FArray1D_double weights( n_atoms_, 1.0 );
344  Real wsum_old = 100;
345  Real wsum ( 1.0 );
346  Real invn ( 1.0/n_atoms_ );
347  Size ct ( 0 );
348  Size i_center( 1 );
349  Size max_iter( 100 );
350  tr.Debug << "run wRMSD iterations with " << n_decoys() << " decoys of " << n_atoms() << " atoms " << std::endl;
351  tr.Info << "wRMSD: iter wsum wRMSD icenter " << std::endl;
352  while ( ( std::abs( wsum_old - wsum ) > tolerance ) && ( --max_iter > 0 ) ) {
353  superimpose( weights, i_center );
354  FArray2D_double average_structure( 3, n_atoms_, 0.0 );
355  compute_average_structure( average_structure );
356  i_center = find_closest_to_average( average_structure );
357  rmsf( weights );
358  wsum_old = wsum;
359  wsum = 0.0;
360  Real wMSD = 0.0;
361  for ( Size i = 1; i <= n_atoms_; ++i ) {
362  Real di2 = weights( i )*weights( i );
363  weights( i ) = exp( - di2 / sigma2 );
364  wsum += weights( i )*invn;
365  wMSD += weights( i ) * di2;
366  }
367  tr.Info << "wRMSD: " << ++ct << " " << wsum << " " << sqrt( wMSD ) << " " << i_center << std::endl;
368  }
369  return i_center;
370 }
371 
373  dist.dimension( n_decoys(), n_decoys(), 0.0 );
374  int count = 0;
375  Real invn( 1.0 / n_atoms() );
376 
377  Real sum_w( 0.0 );
378  for ( Size n = 1; n <= n_atoms(); n++) {
379  sum_w+=weights_( n );
380  }
381  invn = 1.0 / sum_w;
382 
383  for ( Size i = 1; i <= n_decoys(); i++ ) {
384 
385  FArray2P_double xx( coords_( 1, 1, i ), 3, n_atoms_ ); //proxy array provides view to coords_
386  FArray1D_double transvec( 3 );
387  reset_x( n_atoms_, xx, weights_, transvec );
388 
389  for ( Size j = 1; j<i; j++ ) {
390  //already centered since j<i
391  Matrix R;
392  FArray2P_double xx2( coords_( 1, 1, j ), 3, n_atoms_ ); //proxy array provides view to coords_
393  fit_centered_coords( n_atoms_, weights_, xx, xx2, R );
394  Real rmsd( 0.0 );
395  for ( Size n = 1; n <= n_atoms(); n++) {
396  for ( Size d = 1; d<=3; ++d ) {
397  rmsd += ( xx( d, n ) - xx2( d, n ) ) * ( xx( d, n ) - xx2( d, n ) ) * invn * weights_( n );
398  }
399  }
400  rmsd = sqrt( rmsd );
401  dist( i, j ) = rmsd;
402  dist( j, i ) = rmsd;
403  // tr.Trace << i << " " << j << " " << rmsd << " " << n_atoms_ << std::endl;
404  // print some stats of progress
405  count ++;
406  if ( count % 50000 == 0 ) {
407  Real const percent_done ( 200.0 * static_cast< Real > ( count ) / ( (n_decoys() - 1) * n_decoys() ) );
408  tr.Info << count
409  << "/" << ( n_decoys() - 1 )*( n_decoys() )/2
410  << " ( " << ObjexxFCL::fmt::F(8,1,percent_done) << "% )"
411  << std::endl;
412  }
413  }
414  dist ( i,i )=0.0;
415  }
416 }
417 
418 
421 ) const {
422 
423 using namespace basic::options;
424 using namespace basic::options::OptionKeys;
425  runtime_assert( options_registered_ );
426 
427  if ( option[ dist_cst::median ]() ) {
429  return;
430  }
431  ObjexxFCL::FArray2D_double ivm( n_atoms(), n_atoms(), 0.0 );
432  Real const invn( 1.0/n_decoys() );
433 
434  for ( Size i = 1; i <= n_atoms(); i++ ) {
435  for ( Size j = i+1; j<=n_atoms(); j++ ) {
436  Real var( 0.0 );
437  Real av( 0.0 );
438 
439  for ( Size n = 1; n<=n_decoys(); n++ ) {
440  core::Vector xi( coords_( 1, i, n ), coords_( 2, i, n ), coords_( 3, i, n ));
441  core::Vector xj( coords_( 1, j, n ), coords_( 2, j, n ), coords_( 3, j, n ));
442  Real dist = xi.distance(xj);
443  var += dist * dist * invn;
444  av += dist * invn;
445  }
446  ivm( j, i ) = var - av*av;
447  ivm( i, j ) = ivm( j, i);
448  tr.Debug << i << " " << j << " " << ivm( i, j ) << "\n";
449  if ( av < option[ dist_cst::max_dist ] && ( (int) j - (int) i) >= option[ dist_cst::min_seq_sep ]) {
450  using namespace scoring::constraints;
451  Real const lb( sqrt( ivm( i,j ) )*option[ dist_cst::lb_fact ] );
452  Real const ub( sqrt( ivm( i,j ) )*option[ dist_cst::ub_fact ] );
453  Real const sd( option[ dist_cst::sd ] );
455  id::NamedAtomID( "CA", i ),
456  id::NamedAtomID( "CA", j ),
457  new BoundFunc( av - lb, av + ub, sd, "CM_DECOYS" )
458  );
459  cst_set.add_constraint( cst.clone() );
460  pose::Pose dummy_pose;
461  cst.show_def( std::cout, dummy_pose );
462  }
463  }
464  }
465  tr.Debug << std::endl;
466 }
467 
468 
471 ) const {
472 using namespace basic::options;
473 using namespace basic::options::OptionKeys;
474 
475 
476  Real const invn( 1.0/n_decoys() );
477  Size const Nlb( static_cast< Size > ( std::ceil( n_decoys()*option[ dist_cst::lb_fact ] )));
478  Size const Nub( static_cast< Size > ( std::ceil( n_decoys()*option[ dist_cst::ub_fact ] )));
479  Real const grow_fact( option[ dist_cst::grow_fact ] );
480  Real const grow_fact_lb( option[ dist_cst::grow_fact_lb ] );
481  loops::Loops rigid;
482  if ( option[ dist_cst::excl_rigid ].user() ) {
483  std::ifstream is( option[ dist_cst::excl_rigid ]().name().c_str() );
484 
485  if (!is.good()) {
486  utility_exit_with_message( "[ERROR] Error opening RBSeg file '" + option[ dist_cst::excl_rigid ]().name() + "'" );
487  }
488 
492  is, option[ dist_cst::excl_rigid ](), false );
493  rigid = loops::Loops( loops );
494  }
495  // utility::vector1< core::Real > dist_sorted;
496  for ( Size i = 1; i <= n_atoms(); i++ ) {
497  for ( Size j = i+1; j<=n_atoms(); j++ ) {
498  if ( rigid.size() && rigid.is_loop_residue( i ) && rigid.is_loop_residue( j ) ) continue;
499  Real av( 0.0 );
500  // dist_sorted.clear();
501  // dist_sorted.reserve(n_decoys());
502  Real* dist_sorted = new Real[ n_decoys() ];
503  for ( Size n = 1; n<=n_decoys(); n++ ) {
504  core::Vector xi( coords_( 1, i, n ), coords_( 2, i, n ), coords_( 3, i, n ));
505  core::Vector xj( coords_( 1, j, n ), coords_( 2, j, n ), coords_( 3, j, n ));
506  Real dist = xi.distance(xj);
507  av += dist * invn;
508  // dist_sorted.push_back( dist );
509  dist_sorted[ n - 1 ]=dist;
510  }
511  if ( av < option[ dist_cst::max_dist ] && ( (int) j - (int) i) >= option[ dist_cst::min_seq_sep ]) {
512  std::sort( dist_sorted, dist_sorted + n_decoys() );
513  tr.Debug << "Nlb: " << Nlb << " "<< dist_sorted[ Nlb ] << " Nub: " << Nub << " " << dist_sorted[ n_decoys()-Nub ] << std::endl;
514  Real lb( dist_sorted[ Nlb ] );
515  Real ub( dist_sorted[ n_decoys() - Nub ] );
516  lb = lb + (ub-lb)*(grow_fact + grow_fact_lb );
517  ub = ub - (ub-lb)*grow_fact;
518  if ( ub - lb < option[ dist_cst::max_spread ]() ) {
519  if ( ub < option[ dist_cst::min_ub ] ) ub = option[ dist_cst::min_ub ];
520  if ( (ub - lb) < option[ dist_cst::min_spread ]() ) {
521  ub = (ub+lb)*0.5 + 0.5*option[ dist_cst::min_spread ]();
522  lb = (ub+lb)*0.5 - 0.5*option[ dist_cst::min_spread ]();
523  }
524  Real const sd( option[ dist_cst::sd ] );
525  using namespace scoring::constraints;
527  id::NamedAtomID( "CA", i ),
528  id::NamedAtomID( "CA", j ),
529  new BoundFunc( lb, ub, sd, "CM_DECOYS" )
530  );
531  cst_set.add_constraint( cst.clone() );
532  pose::Pose dummy_pose;
533  cst.show_def( std::cout, dummy_pose );
534  }
535  }
536  delete[] dist_sorted;
537  }
538  }
539  tr.Debug << std::endl;
540 }
541 
542 
545  core::pose::Pose const& ref_pose,
546  Size root
547 ) const {
548 using namespace basic::options;
549 using namespace basic::options::OptionKeys;
550 
551  Real const invn( 1.0/n_decoys() );
552  //Size const Nlb( std::ceil( n_decoys()*option[ dist_cst::lb_fact ] ));
553  Size const Nub( static_cast< Size > ( std::ceil( n_decoys()*option[ dist_cst::ub_fact ] )));
554  if ( Nub >= n_decoys() ) {
555  utility_exit_with_message( "set ub_fact to 0.05 such that e.g., 5% of decoys are allowed to violate upper bound." );
556  }
557  Real const grow_fact( option[ dist_cst::grow_fact ] );
558  Real const min_ub( option[ dist_cst::min_ub ] );
559  //Size const grow_fact_lb( option[ dist_cst::grow_fact_lb ] );
560 
561  // utility::vector1< core::Real > dist_sorted;
562  for ( Size pos = 1; pos <= n_atoms(); pos++ ) {
563  core::Vector xyz_av( 0.0 );
564  //compute average position
565  for ( Size n = 1; n<=n_decoys(); n++ ) {
566  for ( Size d = 1; d<=3; ++d ) {
567  core::Real dx = coords_( d, pos, n );
568  xyz_av( d ) += dx * invn;
569  }
570  }
571 
572  //use this to throw outliers away.
573  typedef std::list< std::pair< core::Real, Size > > PointList;
574  PointList sorted_points;
575  for ( Size n = 1; n<=n_decoys(); n++ ) {
576  core::Vector xi( coords_( 1, pos, n ), coords_( 2, pos, n ), coords_( 3, pos, n ));
577  Real dist = xyz_av.distance(xi);
578  sorted_points.push_back( std::make_pair( dist, n ) );
579  }
580  sorted_points.sort();
581 
582  //now compute new average only on the 70% points closest to the average xyz
583  Size ct = 1;
584  Size const N_find_center( static_cast< Size >( std::ceil( n_decoys()*0.7 )));
585  tr.Debug << "use " << N_find_center << " points to compute average " << std::endl;
586  xyz_av = core::Vector( 0.0 );
587  for ( PointList::const_iterator it = sorted_points.begin(); ct<=N_find_center; ++ct, ++it ) {
588  for ( Size d = 1; d<=3; ++d ) {
589  Real dx = coords_( d, pos, it->second );
590  xyz_av( d ) += dx / N_find_center;
591  }
592  }
593  char buf[300];
594  sprintf( buf, "%8.3f%8.3f%8.3f",xyz_av.x(),xyz_av.y(),xyz_av.z() );
595  std::cout << "ATOM " << ObjexxFCL::fmt::RJ( 5, pos) << " CA " << " ALA A " << ObjexxFCL::fmt::RJ( 3, pos) << " " << std::setw( 3) <<
596  buf << std::endl;
597 
598 
599  Real* dist_sorted = new Real[ n_decoys() ];
600  for ( Size n = 1; n<=n_decoys(); n++ ) {
601  core::Vector xi( coords_( 1, pos, n ), coords_( 2, pos, n ), coords_( 3, pos, n ));
602  Real dist = xyz_av.distance(xi);
603  tr.Debug << "push_dist " << dist << std::endl;
604  dist_sorted[ n - 1 ]=dist;
605  }
606 
607  std::sort( dist_sorted, dist_sorted + n_decoys() );
608 
609  Real lb( 0.0 );
610  Real ub( dist_sorted[ n_decoys() - Nub ] );
611  delete[] dist_sorted;
612  tr.Debug << "ub-raw " << ub << std::endl;
613  ub = ub - ub*grow_fact;
614  if ( ub <= min_ub ) ub = min_ub;
615  using namespace scoring::constraints;
617  id::AtomID( ref_pose.residue(pos).atom_index("CA"), pos),
619  xyz_av,
620  new BoundFunc( lb, ub, 1.0, "CM_DECOYS" )
621  );
622  cst_set.add_constraint( cst.clone() );
623  }
624 }
625 
626 
627 // void DecoySetEvaluation::dump_coords( utility::io::ozstream& out) const {
628 
629 // // dump file with i, j dist1 dist2 ..... dist N
630 // for ( Size i = 1; i <= n_atoms(); i++ ) {
631 // for ( Size j = i+3; j<=n_atoms(); j++ ) {
632 // out << i << " " << j << " ";
633 // for ( Size n = 1; n<=n_decoys(); n++ ) {
634 // core::Vector xi( coords_( 1, i, n ), coords_( 2, i, n ), coords_( 3, i, n ));
635 // core::Vector xj( coords_( 1, j, n ), coords_( 2, j, n ), coords_( 3, j, n ));
636 // Real dist = distance(xi, xj);
637 // out << dist << " ";
638 // }
639 // out << std::endl;
640 // }
641 // }
642 // }
643 
644 
645 
646 } //evaluation
647 } //protocols