Rosetta 3.5
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
Pose.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/pose/Pose.cc
11 /// @brief Pose class
12 /// @author Phil Bradley
13 /// @author Modified by Sergey Lyskov
14 
15 // Unit headers
16 #include <core/pose/Pose.hh>
17 
18 // package headers
19 #include <core/pose/PDBInfo.hh>
24 
25 // Project headers
29 
30 #include <core/id/TorsionID.hh>
31 #include <core/id/types.hh>
32 #include <core/scoring/Energies.hh>
33 // AUTO-REMOVED #include <core/scoring/ScoreFunctionInfo.hh>
35 #include <core/io/pdb/file_data.hh>
37 #include <basic/datacache/BasicDataCache.hh>
38 // AUTO-REMOVED #include <basic/MetricValue.hh>
39 #include <basic/prof.hh>
41 // AUTO-REMOVED #include <core/io/pdb/pose_io.hh>
42 
43 #include <core/chemical/AA.hh>
44 // AUTO-REMOVED #include <core/chemical/ResidueTypeSet.hh>
45 
46 #include <basic/options/option.hh>
47 #include <basic/options/keys/in.OptionKeys.gen.hh>
48 
49 #include <utility/vector1.hh>
50 
51 #include <algorithm>
52 #include <iostream>
53 #include <sstream>
54 #include <fstream>
55 //#include <core/pack/dunbrack/RotamerLibrary.fwd.hh>
56 // AUTO-REMOVED #include <core/scoring/mm/MMBondAngleResidueTypeParamSet.fwd.hh>
57 //#include <core/optimization/MinimizerMap.fwd.hh>
58 #include <basic/options/keys/OptionKeys.hh>
59 
60 //Auto Headers
61 //#include <core/pack/rotamer_set/RotamerSet.fwd.hh>
62 //#include <core/pack/task/PackerTask.fwd.hh>
63 #include <core/pose/util.hh>
67 //#include <core/pack/dunbrack/RotamerLibrary.fwd.hh>
68 
69 #include <utility/vector0.hh>
70 #include <numeric/xyz.functions.hh>
71 
72 #include <core/id/NamedAtomID.hh>
73 
74 //Auto Headers
79 
80 
81 
82 
83 namespace core {
84 namespace pose {
85 
86 /// @details default init function
87 void Pose::init(void)
88 {
89 
91 
92  // have the Pose observe it's Conformation for XYZ changes
93  // we discard the Link because we own the Conformation
94  conformation_->attach_xyz_obs( &Pose::on_conf_xyz_change, this );
95 
97  energies_->set_owner( this );
98 
100 
102 
104  metrics_->attach_to( *this );
105 
106 }
107 
108 
109 /// @details default constructor
111  pdb_info_( NULL ),
112  constraint_set_( 0 )
113 {
114  init();
115 }
116 
117 
118 /// @details construc pose using info from PDB file
119 //Pose::Pose( std::string const & pdb_file ) :
120 // pdb_info_( NULL ),
121 // constraint_set_( 0 )
122 //{
123 // init();
124 // core::import_pose::pose_from_pdb(*this, pdb_file);
125 //}
126 
127 
128 /// @details destructor -- > kill data on the heap
130 {
131  //std::cout << "Pose dstor" << std::endl;
133  clear();
134 }
135 
136 /// @brief copy constructor
137 Pose::Pose( Pose const & src ) :
138  ReferenceCount ( src )
139 {
140  *this = src;
141 }
142 
143 /// @brief partial copy constructor
144 Pose::Pose( Pose const & src, Size begin, Size const end):
145  pdb_info_( NULL ),
146  constraint_set_( 0 )
147 {
148  init();
149  utility::vector1< core::Size > residue_indices;
150  for(; begin <= end; ++begin){
151  residue_indices.push_back(begin);
152  }
153  core::io::pdb::pose_from_pose(*this, src, residue_indices);
154 }
155 
156 /// @brief copy assignment
157 Pose &
158 Pose::operator=( Pose const & src )
159 {
160  PROF_START ( basic::POSE_COPY );
161 
162  ConformationOP old_conf = conformation_; // track for observer transfer
163 
164  if ( conformation_ && conformation_->same_type_as_me( *src.conformation_, true ) ) {
165  (*conformation_) = (*src.conformation_);
166  } else {
167  conformation_ = src.conformation_->clone();
168  conformation_->attach_xyz_obs( &Pose::on_conf_xyz_change, this );
169  }
170 
171  if ( energies_ && energies_->same_type_as_me( *src.energies_ ) ) {
172  (*energies_) = (*src.energies_);
173  } else {
174  energies_ = src.energies_->clone();
175  energies_->set_owner( this );
176  }
177 
179  *data_cache_ = *(src.data_cache_);
180 
183 
184  this->pdb_info( src.pdb_info_ );
185 
187  metrics_->attach_to( *this );
188 
189  if( constraint_set_ ) constraint_set_->detach_from_conformation();
190 
191  if ( src.constraint_set_ ) {
192  constraint_set_ = src.constraint_set_->clone();
193  constraint_set_->attach_to_conformation( conformation_.get() );
194  } else {
195  constraint_set_ = 0;
196  }
197 
198  // transfer remaining observers that honor the Conformation::TRANSFER
199  // event after everything else is done
200  if ( old_conf ) {
201  conformation_->receive_observers_from( *old_conf );
202  old_conf.reset_to_null(); // force clear
203  }
204 
205  PROF_STOP ( basic::POSE_COPY );
206 
207  return *this;
208 }
209 
210 kinematics::FoldTree const &
212 {
213  return conformation_->fold_tree();
214 }
215 
216 void
217 Pose::fold_tree( kinematics::FoldTree const & fold_tree_in )
218 {
219  conformation_->fold_tree( fold_tree_in );
220 }
221 
222 /// @brief get the atom_tree
223 kinematics::AtomTree const &
225 {
226  return conformation_->atom_tree();
227 }
228 
229 int
230 Pose::chain( Size const seqpos ) const
231 {
232  PyAssert( (seqpos<=total_residue()), "Pose::chain( Size const seqpos ): variable seqpos is out of range!" );
233  return residue( seqpos ).chain();
234 }
235 
236 /// @details Note that we do not clone the input conformation -- we just take it directly. This could be unsafe (?)
237 /// but it's more efficient. Maybe we want to switch to cloning... Of course we already hand out nonconst refs to
238 /// our conformation, which is a little unsafe anyhow.
239 /// @warning Classes observing the Pose's old conformation will not automatically
240 /// be re-attached/listening to the new Conformation. Please pay special attention
241 /// if you have a CacheableObserver in the ObserverCache that listens to
242 /// a Pose's Conformation. The prior PDBInfo, ConstraintSet and Energies will be
243 /// cleared as well.
244 void
246 {
247 
248  /// drop stuff
249  pdb_info_.reset_to_null();
250  constraint_set_.reset_to_null();
251  observer_cache_->detach();
252 
253  // initialize new
255  energies_->set_owner( this );
256 
258 
260  metrics_->attach_to( *this );
261 
262  /// clone and reassign the pointer
263  conformation_ = new_conformation->clone();
264  conformation_->attach_xyz_obs( &Pose::on_conf_xyz_change, this );
265 
266  /* OPERATIONS AFTER THIS POINT NEED TO HAPPEN AFTER THE CONFORMATION
267  HAS BEEN SWAPPED */
268 
269 }
270 
271 /// @details This function allow us to attach an Energies object from a derived class. What are the proper
272 /// checks to do for this? This should probably be a protected function, since we do not want this function
273 /// to be used regularly
274 void
276 {
277  energies_ = energies->clone();
278  // Set the owner of the new energies object
279  energies_->set_owner( this );
280 }
281 
282 /// @ details splits the current pose into several poses containing only a single chain each.
283 ///
286 {
287  utility::vector1<PoseOP> singlechain_poses;
288 
289  if ( conformation_->num_chains() == 1 ) {
290  singlechain_poses.push_back( new Pose(*this) );
291  return singlechain_poses;
292  }
293 
294  for ( Size i = 1; i <= conformation_->num_chains(); ++i ) {
295  core::pose::PoseOP chain_pose;
296  Size chain_begin, chain_end, delete_begin, delete_end;
297 
298  chain_pose = new Pose(*this);
299  chain_begin = chain_pose->conformation().chain_begin( i );
300  chain_end = chain_pose->conformation().chain_end( i );
301 
302  // if this is the first chain, delete chain_end to the end of the pose
303  if (chain_begin == 1) {
304  delete_begin = chain_end + 1;
305  delete_end = chain_pose->total_residue();
306  chain_pose->conformation().delete_residue_range_slow( delete_begin, delete_end );
307  }
308  // if this is the last chain, delete the start of the pose to chain_begin
309  else if ( chain_end == chain_pose->total_residue() ) {
310  delete_begin = 1;
311  delete_end = chain_begin - 1;
312  chain_pose->conformation().delete_residue_range_slow( delete_begin, delete_end );
313  }
314  // otherwise, make two deletes around the chain of interest
315  else {
316  delete_begin = 1;
317  delete_end = chain_begin - 1;
318  chain_pose->conformation().delete_residue_range_slow( delete_begin, delete_end );
319  // just deleted residues --> renumbering pose, so need to reset deletion mask
320  delete_begin = chain_end - chain_begin + 2;
321  delete_end = chain_pose->total_residue();
322  chain_pose->conformation().delete_residue_range_slow( delete_begin, delete_end );
323  }
324 
325  // disulfides
326  using basic::options::option;
327  using namespace basic::options::OptionKeys;
328  if ( option[ in::detect_disulf ].user() ?
329  option[ in::detect_disulf ]() : // detect_disulf true
330  chain_pose->is_fullatom() ) // detect_disulf default but fa pose
331  {
332  chain_pose->conformation().detect_disulfides();
333  }
334 
335  // restore broken pdb_info to new pose ~ Labonte
336  chain_pose->pdb_info()->obsolete(false);
337 
338  singlechain_poses.push_back( chain_pose );
339  }
340  return singlechain_poses;
341 }
342 
343 /// @details. new pose from a set of residues
344 Pose
345 Pose::split_by_chain(Size const chain_id) const{
346  core::Size const begin = conformation().chain_begin(chain_id);
347  core::Size const end = conformation().chain_end(chain_id);
348  return Pose(*this, begin, end);
349 }
350 
351 
352 // TODO: Move to util.cc.
353 /// @details This method updates the pose chain IDs to match the chain IDs
354 /// found in pdb_info(). In some applications, it is more intuitive to change
355 /// pdb chain ID letters than it is to change pose chain IDs. This method
356 /// adds chain endings between pdb chains and redrives the pose chain IDs.
357 /// Currently, disconnected segments with the same pdb chain ID character are
358 /// treated as separate pose chains, e.g., it is possible for pose chains 1,
359 /// 3, and 5 to all be chain X. In the future, I will add a flag to force a
360 /// one-to-one correspondence between the two chain designations, e.g., if
361 /// residues 6 through 10 are chain B and residues 1 through 5 AND residues 11
362 /// through 15 are chain A, then the pose will be reordered to place all res-
363 /// idues with the same pdb chain ID into a single pose chain. (This is how it
364 /// works when a pose is loaded from a pdb file.) I personally have needed
365 /// use of both functionalities. I have chosen to create this as a separate
366 /// method, rather than a part of a change_pdb_chain_ID_of_range(), to avoid
367 /// multiple calls to Conformation.rederive_chain_ids(). Thus, this method
368 /// should be called once after all modifications to pdb_info() have been
369 /// made. ~ Labonte
370 ///
371 /// See also:
372 /// PDBInfo.chain()
373 /// PDBInfo.set_resinfo()
374 /// Pose.split_by_chain()
375 /// Conformation.rederive_chain_IDs()
376 /// Conformation.rederive_chain_endings()
377 void
379 {
380  // Declare a vector for storing new (between-residue) chain endings.
381  utility::vector1<Size> new_endings;
382 
383  char last_pdb_chain = pdb_info_->chain(1);
384  char current_pdb_chain;
385 
386  for (Size i = 1; i <= conformation_->size(); ++i) {
387  current_pdb_chain = pdb_info_->chain(i);
388  if (current_pdb_chain != last_pdb_chain) {
389  new_endings.push_back(i - 1);
390  last_pdb_chain = current_pdb_chain;
391  }
392 
393  // (chain_endings() includes a call to Conformer.rederive_chain_IDs.)
394  conformation_->chain_endings(new_endings);
395  }
396 }
397 
398 
399 /// APL Illegal.
400 ///conformation::ResidueOPs::iterator Pose::res_begin() { return conformation_->res_begin(); }
401 ///conformation::ResidueOPs::iterator Pose::res_end () { return conformation_->res_end (); }
402 
403 void
404 Pose::metric( std::string const & calculator_name, std::string const & key, basic::MetricValueBase & val ) const
405 { metrics_->get(calculator_name, key, val, *this); return; }
406 
408 Pose::print_metric( std::string const & calculator_name, std::string const & key ) const
409 { return metrics_->print(calculator_name, key, *this); }
410 
411 void
413  conformation::Residue const & new_rsd,
414  Size const jump_anchor_residue,
415  std::string const& jump_anchor_atom, // = "",
416  std::string const& jump_root_atom, // = "",
417  bool const start_new_chain //= false
418 )
419 {
420  //PyAssert( (jump_anchor_residue>0) && (jump_anchor_residue<total_residue()), "Pose::append_residue_by_jump( ...Size const jump_anchor_residue... ): variable jump_anchor_residue is out of range!" ); // check later: may be fixed in conformation
421  energies_->clear(); // TEMPORARY
422  conformation_->append_residue_by_jump( new_rsd, jump_anchor_residue, jump_anchor_atom, jump_root_atom, start_new_chain );
423 }
424 
425 void
427  conformation::Residue const & new_rsd,
428  bool const build_ideal_geometry, // = false,
429  int const connection, // = 0,
430  Size const anchor_residue, // = 0,
431  int const anchor_connection, // = 0,
432  bool const start_new_chain, // = false
433  bool const lookup_bond_length // = false
434 )
435 {
436  //PyAssert( (anchor_residue>0) && (anchor_residue<=total_residue()), "Pose::append_residue_by_bond( ...Size const anchor_residue... ): variable anchor_residue is out of range!" ); // check later: may be fixed in conformation
437  energies_->clear(); // TEMPORARY
438  conformation_->append_residue_by_bond( new_rsd, build_ideal_geometry, connection, anchor_residue, anchor_connection, start_new_chain, lookup_bond_length);
439 }
440 
441 void
443  Residue const & new_rsd_in,
444  Size const seqpos, // desired seqpos of new_rsd
445  Size anchor_pos, // in the current sequence numbering, ie before insertion of seqpos
446  std::string const& anchor_atomno, // = "",
447  std::string const& root_atomno // = ""
448 )
449 {
450  //PyAssert( (seqpos>0), "Pose::insert_residue_by_jump( ...Size const seqpos... ): variable seqpos is out of range!" ); // check later:
451  PyAssert( (anchor_pos<=total_residue()), "Pose::insert_residue_by_jump( ...Size anchor_pos... ): variable anchor_pos is out of range!" ); // check later:
452  energies_->clear(); // TEMPORARY
453  conformation_->insert_residue_by_jump( new_rsd_in, seqpos, anchor_pos, anchor_atomno, root_atomno );
454 }
455 
456 void
458  Size const seqpos,
459  Residue const & new_rsd_in,
460  bool const orient_backbone
461 )
462 {
463  PyAssert( (seqpos<=total_residue()), "Pose::replace_residue( ...Size const seqpos... ): variable seqpos is out of range!" ); // check later: may become unecessary
464  conformation_->replace_residue( seqpos, new_rsd_in, orient_backbone );
465 }
466 
467 
468 void
470  int const seqpos,
471  Residue const & new_rsd_in,
472  utility::vector1< std::pair< std::string, std::string > > const & atom_pairs
473 )
474 {
475  PyAssert( (seqpos<=total_residue()), "Pose::replace_residue( ...Size const seqpos... ): variable seqpos is out of range!" ); // check later: may become unecessary
476  conformation_->replace_residue( seqpos, new_rsd_in, atom_pairs );
477 }
478 
479 void
481  Residue const & new_rsd,
482  Size const seqpos,
483  bool const build_ideal_geometry
484 )
485 {
486  PyAssert( (seqpos<=total_residue()), "Pose::append_polymer_residue_after_seqpos( ...Size const seqpos... ): variable seqpos is out of range!" ); // check later: may become unecessary
487  energies_->clear(); // TEMPORARY
488  conformation_->append_polymer_residue_after_seqpos( new_rsd, seqpos, build_ideal_geometry );
489 }
490 
491 
492 void
494  Residue const & new_rsd,
495  Size const seqpos,
496  bool const build_ideal_geometry
497 )
498 {
499  PyAssert( (seqpos<=total_residue()), "Pose::prepend_polymer_residue_before_seqpos( ...Size const seqpos... ): variable seqpos is out of range!" ); // check later:
500  energies_->clear(); // TEMPORARY
501  conformation_->prepend_polymer_residue_before_seqpos( new_rsd, seqpos, build_ideal_geometry );
502 }
503 
504 void
506 {
507  PyAssert( (seqpos<=total_residue()), "Pose::delete_polymer_residue( Size const seqpos ): variable seqpos is out of range!" );
508  energies_->clear(); // TEMPORARY
509  conformation_->delete_polymer_residue( seqpos );
510 }
511 
512 
513 void
515  Size const size,
516  Pose const & src,
517  Size const begin,
518  Size const src_begin
519 )
520 {
521  conformation_->copy_segment( size, src.conformation(), begin, src_begin );
522  // now copy any other data
523 }
524 
525 
526 
527 Size
529 {
530  return conformation_->size();
531 }
532 
533 Size
535 {
536  return conformation_->size();
537 }
538 
539 bool
540 Pose::empty() const
541 {
542  return conformation_->empty();
543 }
544 
545 Size
547 {
548  return conformation_->fold_tree().num_jump();
549 }
550 
552 Pose::aa( Size const seqpos ) const
553 {
554  PyAssert( (seqpos<=total_residue()), "Pose::aa( Size const seqpos ): variable seqpos is out of range!" );
555  return conformation_->aa( seqpos );
556 }
557 
558 char
559 Pose::secstruct( Size const seqpos ) const
560 {
561  PyAssert( (seqpos<=total_residue()), "Pose::secstruct( Size const seqpos ): variable seqpos is out of range!" );
562  return conformation_->secstruct(seqpos);
563 }
564 
567  std::string ss="";
568  for ( Size i = 1; i <= total_residue(); i++ ) {
569  ss += secstruct( i );
570  }
571  return ss;
572 }
573 
574 void
575 Pose::set_secstruct( Size const seqpos, char const setting )
576 {
577  PyAssert( (seqpos<=total_residue()), "Pose::set_secstruct( Size const seqpos , char const setting ): variable seqpos is out of range!" );
578  // check variable "setting" to ensure it is logical?
579  conformation_->set_secstruct( seqpos, setting );
580 }
581 
582 
583 // Sequence accessors
586 {
587  std::string seq;
588  for ( Size i=1; i<= conformation_->size(); ++i ) {
589  seq += residue(i).name1();
590  }
591  return seq;
592 }
593 
595 Pose::annotated_sequence( bool show_all_variants ) const
596 {
597  using namespace core::chemical;
598 
599  std::string seq;
600  for ( Size i=1; i<= conformation_->size(); ++i ) {
601  char c = residue(i).name1();
602  seq += c;
603  if (
605  && ( show_all_variants || residue(i).name().substr(0,3) != "CYD")
606  ) {
607  seq = seq + '[' + residue(i).name() + ']';
608  }
609  }
610  return seq;
611 }
612 
614 Pose::chain_sequence(core::Size const chain_in) const
615 {
616  using namespace std;
617 
618  assert(chain_in <= conformation_->num_chains());
619  PyAssert((chain_in <= conformation_->num_chains()),
620  "Pose::chain_sequence(core::Size const chain_in): variable chain_in is out of range!");
621 
622  stringstream seq(stringstream::out);
623 
624  Size begin = conformation_->chain_begin(chain_in);
625  Size end = conformation_->chain_end(chain_in);
626 
627  if (!residue(begin).is_carbohydrate()) {
628  for (Size i = begin; i <= end; ++i) {
629  seq << residue(i).name1();
630  }
631  } else /*is carbohydrate*/ {
632  // Carbohydrate sequences are listed in the opposite direction as they are numbered.
633  for (Size i = end; i >= begin; --i) {
634  seq << residue(i).carbohydrate_info()->short_name();
635  if (i != begin) {
636  seq << "(";
637  seq << residue(i).carbohydrate_info()->anomeric_carbon();
638  }
639  }
640  }
641  return seq.str();
642 }
643 
644 
645 // Residue at position seqpos
646 Pose::Residue const &
648  Size const seqpos
649 ) const
650 {
651  PyAssert( (seqpos<=total_residue()), "Pose::residue( Size const seqpos ): variable seqpos is out of range!" );
652  return conformation_->residue( seqpos );
653 }
654 
655 chemical::ResidueType const &
657  Size const seqpos
658 ) const
659 {
660  PyAssert( (seqpos<=total_residue()), "Pose::residue_type( Size const seqpos ): variable seqpos is out of range!" );
661  return conformation_->residue_type( seqpos );
662 }
663 
664 
665 // backbone torsions
666 // peptides and saccharides
667 
668 /// @details For proteins, phi is defined as C(n-1)-N(n)-CA(n)-C(n).\n
669 /// For aldopyranoses, phi is defined as O5(n)-C1(n)-OX(n-1)-CX(n-1),
670 /// where X is the position of the glycosidic linkage.\n
671 /// For aldofuranoses, phi is defined as O4(n)-C1(n)-OX(n-1)-CX(n-1).\n
672 /// For 2-ketopyranoses, phi is defined as O6(n)-C2(n)-OX(n-1)-CX(n-1).\n
673 /// For 2-ketofuranoses, phi is defined as O5(n)-C2(n)-OX(n-1)-CX(n-1).\n
674 /// Et cetera...
675 Real
676 Pose::phi( Size const seqpos ) const
677 {
678  using namespace id;
679 
680  assert( residue_type(seqpos).is_protein() || residue_type(seqpos).is_carbohydrate() );
681  PyAssert( (seqpos<=total_residue()),
682  "Pose::phi( Size const seqpos ): variable seqpos is out of range!" );
683  PyAssert( (residue_type(seqpos).is_protein() || residue_type(seqpos).is_carbohydrate()),
684  "Pose::phi( Size const seqpos ): residue seqpos is not part of a protein or carbohydrate!" );
685  if (residue_type(seqpos).is_protein()) {
686  return residue(seqpos).mainchain_torsion(phi_torsion);
687  } else /*is carbohydrate*/ {
688  return carbohydrates::calculate_carbohydrate_phi(*this, seqpos);
689  }
690 }
691 
692 /// @details For proteins, phi is defined as C(n-1)-N(n)-CA(n)-C(n).\n
693 /// For aldopyranoses, phi is defined as O5(n)-C1(n)-OX(n-1)-CX(n-1),
694 /// where X is the position of the glycosidic linkage.\n
695 /// For aldofuranoses, phi is defined as O4(n)-C1(n)-OX(n-1)-CX(n-1).\n
696 /// For 2-ketopyranoses, phi is defined as O6(n)-C2(n)-OX(n-1)-CX(n-1).\n
697 /// For 2-ketofuranoses, phi is defined as O5(n)-C2(n)-OX(n-1)-CX(n-1).\n
698 /// Et cetera...
699 void
700 Pose::set_phi( Size const seqpos, Real const setting )
701 {
702  using namespace id;
703 
704  assert( residue_type(seqpos).is_protein() || residue_type(seqpos).is_carbohydrate() );
705  PyAssert( (seqpos<=total_residue()),
706  "Pose::set_phi( Size const seqpos, Real const setting ): variable seqpos is out of range!" );
707  PyAssert( (residue_type(seqpos).is_protein() || residue_type(seqpos).is_carbohydrate()),
708  "Pose::set_phi( Size const seqpos , Real const setting ): residue seqpos is not part of a protein or carbohydrate!" );
709  if (residue_type(seqpos).is_protein()) {
710  conformation_->set_torsion( TorsionID( seqpos, BB, phi_torsion ), setting );
711  } else /*is carbohydrate*/ {
712  // The torsion angle BB X+1 (from the previous residue) is the correct bond but has the incorrect reference atoms,
713  // so get the angle offset.
714  uint x = residue_type(seqpos - 1).carbohydrate_info()->mainchain_glycosidic_bond_acceptor();
716  conformation_->set_torsion(TorsionID(seqpos - 1, BB, x + 1), setting - offset);
717  }
718 }
719 
720 /// @details For proteins, psi is defined as N(n)-CA(n)-C(n)-N(n+1).\n
721 /// For aldoses, psi is defined as C1(n)-OX(n-1)-CX(n-1)-CX-1(n-1), where X is the position of the glycosidic linkage.
722 /// For 2-ketoses (uloses), replace C1 with C2, etc.
723 Real
724 Pose::psi( Size const seqpos ) const
725 {
726  using namespace id;
727 
728  assert( residue_type(seqpos).is_protein() || residue_type(seqpos).is_carbohydrate() );
729  PyAssert( (seqpos<=total_residue()),
730  "Pose::psi( Size const seqpos ): variable seqpos is out of range!" );
731  PyAssert( (residue_type(seqpos).is_protein() || residue_type(seqpos).is_carbohydrate()),
732  "Pose::psi( Size const seqpos ): residue seqpos is not part of a protein or carbohydrate!" );
733  if (residue_type(seqpos).is_protein()) {
734  return residue(seqpos).mainchain_torsion(psi_torsion);
735  } else /*is carbohydrate*/ {
736  // To match IUPAC definitions, the value from the previous residue is returned here.
737  // See CarbohydrateInfo::determine_polymer_connections() and glycosidic_linkage_id() for more info.
738  PyAssert((seqpos != 1),
739  "Pose::psi( Size const seqpos ): variable seqpos is out of range for carbohydrates!");
740  TorsionType id_type = residue_type(seqpos - 1).carbohydrate_info()->glycosidic_linkage_id(psi_torsion).first;
741  Size id_num = residue_type(seqpos - 1).carbohydrate_info()->glycosidic_linkage_id(psi_torsion).second;
742  return torsion(TorsionID(seqpos - 1, id_type, id_num));
743  }
744 }
745 
746 /// @details For proteins, psi is defined as N(n)-CA(n)-C(n)-N(n+1).\n
747 /// For aldoses, psi is defined as C1(n)-OX(n-1)-CX(n-1)-CX-1(n-1), where X is the position of the glycosidic linkage.
748 /// For 2-ketoses (uloses), replace C1 with C2, etc.
749 void
750 Pose::set_psi( Size const seqpos, Real const setting )
751 {
752  using namespace id;
753 
754  assert( residue_type(seqpos).is_protein() || residue_type(seqpos).is_carbohydrate() );
755  PyAssert( (seqpos<=total_residue()),
756  "Pose::set_psi( Size const seqpos, Real const setting ): variable seqpos is out of range!" );
757  PyAssert( (residue_type(seqpos).is_protein() || residue_type(seqpos).is_carbohydrate()),
758  "Pose::set_psi( Size const seqpos , Real const setting ): residue seqpos is not part of a protein or carbohydrate!" );
759  if (residue_type(seqpos).is_protein()) {
760  conformation_->set_torsion( TorsionID( seqpos, BB, psi_torsion ), setting);
761  } else /*is carbohydrate*/ {
762  // To match IUPAC definitions, the value from the previous residue is set here.
763  // See CarbohydrateInfo::determine_polymer_connections() and glycosidic_linkage_id() for more info.
764  PyAssert((seqpos != 1),
765  "Pose::set_psi( Size const seqpos, Real const setting ): variable seqpos is out of range for carbohydrates!");
766  TorsionType id_type = residue_type(seqpos - 1).carbohydrate_info()->glycosidic_linkage_id(psi_torsion).first;
767  Size id_num = residue_type(seqpos - 1).carbohydrate_info()->glycosidic_linkage_id(psi_torsion).second;
768  conformation_->set_torsion(TorsionID(seqpos - 1, id_type, id_num), setting);
769  }
770 }
771 
772 /// @details For proteins, omega is defined as CA(n)-C(n)-N(n+1)-CA(n+1).
773 /// For carbohydrates glycosylated at an exocyclic position,
774 /// omega of residue n is defined as OX(n-1)-CX(n-1)-CX-1(n-1)-OX-1(n-1),
775 /// where X is the position of the glycosidic linkage. (Note that every atom
776 /// defining this torsion comes from the previous residue!)
777 Real Pose::omega( Size const seqpos ) const
778 {
779  using namespace id;
780 
781  assert( residue_type(seqpos).is_protein() || residue_type(seqpos).is_carbohydrate() );
782  PyAssert( (seqpos<=total_residue()),
783  "Pose::omega( Size const seqpos ): variable seqpos is out of range!" );
784  PyAssert( (residue_type(seqpos).is_protein() || residue_type(seqpos).is_carbohydrate() ),
785  "Pose::omega( Size const seqpos ): residue seqpos is not part of a protein or carbohydrate!" );
786  if (residue_type(seqpos).is_protein()) {
787  return residue(seqpos).mainchain_torsion(omega_torsion);
788  } else /*is carbohydrate*/ {
789  // To match IUPAC definitions, the value from the previous residue is returned here.
790  // See CarbohydrateInfo::determine_polymer_connections() and glycosidic_linkage_id() for more info.
791  PyAssert((seqpos != 1),
792  "Pose::omega( Size const seqpos ): variable seqpos is out of range for carbohydrates!");
793  PyAssert((residue_type(seqpos - 1).carbohydrate_info()->has_exocyclic_linkage()),
794  "Pose::omega( Size const seqpos ): residue seqpos - 1 does not have an exocyclic glycosidic linkage!");
795  TorsionType id_type = residue_type(seqpos - 1).carbohydrate_info()->glycosidic_linkage_id(omega_torsion).first;
796  Size id_num = residue_type(seqpos - 1).carbohydrate_info()->glycosidic_linkage_id(omega_torsion).second;
797  return torsion(TorsionID(seqpos - 1, id_type, id_num));
798  }
799 }
800 
801 /// @details For proteins, omega is defined as CA(n)-C(n)-N(n+1)-CA(n+1).
802 /// For carbohydrates glycosylated at an exocyclic position,
803 /// omega of residue n is defined as OX(n-1)-CX(n-1)-CX-1(n-1)-OX-1(n-1),
804 /// where X is the position of the glycosidic linkage. (Note that every atom
805 /// defining this torsion comes from the previous residue!)
806 void
807 Pose::set_omega( Size const seqpos, Real const setting )
808 {
809  using namespace id;
810 
811  assert( residue_type(seqpos).is_protein() || residue_type(seqpos).is_carbohydrate() );
812  PyAssert( (seqpos<=total_residue()),
813  "Pose::set_omega( Size const seqpos, Real const setting ): variable seqpos is out of range!" );
814  PyAssert( (residue_type(seqpos).is_protein() || residue_type(seqpos).is_carbohydrate() ),
815  "Pose::set_omega( Size const seqpos , Real const setting ): "
816  "residue seqpos is not part of a protein or carbohydrate!" );
817  if (residue_type(seqpos).is_protein()) {
818  conformation_->set_torsion( TorsionID( seqpos, BB, omega_torsion ), setting);
819  } else /*is carbohydrate*/ {
820  // To match IUPAC definitions, the value from the previous residue is returned here.
821  // See CarbohydrateInfo::determine_polymer_connections() and glycosidic_linkage_id() for more info.
822  PyAssert((seqpos != 1),
823  "Pose::set_omega( Size const seqpos, Real const setting ): "
824  "variable seqpos is out of range for carbohydrates!");
825  PyAssert((residue_type(seqpos - 1).carbohydrate_info()->has_exocyclic_linkage()),
826  "Pose::set_omega( Size const seqpos, Real const setting ): "
827  "residue seqpos - 1 does not have an exocyclic glycosidic linkage!");
828  TorsionType id_type = residue_type(seqpos - 1).carbohydrate_info()->glycosidic_linkage_id(omega_torsion).first;
829  Size id_num = residue_type(seqpos - 1).carbohydrate_info()->glycosidic_linkage_id(omega_torsion).second;
830  conformation_->set_torsion(TorsionID(seqpos - 1, id_type, id_num), setting);
831  }
832 }
833 
834 // nucleic acids
835 
836 ///
837 Real
838 Pose::alpha( Size const seqpos ) const{
839  assert( residue_type( seqpos ).is_NA() );
840  PyAssert( (seqpos<=total_residue()), "Pose::alpha( Size const seqpos ): variable seqpos is out of range!" );
841  PyAssert( (residue_type(seqpos).is_NA()), "Pose::alpha( Size const seqpos ): residue seqpos is not part of a Nucleic Acid!" );
842  return torsion( id::TorsionID( seqpos, id::BB, 1 ) );
843 }
844 
845 ///
846 void
847 Pose::set_alpha( Size const seqpos, Real const setting )
848 {
849  assert( residue_type( seqpos ).is_NA() );
850  PyAssert( (seqpos<=total_residue()), "Pose::set_alpha( Size const seqpos, Real const setting ): variable seqpos is out of range!" );
851  PyAssert( (residue_type(seqpos).is_NA()), "Pose::set_alpha( Size const seqpos , Real const setting ): residue seqpos is not part of a Nucleic Acid!" );
852  conformation_->set_torsion( TorsionID( seqpos, id::BB, 1 ), setting );
853 }
854 
855 ///
856 Real
857 Pose::beta( Size const seqpos ) const{
858  assert( residue_type( seqpos ).is_NA() );
859  PyAssert( (seqpos<=total_residue()), "Pose::beta( Size const seqpos ): variable seqpos is out of range!" );
860  PyAssert( (residue_type(seqpos).is_NA()), "Pose::beta( Size const seqpos ): residue seqpos is not part of a Nucleic Acid!" );
861  return torsion( id::TorsionID( seqpos, id::BB, 2 ) );
862 }
863 
864 ///
865 void
866 Pose::set_beta( Size const seqpos, Real const setting )
867 {
868  assert( residue_type( seqpos ).is_NA() );
869  PyAssert( (seqpos<=total_residue()), "Pose::set_beta( Size const seqpos, Real const setting ): variable seqpos is out of range!" );
870  PyAssert( (residue_type(seqpos).is_NA()), "Pose::set_beta( Size const seqpos , Real const setting ): residue seqpos is not part of a Nucleic Acid!" );
871  conformation_->set_torsion( TorsionID( seqpos, id::BB, 2 ), setting );
872 }
873 
874 ///
875 Real
876 Pose::gamma( Size const seqpos ) const{
877  assert( residue_type( seqpos ).is_NA() );
878  PyAssert( (seqpos<=total_residue()), "Pose::gamma( Size const seqpos ): variable seqpos is out of range!" );
879  PyAssert( (residue_type(seqpos).is_NA()), "Pose::gamma( Size const seqpos ): residue seqpos is not part of a Nucleic Acid!" );
880  return torsion( id::TorsionID( seqpos, id::BB, 3 ) );
881 }
882 
883 ///
884 void
885 Pose::set_gamma( Size const seqpos, Real const setting )
886 {
887  assert( residue_type( seqpos ).is_NA() );
888  PyAssert( (seqpos<=total_residue()), "Pose::set_gamma( Size const seqpos, Real const setting ): variable seqpos is out of range!" );
889  PyAssert( (residue_type(seqpos).is_NA()), "Pose::set_gamma( Size const seqpos , Real const setting ): residue seqpos is not part of a Nucleic Acid!" );
890  conformation_->set_torsion( TorsionID( seqpos, id::BB, 3 ), setting );
891 }
892 
893 ///
894 Real
895 Pose::delta( Size const seqpos ) const{
896  assert( residue_type( seqpos ).is_NA() );
897  PyAssert( (seqpos<=total_residue()), "Pose::delta( Size const seqpos ): variable seqpos is out of range!" );
898  PyAssert( (residue_type(seqpos).is_NA()), "Pose::delta( Size const seqpos ): residue seqpos is not part of a Nucleic Acid!" );
899  return torsion( id::TorsionID( seqpos, id::BB, 4 ) );
900 }
901 
902 ///
903 void
904 Pose::set_delta( Size const seqpos, Real const setting )
905 {
906  assert( residue_type( seqpos ).is_NA() );
907  PyAssert( (seqpos<=total_residue()), "Pose::set_delta( Size const seqpos, Real const setting ): variable seqpos is out of range!" );
908  PyAssert( (residue_type(seqpos).is_NA()), "Pose::set_delta( Size const seqpos , Real const setting ): residue seqpos is not part of a Nucleic Acid!" );
909  conformation_->set_torsion( TorsionID( seqpos, id::BB, 4 ), setting );
910 }
911 
912 ///
913 Real
914 Pose::epsilon( Size const seqpos ) const{
915  assert( residue_type( seqpos ).is_NA() );
916  PyAssert( (seqpos<=total_residue()), "Pose::epsilon( Size const seqpos ): variable seqpos is out of range!" );
917  PyAssert( (residue_type(seqpos).is_NA()), "Pose::epsilon( Size const seqpos ): residue seqpos is not part of a Nucleic Acid!" );
918  return torsion( id::TorsionID( seqpos, id::BB, 5 ) );
919 }
920 
921  ///
922 void
923 Pose::set_epsilon( Size const seqpos, Real const setting )
924 {
925  assert( residue_type( seqpos ).is_NA() );
926  PyAssert( (seqpos<=total_residue()), "Pose::set_epsilon( Size const seqpos, Real const setting ): variable seqpos is out of range!" );
927  PyAssert( (residue_type(seqpos).is_NA()), "Pose::set_epsilon( Size const seqpos , Real const setting ): residue seqpos is not part of a Nucleic Acid!" );
928  conformation_->set_torsion( TorsionID( seqpos, id::BB, 5 ), setting );
929 }
930 
931 ///
932 Real
933 Pose::zeta( Size const seqpos ) const{
934  assert( residue_type( seqpos ).is_NA() );
935  PyAssert( (seqpos<=total_residue()), "Pose::zeta( Size const seqpos ): variable seqpos is out of range!" );
936  PyAssert( (residue_type(seqpos).is_NA()), "Pose::zeta( Size const seqpos ): residue seqpos is not part of a Nucleic Acid!" );
937  return torsion( id::TorsionID( seqpos, id::BB, 6 ) );
938 }
939 
940 ///
941 void
942 Pose::set_zeta( Size const seqpos, Real const setting )
943 {
944  assert( residue_type( seqpos ).is_NA() );
945  PyAssert( (seqpos<=total_residue()), "Pose::set_zeta( Size const seqpos, Real const setting ): variable seqpos is out of range!" );
946  PyAssert( (residue_type(seqpos).is_NA()), "Pose::set_zeta( Size const seqpos , Real const setting ): residue seqpos is not part of a Nucleic Acid!" );
947  conformation_->set_torsion( TorsionID( seqpos, id::BB, 6 ), setting );
948 }
949 
950 // sidechain torsions
951 // peptides and saccharides
952 
953 ///
954 Real
956  int const chino,
957  Size const seqpos
958 ) const
959 {
960  PyAssert( (seqpos<=total_residue()), "Pose::chi( int const chino , Size const seqpos ): variable seqpos is out of range!" );
961  PyAssert( (residue_type(seqpos).is_protein() || residue_type(seqpos).is_carbohydrate() ),
962  "Pose::chi( int const chino , Size const seqpos ): residue seqpos is not part of a protein or carbohydrate!" );
963  PyAssert( (chino>0) && (chino<=residue(seqpos).nchi()), "Pose::chi( int const chino , Size const seqpos ): variable chino innappropriate for this residue!" );
964  return residue( seqpos ).chi( chino );
965 }
966 
967 ///
968 void
970  int const chino,
971  Size const seqpos,
972  Real const setting
973 )
974 {
975  PyAssert( (seqpos<=total_residue()), "Pose::set_chi( int const chino , Size const seqpos ): variable seqpos is out of range!" );
976  PyAssert( (residue_type(seqpos).is_protein() || residue_type(seqpos).is_carbohydrate() ),
977  "Pose::set_chi( int const chino , Size const seqpos , Real const setting ): residue seqpos is not part of a protein or carbohydrate!" );
978  PyAssert( (chino>0) && (chino<=residue(seqpos).nchi()), "Pose::set_chi( int const chino , Size const seqpos ): variable chino innappropriate for this residue!" );
979  conformation_->set_torsion( TorsionID(seqpos, id::CHI, chino), setting);
980 }
981 
982 // nucleic acids
983 
984 ///
985 Real
986 Pose::chi( Size const seqpos ) const{
987  assert( residue_type( seqpos ).is_NA() );
988  PyAssert( (seqpos<=total_residue()), "Pose::chi( Size const seqpos ): variable seqpos is out of range!" );
989  PyAssert( (residue_type(seqpos).is_NA()), "Pose::chi( Size const seqpos ): residue seqpos is not part of a Nucleic Acid!" );
990  return torsion( id::TorsionID( seqpos, id::CHI, 1 ) );
991 }
992 
993 ///
994 void
995 Pose::set_chi( Size const seqpos, Real const setting )
996 {
997  assert( residue_type( seqpos ).is_NA() );
998  PyAssert( (seqpos<=total_residue()), "Pose::set_chi( Size const seqpos, Real const setting ): variable seqpos is out of range!" );
999  PyAssert( (residue_type(seqpos).is_NA()), "Pose::set_chi( Size const seqpos , Real const setting ): residue seqpos is not part of a Nucleic Acid!" );
1000  conformation_->set_torsion( TorsionID( seqpos, id::CHI, 1 ), setting );
1001 }
1002 
1003 
1004 /////////////////////////////////////////////////////////////////////////////
1005 // generic torsion-angle access
1006 
1007 /// @brief get the torsion angle identified by id
1008 Real
1009 Pose::torsion( TorsionID const & id ) const
1010 {
1011  return conformation_->torsion( id );
1012 }
1013 
1014 /// @brief set the torsion angle identified by id
1015 void
1016 Pose::set_torsion( TorsionID const & id, Real const setting )
1017 {
1018  conformation_->set_torsion( id, setting );
1019 }
1020 
1021 
1022 /////////////////////////////////////////////////////////////////////////////
1023 // jumps
1024 
1025 ///
1026 void
1028  int const jump_number,
1029  const kinematics::Jump & new_jump
1030 )
1031 {
1032  conformation_->set_jump( jump_number, new_jump );
1033 }
1034 
1035 ///
1036 void
1038  int const jump_number,
1039  const kinematics::Jump & new_jump
1040 )
1041 {
1042  conformation_->set_jump_now( jump_number, new_jump );
1043 }
1044 
1045 ///
1046 kinematics::Jump const &
1047 Pose::jump( int const jump_number ) const
1048 {
1049  return conformation_->jump( jump_number );
1050 }
1051 
1052 ///
1053 void
1055  AtomID const & id,
1056  const kinematics::Jump & new_jump
1057 )
1058 {
1059  conformation_->set_jump( id, new_jump );
1060 }
1061 
1062 ///
1063 kinematics::Jump const &
1064 Pose::jump( AtomID const & id ) const
1065 {
1066  return conformation_->jump( id );
1067 }
1068 
1069 
1070 ///////////////////////////////////////////////////////////////////////////
1071 // access atomtree dof's
1072 
1073 /// get the value of the atomtree degree of freedom (DOF)
1074 Real
1075 Pose::dof( DOF_ID const & id ) const
1076 {
1077  return conformation_->dof( id );
1078 }
1079 
1080 
1081 /// set the value of the atomtree degree of freedom (DOF)
1082 void
1083 Pose::set_dof( DOF_ID const & id, Real const setting )
1084 {
1085  conformation_->set_dof( id, setting );
1086 }
1087 
1088 bool
1090  DOF_ID const & did
1091 ) const
1092 {
1093  if( Size(did.rsd()) > total_residue() || did.rsd() < 1 ) return false;
1094  if( Size(did.atomno()) > residue(did.rsd()).natoms() || did.atomno() < 1 ) return false;
1095  if( id::PHI == did.type() || id::THETA == did.type() || id::D == did.type() )
1096  if( conformation_->atom_tree().atom(did.atom_id()).is_jump() ) return false;
1097  // TODO SHEFFLER MAKE THIS RIGHT!!!!!
1098  return true;
1099 }
1100 
1101 
1102 /// get the location of an atom
1103 PointPosition const &
1104 Pose::xyz( AtomID const & id ) const
1105 {
1106  return conformation_->xyz( id );
1107 }
1108 
1109 /// get the location of an atom
1110 PointPosition const &
1111 Pose::xyz( NamedAtomID const & id ) const
1112 {
1113  return conformation_->residue(id.rsd()).xyz(id.atom());
1114 }
1115 
1116 /// set the location of an atom
1117 void
1118 Pose::set_xyz( AtomID const & id, PointPosition const & point )
1119 {
1120  conformation_->set_xyz( id, point );
1121 }
1122 
1123 /// set the location of an atom
1124 void
1126  NamedAtomID const & id,
1127  PointPosition const & point
1128 )
1129 {
1130  conformation_->set_xyz( named_atom_id_to_atom_id(id, *this), point );
1131 }
1132 
1133 /// set the locations of a vector of atoms
1134 void
1136 {
1137  conformation_->batch_set_xyz( ids, points );
1138 }
1139 
1140 
1141 /// get the locations of a vector of atoms
1142 void
1144 {
1145  conformation_->batch_get_xyz( ids, points );
1146 }
1147 
1150  id::NamedStubID const& id
1151 )
1152 {
1153  return conformation_->stub_from_id( named_stub_id_to_stub_id( id, *this ) );
1154 }
1155 
1156 void
1158 {
1159 
1160  PointPosition cog(0,0,0);
1161 
1162  Size count=0;
1163  for( Size ir = 1; ir <= total_residue(); ir++){
1164  for( Size at = 1; at <= residue( ir ).natoms(); at++){
1165  cog += xyz( AtomID( at, ir ) );
1166  count++;
1167  }
1168  }
1169 
1170  //std::cout << cog.x() << std::endl;
1171  cog /= (Real) count;
1172 
1173  //std::cout << cog.x() << std::endl;
1174 
1175  for( Size ir = 1; ir <= total_residue(); ir++){
1176  for( Size at = 1; at <= residue( ir ).natoms(); at++){
1177  set_xyz( AtomID( at, ir ), xyz( AtomID( at, ir )) - cog );
1178  }
1179  }
1180 }
1181 
1182 ///////////////////////////////////////////////////////////////////////////////
1183 /// @details transfers domain map information into the Energies object, and then
1184 /// resets the domain map information from the Conformation object
1185 void
1187 {
1188  runtime_assert( total_residue() != 0 ); // Avoid crash on empty Pose (e.g. if PDB occupancy is all zero)
1189  residue( total_residue() ); // completely unnecessary temporary hack to force refold if nec.
1190 
1191  if ( conformation_->structure_moved() ) {
1192  energies_->structure_has_moved( total_residue() );
1193  conformation_->reset_structure_moved();
1194  } else if ( energies_->residue_neighbors_updated() ) {
1195  return;
1196  }
1197 
1198  // figure out what's changed since the residue neighbor update
1199  kinematics::DomainMap domain_map( total_residue() );
1200  conformation_->update_domain_map( domain_map );
1201 
1202  energies_->update_residue_neighbors( domain_map, *this );
1203  if ( energies_->discard_conformation_domain_map() ) conformation_->reset_move_data();
1204 }
1205 
1206 ///////////////////////////////////////////////////////////////////////////////
1207 ///@details called by the ScoreFunction at the start of scoring. If the score
1208 /// function has changed since the last round of scoring, then cached energies
1209 /// may have become invalidated -- the Energies object makes that decision.
1210 void
1212  scoring::ScoreFunction const & sfxn
1213 )
1214 {
1215  // notify of any structure changes
1216  if ( conformation_->structure_moved() ) {
1217  conformation_->reset_structure_moved();
1218  energies_->structure_has_moved( total_residue() );
1219  }
1220 
1221  energies_->scoring_begin( sfxn, *this );
1222  // figure out what's changed since the last score evaluation
1223  /// and update the Energies object
1225 }
1226 
1227 void
1229 {
1230  // reset the data that describes what has moved
1231  //conformation_->reset_move_data();
1232  energies_->scoring_end( scorefxn );
1233  notify_energy_obs( EnergyEvent( this ) );
1234 }
1235 
1236 /// @brief called by PairEPotential
1237 void
1239 {
1240  conformation_->update_actcoords();
1241 }
1242 
1243 void
1245 {
1246  conformation_->update_actcoord( resid );
1247 }
1248 
1249 void
1251 {
1252  conformation_->update_orbital_coords( resid );
1253 }
1254 
1255 
1256 /// @brief Applies a transform of the form Rx + v, where R is a rotation
1257 /// matrix, V is a vector, and x is the original position in xyz space.
1258 void
1260  numeric::xyzMatrix< Real > const & R,
1261  Vector const & v
1262 ) {
1263  for ( Size i = 1; i <= total_residue(); ++i ) {
1264  for ( Size j = 1; j <= residue_type(i).natoms(); ++j ) {
1265  AtomID id( j, i );
1266  set_xyz( id, R * xyz(id) + v );
1267  //apply_transform_Rx_plus_v( R, v );
1268  }
1269  }
1270 }
1271 
1272 void
1274 {
1275  conformation_->clear();
1276  energies_->clear();
1277  constraint_set_ = 0;
1278  metrics_->clear();
1279  data_cache_->clear();
1280  observer_cache_->clear();
1281  pdb_info( NULL ); // will check for existence, remove observers, etc
1282 }
1283 
1284 ///////////////////////////////////////////////////////////////////////////////
1285 /// @details save pose data to file with supplied file_name
1286 ///
1287 bool
1288 Pose::dump_pdb(std::string const &file_name, std::string const & tag) const
1289 {
1290  return core::io::pdb::FileData::dump_pdb(*this, file_name, tag);
1291 }
1292 
1293 /// @brief Dump a pdbfile with some score info at the end.
1294 void
1296  std::string const &file_name,
1297  scoring::ScoreFunction const & scorefxn,
1298  std::string const & tag
1299 ) {
1300  Real const total_score( scorefxn( *this ) );
1301  /// Now handled automatically. scorefxn.accumulate_residue_total_energies( *this );
1302  std::ofstream out( file_name.c_str() );
1303  core::io::pdb::FileData::dump_pdb( *this, out, tag );
1304  // verbose output
1305  out << "END\n";
1307  for ( Size i=1; i<= total_residue(); ++i ) secstruct += conformation_->secstruct(i);
1308  out << "SS: " << secstruct << '\n';
1309  out << "SCORE_INFO:\n";
1310  out << "TOTAL_SCORE: " << total_score << '\n';
1311  scoring::EnergyMap const & wts( scorefxn.weights() );
1312  out << "WTS: " << wts.show_nonzero() << '\n';
1313  out << "TOTAL_WTD: " << this->energies().total_energies().weighted_string_of( wts ) << '\n';
1314  for ( Size i=1; i<= total_residue(); ++i ) {
1315  out << "RSD_WTD: " << i << ' ' << this->energies().residue_total_energies( i ).weighted_string_of( wts ) << '\n';
1316  }
1317  scorefxn.show( out );
1318  out.close();
1319 }
1320 
1321 void Pose::dump_pdb(std::ostream & out, std::string const & tag) const
1322 {
1323  return core::io::pdb::FileData::dump_pdb(*this, out, tag);
1324 }
1325 
1326 /// @brief for writing a specified subset of residues in pdb format
1327 void
1329  std::ostream & out,
1330  utility::vector1< Size > const & residue_indices,
1331  std::string const & tag
1332 ) const
1333 {
1334  return core::io::pdb::FileData::dump_pdb( *this, out, residue_indices, tag );
1335 }
1336 
1337 
1340 {
1341  if ( constraint_set_ == 0 ) {
1342  return new scoring::constraints::ConstraintSet; // create an empty constraint set
1343  }
1344  return constraint_set_;
1345 }
1346 
1349 {
1350  energies_->clear();
1351  if ( constraint_set_ == 0 ) {
1352  constraint_set_ = new scoring::constraints::ConstraintSet; // create an empty constraint set the first time it's asked for
1353  constraint_set_->attach_to_conformation( conformation_.get() );
1354  }
1355  scoring::constraints::ConstraintCOP new_cst( cst->clone() );
1356  constraint_set_->add_constraint( new_cst );
1357  return( new_cst );
1358 }
1359 
1362 {
1363  energies_->clear();
1364  if ( constraint_set_ == 0 ) {
1365  constraint_set_ = new scoring::constraints::ConstraintSet; // create an empty constraint set the first time it's asked for
1366  constraint_set_->attach_to_conformation( conformation_.get() );
1367  }
1368  using namespace scoring::constraints;
1369  ConstraintCOPs new_csts;
1370  for( ConstraintCOPs::const_iterator cst_it = csts.begin(); cst_it != csts.end(); ++cst_it )
1371  new_csts.push_back( (*cst_it)->clone() );
1372  constraint_set_->add_constraints( new_csts );
1373  return( new_csts );
1374 }
1375 
1376 bool
1379  bool object_comparison )
1380 {
1381  if ( constraint_set_ == 0 ) return false;
1382  energies_->clear();
1383  return constraint_set_->remove_constraint(cst, object_comparison);
1384 }
1385 
1386 bool
1389  bool object_comparison )
1390 {
1391  if ( constraint_set_ == 0 ) return false;
1392  energies_->clear();
1393  return constraint_set_->remove_constraints(csts, object_comparison);
1394 }
1395 
1396 bool
1398  if ( constraint_set_ == 0 ) return false;
1399  energies_->clear();
1400  constraint_set_->clear();
1401  return true;
1402 }
1403 
1404 void
1406 {
1407  energies_->clear();
1408 
1409  if( constraint_set_ != 0 ) constraint_set_->detach_from_conformation();
1410 
1411  if( constraint_set != 0 ){
1412  constraint_set_ = constraint_set->clone();
1413  constraint_set_->attach_to_conformation( conformation_.get() );
1414  }
1416 }
1417 
1419  energies_->clear();
1420 
1421  if( constraint_set_ != 0 ) constraint_set_->detach_from_conformation();
1422 
1423  if( pose.constraint_set_ != 0 ){
1424  constraint_set_ = pose.constraint_set_->clone();
1425  constraint_set_->attach_to_conformation( conformation_.get() );
1426  }
1427  else constraint_set_ = pose.constraint_set_;
1428 }
1429 
1430 
1431 //////////////////////////////// PDBInfo methods /////////////////////////////////////
1432 
1433 
1434 /// @brief get pdb info (const)
1435 /// @return NULL if no PDBInfo instance exists, the pdb info instance otherwise
1436 PDBInfoCOP
1438 {
1439  assert( pdb_info_ ? pdb_info_->nres() == total_residue() : true );
1440  return pdb_info_;
1441 }
1442 
1443 /// @brief get pdb info
1444 /// @return NULL if no PDBInfo instance exists, the pdb info instance otherwise
1445 PDBInfoOP
1447 {
1448  assert( pdb_info_ ? pdb_info_->nres() == total_residue() : true );
1449  return pdb_info_;
1450 }
1451 
1452 /// @brief copy new pdb info into this Pose
1453 /// @param[in] new_info the new pdb info to copy, pass NULL if you want to zero
1454 /// the existence of pdb info inside this Pose
1455 /// @return the prior pdb info instance
1456 PDBInfoOP
1458 {
1459  if ( pdb_info_ ) {
1460  pdb_info_->detach_from();
1461  }
1462 
1463  PDBInfoOP prior_pdb_info = pdb_info_;
1464 
1465  if ( new_info ) {
1466  pdb_info_ = new PDBInfo( *new_info ); // make a copy
1467  pdb_info_->attach_to( *conformation_ );
1468  } else {
1469  pdb_info_.reset_to_null();
1470  }
1471 
1472  assert( pdb_info_ ? pdb_info_->nres() == total_residue() : true );
1473 
1474  return prior_pdb_info;
1475 }
1476 
1477 bool Pose::is_fullatom() const {
1478  return conformation_->is_fullatom();
1479 }
1480 
1481 bool Pose::is_centroid() const {
1482  return conformation_->is_centroid();
1483 }
1484 
1485 /// @brief notify DestructionEvent observers
1486 /// @remarks called only upon destruction of the Pose
1487 void
1489  destruction_obs_hub_( e );
1490 }
1491 
1492 
1493 /// @brief notify GeneralEvent observers
1494 /// @remarks should only be called when there are no other suitable event types
1495 /// since specific event notifications will automatically fire a GeneralEvent signal
1496 void
1498  general_obs_hub_( e );
1499 }
1500 
1501 
1502 /// @brief notify EnergyEvent observers
1503 /// @param e the event
1504 /// @param fire_general fire a GeneralEvent afterwards? default true
1505 void
1506 Pose::notify_energy_obs( EnergyEvent const & e, bool const fire_general ) {
1507  energy_obs_hub_( e );
1508  if ( fire_general ) {
1509  notify_general_obs( e );
1510  }
1511 }
1512 
1513 /// @brief notify ConformationEvent observers
1514 /// @param e the event
1515 /// @param fire_general fire a GeneralEvent afterwards? default true
1516 void
1517 Pose::notify_conformation_obs( ConformationEvent const & e, bool const fire_general ) {
1518  conformation_obs_hub_( e );
1519  if ( fire_general ) {
1520  notify_general_obs( e );
1521  }
1522 }
1523 
1524 /// @brief upon receiving a conformation::signals::XYZEvent
1525 void
1528 }
1529 
1530 
1531 std::ostream & operator << ( std::ostream & os, Pose const & pose)
1532 {
1533  PDBInfoCOP p = pose.pdb_info();
1534  if( p ) {
1535  os << "PDB file name: "<< p->name() << std::endl;
1536  }
1537  os << "Total residues:" << pose.total_residue() << std::endl;
1538  os << "Sequence: " << pose.sequence() << std::endl;
1539  os << "Fold tree:" << std::endl << pose.fold_tree();
1540  return os;
1541 }
1542 
1543 #ifdef USELUA
1544 PoseSP clone( PoseSP p ) {
1545  PoseSP pp( new Pose( *p ) );
1546  return pp;
1547 }
1548 
1549 void lregister_Pose( lua_State * lstate ) {
1550  luabind::module(lstate, "core")
1551  [
1552  luabind::namespace_("pose")
1553  [
1554  luabind::class_<Pose>("Pose")
1555  .def("total_residue", &Pose::total_residue)
1556  .def("sequence", &Pose::sequence)
1557  .def("clone", (PoseSP (*) (PoseSP)) &clone )
1558  ]
1559  ];
1560 }
1561 #endif
1562 
1563 } // pose
1564 } // core