Rosetta 3.5
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
ddG.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/simple_moves/ddG.cc
11 /// @brief implementation of the ddG class for computing interface delta dGs
12 ///
13 ///
14 /// @author Sarel Fleishman (sarelf@u.washington.edu)
15 /// @author Sachko Honda (honda@apl.washington.edu)
16 /// Additional notes by Honda on 12/16/2012
17 /// When this mover is called with PB_elec (PB potential energy) in scorefxn,
18 /// it enables caching poses in two (bound/unbound) states so that subsequent calls can avoid
19 /// resolving the PDE over and over for the same conformation.
20 ///
21 /// See also core/scoring/methods/PoissonBoltzmannEnergy, core/scoring/PoissonBoltzmannPotential
22 ///
23 #include <core/types.hh>
24 
25 #include <core/scoring/Energies.hh>
29 
33 
36 
37 #include <core/pose/Pose.hh>
38 #include <core/pose/util.hh>
41 
46 
54 #include <protocols/jd2/Job.hh>
56 
57 #include <numeric/xyzVector.hh>
58 
59 #include <ObjexxFCL/format.hh>
60 
61 #include <utility/vector0.hh>
62 #include <utility/vector1.hh>
63 #include <utility/tag/Tag.hh>
64 #include <basic/Tracer.hh>
65 #include <basic/options/keys/pb_potential.OptionKeys.gen.hh>
66 
67 // C++ headers
68 #include <map>
69 #include <algorithm>
70 
71 //Auto Headers
72 #include <utility/excn/Exceptions.hh>
73 #include <boost/functional/hash.hpp>
74 
75 namespace protocols {
76 namespace simple_moves {
77 
80 
81 using basic::T;
82 using basic::Error;
83 using basic::Warning;
84 
85 static basic::Tracer TR( "protocols.protein_interface_design.movers.ddG" );
86 
88 {
89  return new ddG;
90 }
91 
93 {
94  return "ddG";
95 }
96 
98 {
99  return ddGCreator::mover_name();
100 }
101 
102 using namespace core;
103 using namespace protocols::simple_moves;
104 using namespace core::scoring;
105 
106 const Real ddG::DEFAULT_TRANSLATION_DISTANCE = 100.0; // A
107 
109  simple_moves::DesignRepackMover(ddGCreator::mover_name()),
110  bound_total_energy_(0.0),
111  unbound_total_energy_(0.0),
112  repeats_(0),
113  rb_jump_(0),
114  symmetry_(false),
115  per_residue_ddg_(false),
116  repack_(false),
117  relax_mover_( NULL ),
118  use_custom_task_(false),
119  repack_bound_(true),
120  relax_bound_(false),
121  pb_enabled_(false),
122  translate_by_(DEFAULT_TRANSLATION_DISTANCE)
123 {
124  bound_energies_.clear();
125  unbound_energies_.clear();
128 }
129 
131  core::Size const jump/*=1*/,
132  bool const symmetry /*=false*/ ) :
133  simple_moves::DesignRepackMover(ddGCreator::mover_name()),
134  bound_total_energy_(0.0),
135  unbound_total_energy_(0.0),
136  repeats_(1),
137  rb_jump_(jump),
138  symmetry_(symmetry),
139  per_residue_ddg_(false),
140  repack_(true),
141  relax_mover_( NULL ),
142  use_custom_task_(false),
143  repack_bound_(true),
144  relax_bound_(false),
145  pb_enabled_(false),
146  translate_by_(DEFAULT_TRANSLATION_DISTANCE)
147 {
148  scorefxn_ = new core::scoring::ScoreFunction( *scorefxn_in );
149 
150  bound_energies_.clear();
151  unbound_energies_.clear();
154 
155  // Determine if this PB enabled.
156  if( scorefxn_->get_weight(core::scoring::PB_elec) != 0.) {
157  // Set this to PB enabled
158  pb_enabled_ = true;
159  TR << "PB enabled" << std::endl;
160  }
161  else{
162  pb_enabled_ = false;
163  }
164 }
165 
167  core::Size const jump/*=1*/,
168  utility::vector1<core::Size> const & chain_ids,
169  bool const symmetry /*=false*/ ) :
170  simple_moves::DesignRepackMover(ddGCreator::mover_name()),
171  bound_total_energy_(0.0),
172  unbound_total_energy_(0.0),
173  repeats_(1),
174  rb_jump_(jump),
175  symmetry_(symmetry),
176  per_residue_ddg_(false),
177  repack_(true),
178  relax_mover_( NULL ),
179  use_custom_task_(false),
180  repack_bound_(true),
181  relax_bound_(false),
182  pb_enabled_(false),
183  translate_by_(DEFAULT_TRANSLATION_DISTANCE)
184 {
185  scorefxn_ = new core::scoring::ScoreFunction( *scorefxn_in );
186  chain_ids_ = chain_ids;
187 
188  bound_energies_.clear();
189  unbound_energies_.clear();
192 
193  // Determine if this PB enabled.
194  if( scorefxn_->get_weight(core::scoring::PB_elec) != 0.) {
195  // Set this to PB enabled
196  pb_enabled_ = true;
197  TR << "PB enabled" << std::endl;
198  }
199  else{
200  pb_enabled_ = false;
201  }
202 }
204  utility::tag::TagPtr const tag,
208  core::pose::Pose const& pose)
209 {
210  rb_jump_ = tag->getOption<core::Size>("jump", 1);
211  symmetry_ = tag->getOption<bool>("symmetry",0);
212  per_residue_ddg_ = tag->getOption<bool>("per_residue_ddg",0);
213  repack_ = tag->getOption<bool>("repack",0);
214  repeats_ = tag->getOption<Size>("repeats",1);
216  use_custom_task( tag->hasOption("task_operations") );
217  repack_bound_ = tag->getOption<bool>("repack_bound",1);
218  relax_bound_ = tag->getOption<bool>("relax_bound",0);
219  translate_by_ = tag->getOption<int>("translate_by", DEFAULT_TRANSLATION_DISTANCE);
220 
221  if(tag->hasOption("chains") && symmetry_)
222  {
223  throw utility::excn::EXCN_RosettaScriptsOption("you cannot specify multiple chains and use symmetry mode in the ddG mover at the same time right now. Sorry");
224  }
225 
226  if( ( tag->hasOption("chain_num") || tag->hasOption("chain_name") ) && tag->hasOption("jump"))
227  {
228  throw utility::excn::EXCN_RosettaScriptsOption("you can specify either chains or jump in the ddG mover, but not both");
229  }
230 
231  if(tag->hasOption("chain_num"))
232  {
233  chain_ids_ = utility::string_split(tag->getOption<std::string>("chain_num"),',',core::Size());
234  }
235 
236  if(tag->hasOption("chain_name"))
237  {
238  utility::vector1<std::string> chain_names = utility::string_split(tag->getOption<std::string>("chain_name"),',',std::string());
239  for(utility::vector1<std::string>::iterator chain_name_it = chain_names.begin(); chain_name_it != chain_names.end(); ++chain_name_it)
240  {
241  chain_ids_.push_back(core::pose::get_chain_id_from_chain(*chain_name_it,pose));
242  }
243  }
244 
245  if(std::find(chain_ids_.begin(),chain_ids_.end(),1) != chain_ids_.end())
246  {
247  throw utility::excn::EXCN_RosettaScriptsOption("You can't move the first chain. Moving chain 2 is the same as moving chain 1, so do that instead.");
248  }
249 
250  // Construct score function.
251  std::string const scorefxn_name( tag->getOption<std::string>( "scorefxn", "score12" ) );
252  scorefxn_ = new ScoreFunction( *(data.get< ScoreFunction * >( "scorefxns", scorefxn_name )) );
253 
254  // Determine if this PB enabled.
255  if( scorefxn_->get_weight(core::scoring::PB_elec) != 0.) {
256  // Set this to PB enabled
257  pb_enabled_ = true;
258  TR << "PB enabled. Translation distance = " << translate_by_ << " A" << std::endl;
259  if( translate_by_ > DEFAULT_TRANSLATION_DISTANCE ) {
260  TR.Warning << "Translation distance may be too large for PB-enabled scoring. Consider 100 (default) if you run out of memory: " << translate_by_ << std::endl;
261  TR.Warning.flush();
262  }
263  }
264  else{
265  pb_enabled_ = false;
266  }
267  TR.flush();
268 }
269 
271 
272 void ddG::apply(Pose & pose)
273 {
274  using namespace core::scoring::methods;
275  EnergyMethodOptions emoptions = scorefxn_->energy_method_options();
276 
277  if(per_residue_ddg_)
278  {
279  EnergyMethodOptionsOP energy_options(new core::scoring::methods::EnergyMethodOptions(scorefxn_->energy_method_options()));
280  energy_options->hbond_options().decompose_bb_hb_into_pair_energies(true);
281  scorefxn_->set_energy_method_options(*energy_options);
282 
283  }
284  Real average_ddg = 0.0;
285  std::map<Size, Real> average_per_residue_ddgs;
286 
287  for(Size repeat = 1; repeat <= repeats_; ++repeat)
288  {
289  // calculate() attaches pb-elec related cache to the pose, but shall not change the conformation.
290  calculate(pose);
291 
292  // Carry on the gathered PB energy info.
293  if( pb_cached_data_ != 0 ) {
294  pose.data().set(pose::datacache::CacheableDataType::PB_LIFETIME_CACHE, pb_cached_data_);
295  }
296 
297  average_ddg += sum_ddG();
298  report_ddG(TR);
299  if(per_residue_ddg_)
300  {
301  for(core::Size i = 1; i <= pose.n_residue();++i)
302  {
303  core::Real bound_energy = bound_per_residue_energies_[i];
304  core::Real unbound_energy = unbound_per_residue_energies_[i];
305  core::Real residue_ddg = bound_energy - unbound_energy;
306  if(average_per_residue_ddgs.find(i) == average_per_residue_ddgs.end())
307  {
308  average_per_residue_ddgs[i] = residue_ddg;
309  }else
310  {
311  average_per_residue_ddgs[i] += residue_ddg;
312  }
313  }
314  }
315  }
316 
317  average_ddg /= repeats_;
318  for(std::map<Size,Real>::iterator avg_it = average_per_residue_ddgs.begin(); avg_it != average_per_residue_ddgs.end();++avg_it)
319  {
320  avg_it->second /= repeats_;
321  }
322 
324  job->add_string_real_pair("ddg",average_ddg);
325  if (per_residue_ddg_)
326  {
327  for (core::Size i = 1; i <= pose.n_residue(); ++i) {
328  std::string residue_string(utility::to_string<core::Size>(i));
329  job->add_string_real_pair("residue_ddg_"+residue_string,average_per_residue_ddgs[i]);
330  }
331  }
332 }
333 
334 /// @details a private function for storing energy values
335 void
336 ddG::fill_energy_vector( pose::Pose const & pose, std::map< ScoreType, core::Real > & energy_map )
337 {
338  energy_map.clear();
339  using namespace core::scoring;
340  for ( int i=1; i<= n_score_types; ++i ) {
341  if ( (*scorefxn_)[ ScoreType(i) ] != 0.0 && ScoreType(i) != pro_close ) {
342  energy_map.insert( std::make_pair( ScoreType( i ), (*scorefxn_)[ ScoreType(i)] * pose.energies().total_energies()[ ScoreType( i ) ] ) );
343  }
344  }
345 }
346 
347 void ddG::fill_per_residue_energy_vector(pose::Pose const & pose, std::map<Size, Real> & energy_map)
348 {
349  energy_map.clear();
350  for(core::Size resid = 1; resid <= pose.total_residue(); ++resid)
351  {
352  core::Real energy = 0.0;
353  for (int st = 1; st <= n_score_types; ++st)
354  {
355  if( (*scorefxn_)[ScoreType(st)] != 0.0 && ScoreType(st) != pro_close)
356  {
357  energy += (*scorefxn_)[ScoreType(st)] * pose.energies().residue_total_energies(resid)[ScoreType(st)];
358  }
359  }
360  energy_map.insert(std::make_pair(resid,energy));
361  }
362 }
363 
364 /// @details output the ddG values
365 void
366 ddG::report_ddG( std::ostream & out ) const
367 {
368 
369  using ObjexxFCL::fmt::F;
370  using ObjexxFCL::fmt::LJ;
371  out << "-----------------------------------------\n";
372  out << " Scores Wghtd.Score\n";
373  out << "-----------------------------------------\n";
374  std::map< ScoreType, Real >::const_iterator unbound_it=unbound_energies_.begin();
375  for( std::map< ScoreType, Real >::const_iterator bound_it=bound_energies_.begin();
376  bound_it!=bound_energies_.end();
377  ++bound_it ) {
378  if( std::abs( unbound_it->second ) > 0.001 || std::abs( bound_it->second ) > 0.001 )
379  out << ' ' << LJ( 24, bound_it->first ) << ' ' << F( 9,3, bound_it->second - unbound_it->second )<<'\n';
380  ++unbound_it;
381  }
382  out << "-----------------------------------------\n";
383  out << "Sum ddg: "<< sum_ddG()<<std::endl;
384 }
385 
386 /// @details returns the total ddG
387 Real
389 {
390  Real sum_energy(0.0);
391 
392  std::map< ScoreType, Real >::const_iterator unbound_it=unbound_energies_.begin();
393  for( std::map< ScoreType, Real >::const_iterator bound_it=bound_energies_.begin();
394  bound_it!=bound_energies_.end();
395  ++bound_it ) {
396  sum_energy += bound_it->second - unbound_it->second;
397  ++unbound_it;
398  }
399  return sum_energy;
400 }
401 
402 ///
403 /// @brief compute the energy of the repacked complex in the bound and unbound states
404 /// @param pose_in The base pose.
405 /// @return Nothing, but the base pose's cache be augmented with extra cached data if the scorefunction
406 /// contains non-zero PB_elec term.
407 void
408 ddG::calculate( pose::Pose const & pose_original )
409 {
410  using namespace pack;
411  using namespace protocols::moves;
412  using namespace core::scoring::methods;
413 
414  // work on a copy, don't/can't modify the original comformation.
415  pose::Pose pose = pose_original;
416 
417  // Dummy state as default (<= pb_enabled_=false)
418  std::string original_state = "stateless";
419 
420  //----------------------------------
421  // Save the original state if pb
422  //----------------------------------
423  // The state is marked in pose's data-cache.
424  PBLifetimeCacheOP cached_data = 0;
425  core::scoring::methods::EnergyMethodOptions emoptions = scorefxn_->energy_method_options();
426 
427  // First see if this method is called as part of PB-electrostatic computation.
428  if( pb_enabled_ ) {
429  cached_data = static_cast< PBLifetimeCacheOP > (pose.data().get_ptr< PBLifetimeCache > ( pose::datacache::CacheableDataType::PB_LIFETIME_CACHE ));
430  runtime_assert( cached_data != 0 );
431  original_state = cached_data->get_energy_state();
432  }
433 
434  if ( core::pose::symmetry::is_symmetric( pose ) ) { //JBB 120423 changed from if (symmetry_)
435  symm_ddG( pose );
436  return;
437  }
438 
439  else if(!repack_)
440  {
441  no_repack_ddG(pose);
442  return;
443  }
444 
445  //---------------------------------
446  // Bound state
447  //---------------------------------
448  if( pb_enabled_ ) cached_data->set_energy_state(emoptions.pb_bound_tag());
449 
450  repack_partner1_ = true;
451  repack_partner2_ = true;
452  design_partner1_ = false;
453  design_partner2_ = false;
454 
455  //setup_packer_and_movemap( pose );
457  task_->initialize_from_command_line().or_include_current( true );
459  rpk.apply( pose, *task_ );
461  nodisulf.apply( pose, *task_ );
462  if(chain_ids_.size() > 0 )
463  {
464  //We want to translate each chain the same direction, though it doesnt matter much which one
466  protocols::toolbox::task_operations::RestrictToInterface rti( first_jump, 8.0 /*interface_distance_cutoff_*/ );
467  if(chain_ids_.size() > 1)
468  {
469  for(core::Size chain_index = 2; chain_index <= chain_ids_.size();++chain_index)
470  {
471  core::Size current_jump = core::pose::get_jump_id_from_chain_id(chain_ids_[chain_index],pose);
472  rti.add_jump(current_jump);
473  }
474  }
475  rti.apply(pose,*task_);
476  }
477  else
478  {
479  protocols::toolbox::task_operations::RestrictToInterface rti( rb_jump_, 8.0 /*interface_distance_cutoff_*/ );
480  rti.apply( pose, *task_ );
481  }
482 
483  if ( repack_bound() ) {
485  }
486  if ( relax_bound() ) {
487  if( relax_mover() )
488  relax_mover()->apply( pose );
489  }
490 
491  (*scorefxn_)( pose );
493  if(per_residue_ddg_)
494  {
496  }
497 
498  //---------------------------------
499  // Unbound state
500  //---------------------------------
501  if( pb_enabled_ ) cached_data->set_energy_state(emoptions.pb_unbound_tag());
502 
503  if(chain_ids_.size() > 0)
504  {
505  //We want to translate each chain the same direction, though it doesnt matter much which one
506  Vector translation_axis(1,0,0);
507  for(utility::vector1<core::Size>::const_iterator chain_it = chain_ids_.begin(); chain_it != chain_ids_.end();++chain_it)
508  {
509  core::Size current_chain_id = *chain_it;
510  core::Size current_jump_id = core::pose::get_jump_id_from_chain_id(current_chain_id,pose);
512  // Commented by honda: APBS blows up grid > 500. Just use the default just like bound-state.
513  translate->step_size( translate_by_ );
514  translate->trans_axis(translation_axis);
515  translate->apply( pose );
516  }
517  }else
518  {
520 
521  // Commented by honda: APBS blows up grid > 500. Just use the default just like bound-state.
522  translate->step_size( translate_by_ );
523  translate->apply( pose );
524  }
525 
527  if( relax_mover() )
528  relax_mover()->apply( pose );
529 
530  (*scorefxn_)( pose );
532  if(per_residue_ddg_)
533  {
535  }
536 
537  //----------------------------------
538  // Return to the original state
539  //----------------------------------
540  if( pb_enabled_ ) {
541  cached_data->set_energy_state( original_state );
542  pb_cached_data_ = cached_data;
543  }
544 }
545 
546 // @details compute the energy of a repacked symmetrical complex in bound and unbound states
547 void
548 ddG::symm_ddG( pose::Pose & pose_original )
549 {
550  using namespace pack;
551  using namespace protocols::moves;
552  using namespace core::scoring::methods;
553 
554  // work on a copy, don't/can't modify the original comformation.
555  pose::Pose pose = pose_original;
556 
557  // Dummy state as default (<= pb_enabled_=false)
558  std::string original_state = "stateless";
559 
560  //----------------------------------
561  // Save the original state if pb
562  //----------------------------------
563  // The state is marked in pose's data-cache.
564  PBLifetimeCacheOP cached_data = 0;
565  core::scoring::methods::EnergyMethodOptions emoptions = scorefxn_->energy_method_options();
566 
567  // First see if this method is called as part of PB-electrostatic computation.
568  if( pb_enabled_ ) {
569  cached_data = static_cast< PBLifetimeCacheOP > (pose.data().get_ptr< PBLifetimeCache > ( pose::datacache::CacheableDataType::PB_LIFETIME_CACHE ));
570  runtime_assert( cached_data != 0 );
571  original_state = cached_data->get_energy_state();
572  }
573 
574  // Check symmetry
575  assert( core::pose::symmetry::is_symmetric( pose ));
576  SymmetricConformation & symm_conf (
577  dynamic_cast<SymmetricConformation & > ( pose.conformation()) );
578 
579  std::map< Size, core::conformation::symmetry::SymDof > dofs ( symm_conf.Symmetry_Info()->get_dofs() );
580 
581  // convert to symmetric scorefunction
583 
584  //---------------------------------
585  // Bound state
586  //---------------------------------
587  if( pb_enabled_ ) cached_data->set_energy_state(emoptions.pb_bound_tag());
588 
589  //setup_packer_and_movemap( pose );
591  if ( use_custom_task() ) {
592  // Allows the user to define custom tasks that specify which residues
593  // are allowed to repack if RestrictToInterface doesn't work for them.
594  task_ = task_factory_->create_task_and_apply_taskoperations( pose );
595  } else {
596  task_->initialize_from_command_line().or_include_current( true );
598  rpk.apply( pose, *task_ );
600  nodisulf.apply( pose, *task_ );
601  protocols::toolbox::task_operations::RestrictToInterface rti( rb_jump_, 8.0 /*interface_distance_cutoff_*/ );
602  rti.apply( pose, *task_ );
603  }
604  if ( repack_bound() ) {
606  }
607  if ( relax_bound() ) {
608  if( relax_mover() )
609  relax_mover()->apply( pose );
610  }
611  (*scorefxn_)( pose );
613  if(per_residue_ddg_)
614  {
616  }
617 
618  //---------------------------------
619  // Unbound state
620  //---------------------------------
621  if( pb_enabled_ ) cached_data->set_energy_state( emoptions.pb_unbound_tag() );
622 
624  translate->step_size( translate_by_ );
625  translate->apply( pose );
627  if( relax_mover() )
628  relax_mover()->apply( pose );
629  (*scorefxn_)( pose );
631  if(per_residue_ddg_)
632  {
634  }
635 
636  //----------------------------------
637  // Return to the original state
638  //----------------------------------
639  if( pb_enabled_ ) {
640  cached_data->set_energy_state( original_state );
641  pb_cached_data_ = cached_data;
642  }
643 }
644 
645 void
646 ddG::no_repack_ddG(Pose & pose_original)
647 {
648  using namespace core::scoring::methods;
649 
650  // work on a copy, don't/can't modify the original comformation.
651  pose::Pose pose = pose_original;
652 
653  // Is PB-potential computation enabled?
654  bool pb_enabled_ = false;
655 
656  // Dummy state as default (<= pb_enabled_=false)
657  std::string original_state = "stateless";
658 
659  //----------------------------------
660  // Save the original state if pb
661  //----------------------------------
662  // The state is marked in pose's data-cache.
663  PBLifetimeCacheOP cached_data = 0;
664  core::scoring::methods::EnergyMethodOptions emoptions = scorefxn_->energy_method_options();
665 
666  // First see if this method is called as part of PB-electrostatic computation.
667  if( pb_enabled_ ) {
668  cached_data = static_cast< PBLifetimeCacheOP > (pose.data().get_ptr< PBLifetimeCache > ( pose::datacache::CacheableDataType::PB_LIFETIME_CACHE ));
669  runtime_assert( cached_data != 0 );
670  original_state = cached_data->get_energy_state();
671  }
672 
673  //---------------------------------
674  // Bound state
675  //---------------------------------
676  if( pb_enabled_ ) cached_data->set_energy_state( emoptions.pb_bound_tag() );
677 
678  (*scorefxn_)( pose );
680  if(per_residue_ddg_)
681  {
683  }
684 
685 
686  //---------------------------------
687  // Unbound state
688  //---------------------------------
689  if( pb_enabled_ ) cached_data->set_energy_state( emoptions.pb_unbound_tag() );
690 
691  if(chain_ids_.size() > 0 )
692  {
693  //We want to translate each chain the same direction, though it doesnt matter much which one
694  Vector translation_axis(1,0,0);
695 
696  for(utility::vector1<core::Size>::const_iterator chain_it = chain_ids_.begin(); chain_it != chain_ids_.end();++chain_it)
697  {
698  core::Size current_chain_id = *chain_it;
699  core::Size current_jump_id = core::pose::get_jump_id_from_chain_id(current_chain_id,pose);
701  translate->trans_axis(translation_axis);
702  translate->step_size( translate_by_ );
703  translate->apply( pose );
704  }
705 
706  }else
707  {
709  translate->step_size( translate_by_ );
710  translate->apply( pose );
711  }
712 
713  if( relax_mover() )
714  relax_mover()->apply( pose );
715  (*scorefxn_)( pose );
717  if(per_residue_ddg_)
718  {
720  }
721 
722  //----------------------------------
723  // Return to the original state
724  //----------------------------------
725  if( pb_enabled_ ) {
726  cached_data->set_energy_state( original_state );
727  pb_cached_data_ = cached_data;
728  }
729 }
730 
732 ddG::get_name() const {
733  return "ddG";
734 }
735 
737 ddG::clone() const {
738  return (protocols::moves::MoverOP) new ddG( *this );
739 }
740 
741 } //movers
742 } //protocols