Rosetta 3.5
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
RotamerConstraint.cc
Go to the documentation of this file.
1 // -*- mode:c++;tab-width:2;indent-tabs-mode:t;show-trailing-whitespace:t;rm-trailing-spaces:t -*-
2 // vi: set ts=2 noet:
3 //
4 // (c) Copyright Rosetta Commons Member Institutions.
5 // (c) This file is part of the Rosetta software suite and is made available under license.
6 // (c) The Rosetta software is developed by the contributing members of the Rosetta Commons.
7 // (c) For more information, see http://www.rosettacommons.org. Questions about this can be
8 // (c) addressed to University of Washington UW TechTransfer, email: license@u.washington.edu.
9 
10 /// @file core/scoring/constraints/RotamerConstraint.cc
11 ///
12 /// @brief
13 /// @author Ian W. Davis
14 
15 
17 
18 // AUTO-REMOVED #include <core/io/pdb/pose_io.hh>
19 #include <basic/options/option.hh>
22 // AUTO-REMOVED #include <core/scoring/constraints/ConstraintSet.hh>
24 #include <basic/Tracer.hh>
25 
26 
27 // option key includes
28 
29 #include <basic/options/keys/packing.OptionKeys.gen.hh>
30 
31 //Auto Headers
32 #include <core/io/pdb/file_data.hh>
34 #include <core/pose/Pose.hh>
37 #include <utility/vector1.hh>
38 
39 
40 
41 namespace core {
42 namespace pack {
43 namespace dunbrack {
44 
45 using namespace scoring;
46 using namespace scoring::constraints;
47 
48 static basic::Tracer TR("core.pack.dunbrack.RotamerConstraint");
49 
50 
52 {
53  using namespace basic::options;
54  using namespace core::pose;
55  if( !option[ OptionKeys::packing::unboundrot ].active() ) return;
56 
57  static core::pose::PoseCOPs unboundrot_poses;
58  if( unboundrot_poses.empty() ) {
59  for(Size i = 1; i <= option[ OptionKeys::packing::unboundrot ]().size(); ++i) {
60  std::string filename = option[ OptionKeys::packing::unboundrot ]()[i].name();
61  TR << "Adding 'unbound' rotamers from " << filename << std::endl;
62  PoseOP pose = new Pose();
63  //core::import_pose::pose_from_pdb( *pose, filename );
65  unboundrot_poses.push_back( pose );
66  }
67  }
68 
69  load_unboundrot(pose, unboundrot_poses);
70 }
71 
72 void load_unboundrot(pose::Pose & pose, core::pose::PoseCOPs const & unboundrot_poses)
73 {
74  if( unboundrot_poses.empty() ) return; // guaranteed at least one pose now
75 
76  using namespace std;
77  for(Size rsd_num = 1; rsd_num <= pose.total_residue(); ++rsd_num) {
78  // Each constraint can contain only one ResidueType, so we have to sort them out here.
79  // We should get any scoring overlap since ResidueTypes are mutually exclusive.
80  map< string, RotamerConstraintOP > by_res_type;
81  for(Size pose_num = 1; pose_num <= unboundrot_poses.size(); ++pose_num) {
82  if( rsd_num > unboundrot_poses[pose_num]->total_residue() ) continue;
83  conformation::Residue const & rsd = unboundrot_poses[pose_num]->residue(rsd_num);
84  if( !rsd.is_protein() ) {
85  // Can't determine rotamer number for anything but protein.
86  TR << "Can't use " << rsd.type().name() << " " << rsd_num << " for residue constraint -- protein only." << std::endl;
87  continue;
88  }
89  if( core::pack::dunbrack::RotamerLibrary::get_instance().get_rsd_library( rsd.type() )() == 0 ) continue; // no point in creating constraint
90  if( by_res_type.find( rsd.type().name() ) == by_res_type.end() ) { // first one, create constraint
91  TR.Debug << "Creating rotamer constraint for " << rsd.type().name() << " at " << rsd_num << std::endl;
92  RotamerConstraintOP constraint = new RotamerConstraint( *unboundrot_poses[pose_num], rsd_num );
93  pose.add_constraint( constraint );
94  by_res_type[ rsd.type().name() ] = constraint;
95  } else { // subsequent one, just add residue
96  RotamerConstraintOP constraint = by_res_type[ rsd.type().name() ];
97  constraint->add_residue( unboundrot_poses[pose_num]->residue(rsd_num) );
98  }
99  }
100  }
101 }
102 
104  pose::Pose const & pose,
105  Size seqpos
106 ):
107  Constraint( core::scoring::fa_dun ), // most like a Dunbrack rotamer energy, and should share the same weight
108  seqpos_( seqpos ),
109  rsd_type_name_( pose.residue_type(seqpos).name() ),
110  atom_ids_(),
111  rotlib_( core::pack::dunbrack::RotamerLibrary::get_instance().get_rsd_library( pose.residue_type(seqpos) ) ), // may be NULL
112  favored_rotamers_(),
113  favored_rotamer_numbers_()
114 {
115  // Depends on ~ all heavy atoms (all chis + phi and psi)
116  // Could cause problems if this position mutates to something with fewer atoms?
117  conformation::Residue const & rsd( pose.residue(seqpos_) );
118  for(Size i = 1, i_end = rsd.nheavyatoms(); i <= i_end; ++i) {
119  atom_ids_.push_back(AtomID( i, seqpos_ )); // atom, rsd
120  }
121 
122  // Note: Although the Dunbrack score depends on phi & psi, it shouldn't need to depend on atoms of other residues,
123  // as the phi and psi angles are internalized within a residue to speed things.
124 
125  add_residue( rsd );
126 }
127 
128 
130 
131 
132 void
134 {
135  assert( rsd.type().name() == rsd_type_name_ );
136  favored_rotamers_.push_back( rsd.chi() );
139  favored_rotamer_numbers_.push_back( rot );
140 }
141 
142 
143 Size
145 {
146  return atom_ids_.size();
147 }
148 
149 
150 id::AtomID const &
151 RotamerConstraint::atom( Size const index ) const
152 {
153  return atom_ids_[index];
154 }
155 
156 
157 // Calculates a score for this constraint using XYZ_Func, and puts the UNWEIGHTED score into
158 // emap. Although the current set of weights currently is provided, Constraint objects
159 // should put unweighted scores into emap.
160 void
162  XYZ_Func const & xyz_func,
163  EnergyMap const & weights,
164  EnergyMap & emap
165 ) const
166 {
167  if( rotlib_() == NULL ) return;
168  if( weights[ this->score_type() ] == 0 ) return; // what's the point?
169 
170  conformation::Residue const & rsd( xyz_func.residue(seqpos_) );
171  if( rsd.type().name() != rsd_type_name_ ) return; // residue types must match
172 
175  for(Size i = 1, i_end = favored_rotamer_numbers_.size(); i <= i_end; ++i) {
176  if( rot == favored_rotamer_numbers_[i] ) {
178  Real const best_rotE = rotlib_->best_rotamer_energy(rsd, false /* => global min */, scratch);
179  Real const this_rotE = rotlib_->best_rotamer_energy(rsd, true /* => local min */, scratch);
180  assert( best_rotE <= this_rotE );
181  TR << "rotamer constraint active for " << seqpos_ << " thisE = " << this_rotE << " bestE = " << best_rotE << " dE = " << ( best_rotE - this_rotE ) << std::endl;
182  emap[ this->score_type() ] += ( best_rotE - this_rotE );
183  return; // quit once we find a match
184  }
185  }
186  // no match found, don't adjust score for this rotamer
187 }
188 
189 
190 void
192  AtomID const & ,//atom,
193  XYZ_Func const &,
194  Vector & ,//F1,
195  Vector & ,//F2,
196  EnergyMap const & //weights
197 ) const
198 {
199  // Do nothing.
200  // Derivative of this restraint is effectively zero (because it's constant
201  // within each rotamer well), so we just "add zero" to F1 and F2.
202 }
203 
204 
205 void RotamerConstraint::show( std::ostream & out ) const
206 {
207  out << type() << ": " << seqpos_ << " " << rsd_type_name_ << " " << favored_rotamer_numbers_.size();
208  for(Size i = 1, i_end = favored_rotamer_numbers_.size(); i <= i_end; ++i) {
209  out << ",";
210  for(Size j = 1, j_end = favored_rotamer_numbers_[i].size(); j <= j_end; ++j) {
211  out << " " << favored_rotamer_numbers_[i][j];
212  }
213  }
214  out << std::endl;
215 }
216 
217 
218 } // namespace constraints
219 } // namespace scoring
220 } // namespace core