Rosetta 3.5
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
FlexPepDockingPoseMetrics.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) 199x-2008 Hebrew University, Jerusalem
5 //
6 // (c) Copyright Rosetta Commons Member Institutions.
7 // (c) This file is part of the Rosetta software suite and is made available under license.
8 // (c) The Rosetta software is developed by the contributing members of the Rosetta Commons.
9 // (c) For more information, see http://www.rosettacommons.org. Questions about this can be
10 // (c) addressed to University of Washington UW TechTransfer, email: license@u.washington.edu.
11 /// @file FlexPepDockingPoseMetrics.cc
12 ///
13 /// @brief metrics calculations specific for FlexPepDock (at least for now)
14 /// @date March 29th, 2009
15 /// @author Barak Raveh / Nir London
16 
19 
21 #include <core/pose/Pose.hh>
23 #include <core/scoring/Energies.hh>
26 #include <core/scoring/rms_util.hh>
28 // AUTO-REMOVED #include <core/scoring/constraints/util.hh>
29 
30 #include <basic/basic.hh>
31 #include <basic/Tracer.hh>
32 #include <basic/MetricValue.hh>
33 #include <core/types.hh>
39 // AUTO-REMOVED #include <protocols/viewer/viewers.hh>
40 
41 // Utility headers
42 #include <utility/file/FileName.hh>
43 #include <utility/assert.hh>
44 
45 // ObjexxFCL headers
46 #include <ObjexxFCL/FArray1D.hh>
47 #include <limits>
48 #include <string>
49 
50 #include <utility/vector1.hh>
51 
52 
53 using basic::T;
54 using basic::Error;
55 using basic::Warning;
56 using core::pose::Pose;
57 
58 static basic::Tracer TR("FlexPepDockingPoseMetrics");
59 
60 namespace protocols {
61 namespace flexpep_docking {
62 
63  //@brief fraction of native contacts modeled in final pose (relative to native)
64  //
65  //@param native - native pose
66  //@param final - final model
67  //@param threshold - threshold in Angstroms for native contacts (two
68  // (residues define a native contact if the distance
69  // between two of their atoms is lower than threshold)
72  Pose const& native,
73  Pose const& final,
74  core::Real threashold
75 ) const
76 {
77  core::Size numOfNativeContacts = 0;
78  core::Size subsetOfPredictedContacts = 0;
79 
80  if(flags_->pep_fold_only)
81  {
82  TR << "WARNING: calc_frac_native_contacts() should have not been invoked when -pep_fold_only flag (= no receptor) is active";
83  return 0.0;
84  }
85  //iterate over the peptide
86  for (int i=flags_->peptide_first_res(); i<=flags_->peptide_last_res(); ++i)
87  {
88  //iterate over the protein
89  for (int j=flags_->receptor_first_res(); j<=flags_->receptor_last_res(); ++j)
90  {
91  if (isInContact(native.residue(i),native.residue(j),threashold))
92  {
93  numOfNativeContacts++;
94  if (isInContact(final.residue(i),final.residue(j),threashold))
95  {
96  subsetOfPredictedContacts++;
97  }
98  }
99  }
100  }
101  TR << "nat " << numOfNativeContacts << std::endl;
102  TR << "rec " << subsetOfPredictedContacts << std::endl;
103  core::Real fnat = ((core::Real)subsetOfPredictedContacts/(core::Real)numOfNativeContacts);
104  return fnat;
105 }
106 
108  core::conformation::Residue const res1,
109  core::conformation::Residue const res2,
110  core::Real threashold
111 ) const
112 {
113  core::Size natoms_res1 = res1.natoms();
114  core::Size natoms_res2 = res2.natoms();
115  for ( core::Size i = 1; i <= natoms_res1; ++i ) {
116  for ( core::Size j = 1; j <= natoms_res2; ++j ) {
117  core::Distance dist = res1.xyz(i).distance( res2.xyz(j) );
118  if( dist <= threashold ) {
119  return true;
120  }
121  }
122  }
123  // in case no two atoms are below the threashold
124  return false;
125 }
126 
127 
130  Pose const& pose1,
131  Pose const & pose2,
132  ObjexxFCL::FArray1D_bool const & res_subset,
133  t_predicate_func predicate,
134  double k,
135  core::Size & ngood
136 ) const
137 {
138  using namespace core::scoring;
139 
140  core::Size const nres1 = pose1.total_residue();
141  ASSERT_ONLY(core::Size const nres2 = pose2.total_residue();)
142  assert( nres1 == nres2 );
143 
144  ngood = 0;
145  core::Size natoms_total( 0 );
146  for ( core::Size i = 1; i <= nres1; ++i )
147  {
148  if(!res_subset(i))
149  continue;
150  core::Size natoms_res ( pose1.residue(i).natoms() );
151  if ( predicate == &is_ligand_heavyatom ||
152  predicate == &is_polymer_heavyatom ||
153  predicate == &is_heavyatom )
154  {
155  assert( pose1.residue(i).natoms() == pose2.residue(i).natoms() );
156  }
157  else if ( natoms_res > pose2.residue(i).natoms() )
158  {
159  natoms_res = pose2.residue(i).natoms();
160  }
161  for ( core::Size j = 1; j <= natoms_res; ++j )
162  {
163  if ( predicate( pose1, pose2, i, j ) )
164  {
165  core::Distance dist = pose1.residue(i).xyz(j).distance( pose2.residue(i).xyz(j) );
166  if( dist <= k )
167  ngood++;
168  natoms_total += 1;
169  }
170  }
171  }
172  return (ngood * 1.0) / natoms_total;
173 }
174 
175 
176 // check all sequential Kmers in the peptide, and output the best RMS Kmer
179  ( Pose const& pose1,
180  Pose const& pose2,
181  t_predicate_func predicate,
182  core::Size k) const
183 {
184  using namespace core;
185  assert(pose1.total_residue() == pose2.total_residue());
186  // NOTE: purposely an inefficient but simpler construction...
187  // It would be more efficient to calc the RMS of each position separately
188  // and make the calculation incrementaly, but why bother (Barak)
189  Size nres = pose1.total_residue();
190  Size res1_first = flags_->peptide_first_res() ;
191  Size res1_last = nres - k + 1;
192  Real best_rms = std::numeric_limits<Real>::infinity();
193  for(Size res1 = res1_first ; res1 <= res1_last ; ++res1)
194  {
195  ObjexxFCL::FArray1D_bool res_subset( nres, false );
196  for(Size resi = res1; resi < res1 + k; ++resi){
197  res_subset(resi) = true;
198  }
199  Real cur_rms = scoring::rmsd_no_super_subset( pose1, pose2, res_subset, *predicate );
200  if(cur_rms < best_rms)
201  best_rms = cur_rms;
202  }
203  return best_rms;
204 }
205 
206 
207 /////////////////////////////////////////////////////////////////////////////
208 /// @begin calculate phi/psi torsion-RMSD over peptide
209 ///
210 // @detailed
211 // Calculate the RMSD in phi.psi angle over specified residues
212 //
213 // @param
214 // pose1 - the first structure to be assessed
215 // pose2 - the second structure to be assessed
216 // res_subset - an array of size (nres) indicating the residue
217 // subset for the computation
218 //
219 // @return
220 // phi/psi torsion-RMSD between peptide backbones
221 ////////////////////////////////////////////////////////////////////////////
224 ( Pose const& pose1,
225  Pose const& pose2,
226  ObjexxFCL::FArray1D_bool const & res_subset) const
227 {
228  using namespace core;
229  using namespace basic;
230  assert(pose1.total_residue() == pose2.total_residue());
231  Size nres = pose1.total_residue();
232  Real sumSqr = 0.0; // MSD = sum square deviation
233  Size n = 0;
234  for(Size i = 1 ; i <= nres ; ++i)
235  {
236  if(!res_subset(i))
237  continue;
238  Real phidiff = subtract_degree_angles(pose1.phi(i), pose2.phi(i));
239  Real psidiff = subtract_degree_angles(pose1.psi(i), pose2.psi(i));
240  if(!pose1.residue_type(i).is_lower_terminus()){
241  sumSqr += pow(phidiff,2);
242  n++;
243  }
244  if(!pose1.residue_type(i).is_upper_terminus()) {
245  sumSqr += pow(psidiff,2);
246  n++;
247  }
248  }
249  return sqrt( sumSqr / n);
250 
251 }
252 
253 
254 /////////////////////////////////////////
255 // Calculate pose metrics for interface
256 // and cache them to the score map
257 // calculates i_sc as well
258 /////////////////////////////////////////
259 std::map < std::string, core::Real >
261  using namespace core;
262  using namespace core::pose::metrics;
263  using namespace core::scoring;
264 
265  std::map < std::string, core::Real > if_metrics;
266 
267  core::scoring::ScoreFunctionOP scorefxn_no_cst = new core::scoring::ScoreFunction (*scorefxn);
268  scorefxn_no_cst->set_weight(coordinate_constraint, 0.0);
269  scorefxn_no_cst->set_weight(atom_pair_constraint, 0.0);
270  scorefxn_no_cst->set_weight(angle_constraint, 0.0);
271  scorefxn_no_cst->set_weight(dihedral_constraint, 0.0);
272 
273  // calculate score, this is essential just because of bug in h-bond metrics in pose - TODO: fix this bug //
274  (*scorefxn_no_cst)(pose);
275 
276  //////// calculate interface score ////////
277  core::pose::Pose unbound_pose = pose;
278  float trans_magnitude = 1000;
279  rigid::RigidBodyTransMoverOP translate_away ( new rigid::RigidBodyTransMover( unbound_pose, rb_jump ) );
280  translate_away->step_size( trans_magnitude );
281 
282  float bound_energy = (*scorefxn_no_cst)( unbound_pose );
283  translate_away->apply( unbound_pose );
284  float unbound_energy = (*scorefxn_no_cst)( unbound_pose );
285 
286  float Isc = (bound_energy - unbound_energy);
287  TR << "Isc: " << Isc << std::endl;
288  ///////////////////////////////////////////
289 
290  std::string sasa_calc_name = "sasa";
291  std::string hbond_calc_name = "hbond";
292  std::string packstat_calc_name = "packstat";
293  std::string burunsat_calc_name = "burunsat";
294  ////std::string nonlocalcontacts_calc_name = "conts";
295 
296  // Register calculators (if they do not exist)
297 
298  // sasa
299  if( !CalculatorFactory::Instance().check_calculator_exists( sasa_calc_name ) ){
300  PoseMetricCalculatorOP sasa_calculator =
302  CalculatorFactory::Instance().register_calculator
303  ( sasa_calc_name, sasa_calculator );
304  }
305  // hbonds
306  if( !CalculatorFactory::Instance().check_calculator_exists( hbond_calc_name ) ){
310  ( hbond_calc_name, hb_calc );
311  }
312  // packstats
313  if( !CalculatorFactory::Instance().check_calculator_exists( packstat_calc_name ) ){
317  ( packstat_calc_name, packstat_calc );
318  }
319  // burried unsatisfied polar
320  if( !CalculatorFactory::Instance().check_calculator_exists( burunsat_calc_name ) ){
323  (sasa_calc_name, hbond_calc_name);
325  ( burunsat_calc_name, burunsat_calc );
326  }
327 
328  // define containers for metrics for total complex
329  basic::MetricValue<Real> tot_sasa_mval;
330  basic::MetricValue<Size> tot_hb_mval;
331  basic::MetricValue<Real> tot_packstat_mval;
332  basic::MetricValue<Size> tot_unsat_mval;
333 
334  // define containers for metrics per peptide residue
335  basic::MetricValue< utility::vector1< core::Real > >bound_sasa_per_res_mval;
336  basic::MetricValue< utility::vector1< core::Size > >bound_hb_per_res_mval;
337  basic::MetricValue< utility::vector1< core::Real > >bound_packstat_per_res_mval;
338  basic::MetricValue< utility::vector1< core::Size > >bound_unsat_per_res_mval;
339 
340  basic::MetricValue< utility::vector1< core::Real > >unbound_sasa_per_res_mval;
341  basic::MetricValue< utility::vector1< core::Size > >unbound_hb_per_res_mval;
342  basic::MetricValue< utility::vector1< core::Real > >unbound_packstat_per_res_mval;
343  basic::MetricValue< utility::vector1< core::Size > >unbound_unsat_per_res_mval;
344 
345  // calculate and store total metrics for bound and unbound poses
346  float bound_sasa = 0.0, unbound_sasa = 0.0;
347  Size bound_hb = 0, unbound_hb = 0;
348  float bound_packstat = 0.0, unbound_packstat = 0.0;
349  Size bound_unsat = 0, unbound_unsat = 0;
350 
351  //delta sasa calculation
352  pose.metric(sasa_calc_name,"total_sasa",tot_sasa_mval);
353  bound_sasa = tot_sasa_mval.value();
354  unbound_pose.metric(sasa_calc_name,"total_sasa",tot_sasa_mval);
355  unbound_sasa = tot_sasa_mval.value();
356  TR << "Total BSA is: " << unbound_sasa - bound_sasa << std::endl;
357 
358  //interface hb calculation
359  pose.metric(hbond_calc_name,"all_Hbonds", tot_hb_mval);
360  bound_hb = tot_hb_mval.value();
361  unbound_pose.metric(hbond_calc_name,"all_Hbonds", tot_hb_mval);
362  unbound_hb = tot_hb_mval.value();
363  TR << "Interface HB #: " << bound_hb - unbound_hb << std::endl;
364 
365  if (!flags_->is_ligand_present(pose)) {
366  //packstat calculation
367  pose.metric(packstat_calc_name,"total_packstat", tot_packstat_mval);
368  bound_packstat = tot_packstat_mval.value();
369  unbound_pose.metric(packstat_calc_name,"total_packstat", tot_packstat_mval);
370  unbound_packstat = tot_packstat_mval.value();
371  TR << "Total packstats: " << bound_packstat - unbound_packstat << std::endl;
372  }
373 
374  //unsat polar calculation
375  pose.metric(burunsat_calc_name,"all_bur_unsat_polars", tot_unsat_mval);
376  bound_unsat = tot_unsat_mval.value();
377  unbound_pose.metric(burunsat_calc_name,"all_bur_unsat_polars", tot_unsat_mval);
378  unbound_unsat = tot_unsat_mval.value();
379  TR << "Interface Unsat polar groups: " << bound_unsat - unbound_unsat << std::endl;
380 
381  //update answer:
382  if_metrics["I_sc"] = Isc;
383  if_metrics["I_bsa"] = unbound_sasa - bound_sasa;
384  if_metrics["I_hb"] = bound_hb - unbound_hb;
385  if_metrics["I_pack"] = bound_packstat - unbound_packstat;
386  if_metrics["I_unsat"] = bound_unsat - unbound_unsat;
387 
388  ///////////////// Per peptide residue calculations ///////////////////
389  pose.metric(sasa_calc_name, "residue_sasa" ,bound_sasa_per_res_mval);
390  pose.metric(hbond_calc_name,"residue_Hbonds",bound_hb_per_res_mval);
391  if (!flags_->is_ligand_present(pose)) {
392  pose.metric(packstat_calc_name,"residue_packstat",bound_packstat_per_res_mval);
393  }
394  pose.metric(burunsat_calc_name,"residue_bur_unsat_polars",bound_unsat_per_res_mval);
395 
396  unbound_pose.metric(sasa_calc_name, "residue_sasa" ,unbound_sasa_per_res_mval);
397  unbound_pose.metric(hbond_calc_name,"residue_Hbonds",unbound_hb_per_res_mval);
398  unbound_pose.metric(burunsat_calc_name,"residue_bur_unsat_polars",unbound_unsat_per_res_mval);
399 
400  for (int i=flags_->peptide_first_res();
401  i < flags_->peptide_first_res() + flags_->peptide_nres(); i++){
402  TR << i
403  << " bsa: " << unbound_sasa_per_res_mval.value()[i] - bound_sasa_per_res_mval.value()[i]
404  << " HB: " << bound_hb_per_res_mval.value()[i] - unbound_hb_per_res_mval.value()[i];
405  if (!flags_->is_ligand_present(pose)) {
406  TR << " pack: " << bound_packstat_per_res_mval.value()[i]; //- unbound_packstat_per_res_mval.value()[i]
407  }
408  TR << " unsat: " << bound_unsat_per_res_mval.value()[i] - unbound_unsat_per_res_mval.value()[i]
409  << std::endl;
410  }
411  return if_metrics;
412 }
413 
414 /////////////////////////////////////////
415 // Calculate peptide score with and w/o
416 // fa_ref sequence reference energy
417 /////////////////////////////////////////
418 void
420 ( core::pose::Pose const & pose, Real& pepScore, Real& pepScore_noref ) const {
421  for (int i=flags_->peptide_first_res(); i <= flags_->peptide_last_res(); ++i) {
422  using namespace core::scoring;
423  Real ienergy = pose.energies().residue_total_energy(i);
424  Real ifa_ref = pose.energies().residue_total_energies(i)[ref];
425  pepScore += ienergy;
426  pepScore_noref += ienergy - ifa_ref;
427  }
428 }
429 
430 
431 } // end namespace flexpep_docking
432 } // end namespace protocols