Rosetta 3.5
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
BinaryProteinSilentStruct.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 // :noTabs=false:tabSize=4:indentSize=4:
4 //
5 // (c) Copyright Rosetta Commons Member Institutions.
6 // (c) This file is part of the Rosetta software suite and is made available under license.
7 // (c) The Rosetta software is developed by the contributing members of the Rosetta Commons.
8 // (c) For more information, see http://www.rosettacommons.org. Questions about this can be
9 // (c) addressed to University of Washington UW TechTransfer, email: license@u.washington.edu.
10 
11 /// @file core/io/silent/BinaryProteinSilentStruct.cc
12 ///
13 /// @brief
14 /// @author Frank DiMaio
15 /// @author Mike Tyka
16 
17 // C++ Headers
18 #include <cmath>
19 #include <cstdlib>
20 #include <iostream>
21 #include <utility>
22 #include <vector>
23 #include <list>
24 #include <string>
25 #include <map>
26 #include <sstream>
27 
28 // mini headers
29 #include <ObjexxFCL/char.functions.hh>
30 #include <ObjexxFCL/string.functions.hh>
31 
32 #include <basic/Tracer.hh>
33 // AUTO-REMOVED #include <utility/string_util.hh>
34 
35 #include <core/scoring/Energies.hh>
36 
45 
47 
49 
50 #include <core/id/AtomID.hh>
51 #include <core/id/NamedStubID.hh>
52 
53 #include <core/pose/Pose.hh>
54 #include <core/pose/util.hh>
55 
57 // AUTO-REMOVED #include <core/conformation/ResidueFactory.hh>
58 
59 #include <numeric/model_quality/rms.hh>
60 
62 // AUTO-REMOVED #include <core/conformation/symmetry/util.hh>
63 
66 
67 // option key includes
68 #include <basic/options/option.hh>
69 #include <basic/options/keys/in.OptionKeys.gen.hh>
70 #include <basic/options/keys/run.OptionKeys.gen.hh>
71 
72 #include <boost/lexical_cast.hpp>
73 
75 #include <utility/vector1.hh>
76 #include <utility/Binary_Util.hh>
77 
78 
79 static basic::Tracer tr("core.io.silent");
80 
81 namespace core {
82 namespace io {
83 namespace silent {
84 
85 
86 
87 /// @brief Constructors.
89 {
90  using namespace basic::options;
91  using namespace basic::options::OptionKeys;
92 
93  fullatom_ = false;
95  nres ( nres_in );
96  resize( nres_in );
98  symminfo_->set_use_symmetry(false);
99 }
100 
102 {
103  using namespace basic::options;
104  using namespace basic::options::OptionKeys;
105 
106  fullatom_ = false;
107  bJumps_use_IntraResStub_ = false;
108  nres( 0 );
109  decoy_tag( "empty" );
111  symminfo_->set_use_symmetry(false);
112 }
113 
114 
116  core::pose::Pose const & pose,
117  std::string tag
118 ) {
119  bJumps_use_IntraResStub_ = false;
121  symminfo_->set_use_symmetry(false);
122  fill_struct( pose, tag );
123 } // BinaryProteinSilentStruct
124 
125 void
127  core::pose::Pose const & pose,
128  std::string tag
129 ) {
130  tr.Trace << "binary:fill_struct... " << std::endl;
131  decoy_tag( tag );
132 
133  if ( tag == "empty_tag" ) set_tag_from_pose( pose );
134 
135  fullatom( pose.is_fullatom() );
136  tr.Trace << "get energies from pose..." << std::endl;
137  energies_from_pose( pose );
138 
139  // conformation information
140  sequence( pose.annotated_sequence( true ) );
141 
143  resize( pose.total_residue() );
144  } else { // core::pose::symmetry::is_symmetric(pose)
145  //fpd previous implementation stored all atom coords and only wrote asymm unit coords
146  //fpd however, if this struct is doubling as temporary storage for poses (as in batch relax)
147  //fpd we only want to store asymm unit coords
148  //fpd in other words, the code should work if we call fill_struct()->fill_pose() without an intervening print_conformation()
150  core::Size nres_effective = symmetry_info()->num_virtuals() + symmetry_info()->num_independent_residues();
151  resize( nres_effective );
152  }
153 
154  tr.Trace << "read coords..." << std::endl;
155  for ( unsigned int i = 1; i <= pose.total_residue(); ++i ) {
156  core::conformation::Residue const& resi = pose.residue(i);
157  //int natoms = pose.residue(i).natoms();
158  if( is_symmetric() && !symmetry_info()->bb_is_independent( i ) ) continue;
159  int i_asymm = symmetry_info()->get_asymmetric_seqpos( i ); // remaps virtual ids
160 
161  atm_coords_[i_asymm].resize( resi.natoms() );
162  for (unsigned int j = 1; j <= resi.natoms(); ++j) {
163  atm_coords_[i_asymm][j] = resi.atom(j).xyz();
164  }
165  secstruct_[i_asymm] = pose.secstruct(i);
166  } // for ( unsigned int i = 1; i <= pose.total_residue(); ++i )
167 
168  fold_tree_ = pose.fold_tree();
169  jumps_.clear();
170  for ( Size nr = 1; nr <= fold_tree().num_jump(); nr++) {
171  add_jump( pose.jump(nr) );
172  }
173 
175 } // BinaryProteinSilentStruct
176 
177 
179  core::Size nres_pose = nres();
180  if ( is_symmetric() )
181  nres_pose = symmetry_info()->num_total_residues_with_pseudo() ;
182  if ( seqpos < 1 || seqpos >= nres_pose ) {
183  tr.Fatal << "ERROR: add_chain_ending() invalid chain ending " << seqpos << std::endl;
184  utility_exit();
185  }
186 
187  chain_endings_.push_back( seqpos );
188  std::sort( chain_endings_.begin(), chain_endings_.end() ); // keep the list sorted
189 }
190 
191 void BinaryProteinSilentStruct::parse_chain_endings( std::istream & stream ) {
192  std::string s;
193  stream >> s; // first column is "CHAIN_ENDINGS" tag, skip it
194 
196  while ( stream.good() ) {
197  stream >> s;
198  v.push_back( s );
199  }
200  // remember to skip the last entry in the vector, which is the structure's nametag
201  for ( Size i = 1, ie = v.size(); i < ie; ++i ) {
202  add_chain_ending( boost::lexical_cast< Size >( v[ i ] ) );
203  }
204 }
205 
207  std::ostringstream ss;
208  ss << "CHAIN_ENDINGS ";
209 
210  for ( utility::vector1< Size >::const_iterator i = chain_endings().begin(), ie = chain_endings().end(); i != ie; ++i ) {
211  ss << ' ' << (*i);
212  }
213 
214  return ss.str();
215 }
216 
218  core::Size nres_pose = nres();
219  if ( is_symmetric() )
220  nres_pose = symmetry_info()->num_total_residues_with_pseudo() ;
221  for ( utility::vector1< Size >::const_iterator i = endings.begin(), ie = endings.end(); i != ie; ++i ) {
222  if ( (*i) < 1 || (*i) > nres_pose ) { //fpd if symmetric, chainendings may be > nres (in asu)
223  tr.Fatal << "ERROR: chain_endings() invalid chain ending " << (*i) << std::endl;
224  utility_exit();
225  }
226  }
227 
228  chain_endings_ = endings;
229  std::sort( chain_endings_.begin(), chain_endings_.end() ); // keep the list sorted
230 }
231 
233  utility::vector1< std::string > const & lines,
234  SilentFileData & container
235 ) {
236  using namespace basic::options;
237  using namespace basic::options::OptionKeys;
238 
239  utility::vector1< std::string > energy_names_;
241 
242  if ( iter->substr(0,9) != "SEQUENCE:" ) {
243  // get sequence and scorename data from the silent-file data object,
244  // because I don't have it!
245  EnergyNamesOP enames = EnergyNamesOP(
246  static_cast< EnergyNames * >
247  ( container.get_shared_silent_data( energynames )() )
248  );
249 
251  static_cast< SimpleSequenceData * > ( container.get_shared_silent_data( simplesequencedata )() )
252  );
253 
254  sequence ( seqdata->sequence() );
255  energy_names_ = enames ->energy_names();
256  } else {
257  // get sequence and scorename data from the first two lines provided,
258  // put them into container for further use by other SilentStruct
259  // objects.
260 
261  // first line is SEQUENCE:
262  std::istringstream line_stream( *iter );
263  std::string tag;
264  tr.Debug << "reading sequence from " << *iter << std::endl;
265 
266  std::string temp_seq;
267  line_stream >> tag >> temp_seq;
268  if ( line_stream.fail() || tag != "SEQUENCE:" ) {
269  tr.Error << "bad format in sequence line of silent file" << std::endl;
270  tr.Error << "line = " << *iter << std::endl;
271  tr.Error << "tag = " << tag << std::endl;
272  return false;
273  }
274  sequence( temp_seq );
275 
276  // second line is a list of score names
277  ++iter;
278  if ( iter == lines.end() ) {
279  utility_exit_with_message( "While reading binary silent structure, encountered end of structure too early after reading the 'SEQUENCE' line" );
280  }
281  std::istringstream score_line_stream( *iter );
282  tr.Debug << "reading score names from " << *iter << std::endl;
283  ++iter;
284 
285  score_line_stream >> tag; // SCORE:
286  if ( score_line_stream.fail() || tag != "SCORE:" ) {
287  tr.Error << "bad format in second line of silent file" << std::endl;
288  tr.Error << "tag = " << tag << std::endl;
289  tr.Error << "line = " << *iter << std::endl;
290  }
291 
292  score_line_stream >> tag; // first score name
293  while ( ! score_line_stream.fail() ) {
294  energy_names_.push_back( tag );
295  score_line_stream >> tag; // try to get next score name
296  }
297 
298  EnergyNamesOP enames( new EnergyNames() );
299  SimpleSequenceDataOP seqdata( new SimpleSequenceData() );
300 
301  enames ->energy_names( energy_names_ );
302  seqdata->set_sequence( sequence() );
303 
304  container.set_shared_silent_data( energynames , enames );
305  container.set_shared_silent_data( simplesequencedata, seqdata );
306  } // get header information
307 
308 
309  core::Size currpos = 1;
310  bool bitflip = false;
311  fullatom_ = false; //start with fullatom_ false and update to true as soon as a residue with too many atoms is read...
312  bool fullatom_well_defined = false;
314  iter != end; ++iter ) {
315  std::string tag;
316  std::istringstream line_stream( *iter );
317 
318  if ( iter->substr(0,6) == "REMARK" ) {
319  std::string tag;
320  std::string comment;
321  std::string value;
322  line_stream >> tag >> comment >> value;
323  add_comment( comment, value );
324  continue; // skip comments
325  }
326  if ( iter->substr(0,7) == "SCORE: " ) {
327  // SCORE: line with values from this structure.
328  Size nres = one_letter_sequence().length();
329  resize( nres );
330 
331  std::string tag;
332  line_stream >> tag;
333  if ( line_stream.fail() || tag != "SCORE:" ) {
334  tr.Error << "bad format in first score line of silent file" << std::endl;
335  tr.Error << "line = " << *iter << std::endl;
336  tr.Error << "tag = " << tag << std::endl;
337  }
338 
339  parse_energies( line_stream, energy_names_ );
340 
341  } else { // conformation lines
342  // parse fold_tree and jump lines
343  if ( iter->substr(0,10) == "FOLD_TREE " ) {
345  line_stream >> f;
346  fold_tree( f ); // add fold-tree to this SilentStruct
347  tr.Debug << "read fold-tree " << f; //"\n" is in fold-tree output
348  tr.Debug << "reading " << f.num_jump() << " jumps " << std::endl;
349  continue;
350  } else if ( iter->substr(0,2) == "RT" ) {
352  line_stream >> jump;
353  tr.Debug << "read jump " << jump << std::endl;
354  add_jump( jump );
355  // modern style jumps, defined completely with the FoldTree
356  bJumps_use_IntraResStub_ = false;
357  continue;
358  } else if ( iter->substr(0,9) == "SEQUENCE:" ) {
359  tr.Warning << "Skipping duplicate sequence declaration " << std::endl;
360  continue;
361  } else if ( iter->substr(0,19) == "ANNOTATED_SEQUENCE:" ) {
362  std::string annotated_seq;
363  line_stream >> tag; //ANNOTATED_SEQUENCE
364  line_stream >> annotated_seq;
365  sequence( annotated_seq );
366  // resize pose according to number of resiudes in annotated sequence
367  resize( one_letter_sequence().length() );
368  continue;
369  } else if ( iter->substr(0,4) == "JUMP" ) {
370  // support for rosetta++ silent files
371  std::string tag;
372  Size nr;
373  line_stream >> tag; //JUMP
374  line_stream >> nr;
375  if ( nr != fold_tree().num_jump() ) {
376  tr.Warning
377  << "WARNING: corrupted silent file read line JUMP X -- X should match number of jumps in FOLD_TREE " << std::endl;
378  }
379  for ( Size i = 1; i<= nr; i++ ) {
381  line_stream >> jump;
382  add_jump( jump );
383  }
384  bJumps_use_IntraResStub_ = true;// jump is defined via N-C-CA rosetta++ style
385  continue;
386  } else if ( iter->substr(0,13) == "SYMMETRY_INFO" ) { // symmetry information
388  line_stream >> s;
389  symmetry_info( s );
390  core::Size nres_effective = symmetry_info()->num_virtuals() + symmetry_info()->num_independent_residues();
391  resize( nres_effective ); //fpd resize containers to ASU
392  continue;
393  } else if ( iter->substr( 0, 13 ) == "CHAIN_ENDINGS" ) {
394  chain_endings_.clear();
395  parse_chain_endings( line_stream );
396  continue;
397  }
398 
399 
400  // parse coords
401  line_stream >> tag;
402 
403  if ( tag.length() < 1 ) {
404  tr.Warning << "WARNING: read blank line in decoy tag " << decoy_tag()
405  << std::endl;
406  continue;
407  }
408  if ( static_cast< core::Size > (currpos) > secstruct_.size() ) {
409  tr.Error << "ERROR: trying to index off the end of the secstruct array"
410  << ", idx is " << currpos << " secstruct_.size() is " << secstruct_.size()
411  << std::endl;
412  return false;
413  }
414  secstruct_[currpos] = tag[0]; // first char is sec struct
415 
416  int natoms = (tag.length()-1) / 16;
417  utility::vector1< numeric::xyzVector <float> > atm_buff( natoms+1 );
418  utility::decode6bit( (unsigned char*)&(atm_buff[1]) , tag.substr(1) );
419 
420  // endianness check ...
421  // check the dist between atoms 1 and 2 as well as atoms 2 and 3 if
422  // EITHER is unreasonable .. and flipping fixes BOTH then turn bitflip on
423  if (currpos == 1) {
424  core::Real len_check12 = (atm_buff[1]-atm_buff[2]).length();
425  core::Real len_check23 = (atm_buff[3]-atm_buff[2]).length();
426  if ( len_check12 < 0.5 || len_check12 > 2.0 || len_check23 < 0.5 ||
427  len_check23 > 2.0
428  ) {
429  utility::swap4_aligned ( (void*) &(atm_buff[1][0]) , 3*natoms );
430  // recheck; if not better flip back
431  len_check12 = (atm_buff[1]-atm_buff[2]).length();
432  len_check23 = (atm_buff[3]-atm_buff[2]).length();
433  if ( len_check12 < 0.5 || len_check12 > 2.0 || len_check23 < 0.5 || len_check23 > 2.0 ) {
434  utility::swap4_aligned ( (void*) &(atm_buff[1][0]) , 3*natoms );
435  } else {
436  tr.Warning << "reading big-endian binary silent file! " << decoy_tag() << std::endl;
437  bitflip = true;
438  }
439  }
440  } else {
441  if (bitflip ) {
442  utility::swap4_aligned ( (void*) &(atm_buff[1][0]) , 3*natoms );
443  }
444  }
445  if ( !symmetry_info()->get_use_symmetry() || currpos <=symmetry_info()->num_independent_residues() ) {
446  // always run this if we're not dealing with a symmetric pose, or, if we're dealing with a symmetric pose
447  // and we're still reading in data for the assymetric unit. But if we're reading in a symmetric pose
448  // and currpos > the number of residues in the asymmetric unit (i.e. we're reading in a virtual residue),
449  // then DON'T use a count of the number of atoms in the given residue as an indication of whether we're dealing
450  // with a fullatom structure.
451  detect_fullatom( currpos, natoms, fullatom_, fullatom_well_defined );
452  }
453 
454  atm_coords_[currpos].resize( natoms ); // allocate space for coords
455  for (int j=1; j<=natoms; ++j) {
456  atm_coords_[currpos][j] = atm_buff[j];
457  }
458  currpos++;
459  //tr.Debug << "processing line " << *iter << std::endl;
460  } // conformation lines
461  } // for ( iter ... )
462 
463  if ( fold_tree().num_jump() != jumps_.size() ) {
464  tr.Warning << "parse error: found " << jumps_.size()
465  << " RT lines for a fold-tree with " << fold_tree().num_jump()
466  << " for decoy tag " << decoy_tag() << std::endl;
467  return false;
468  }
469 
470  // if ( (unsigned int) currpos != nres() + 1 ) return false;
471  // if ( nres() == 0 ) return false;
472 
473 
474  if ( atm_coords_.size() != nres() ) {
475  tr << "ERROR: didn't find coordinates for all sequence positions of "
476  << decoy_tag() << std::endl;
477  tr << " expected " << nres()
478  << ", found " << currpos-1 << std::endl;
479  return false; //no success
480  }
481 
482  if ( fold_tree().size() < 1 ) {
484  tr.Debug << " generating simple fold-tree " << fold_tree();
485  }
486 
487  if ( bJumps_use_IntraResStub_ ) { //for rosetta++ file-format
488  //prepares of setting RT via N, CA, C
490  //on could also think of making this a temporary change after read is
491  //finished return to a standard fold_tree...
492  }
493 
494  //tr.Debug << "(TEX) FOLD TREE: " << fold_tree();
495  if ( !fullatom_well_defined ) fullatom_ = option[ in::file::fullatom ]();
496  return true;
497 } // init_from_lines
498 
499 /// @brief Resize this silent-struct to the appropriate number of residues.
500 void
502  Size const nres_in
503 ) {
504  //nres_ = nres_in;
505  nres( nres_in );
506  secstruct_.resize( nres() );
507  atm_coords_.resize( nres() );
508 
509  // make a new FoldTree if we're just replacing a simple FoldTree, otherwise
510  // trust the user to have provided us a reasonable tree in a FOLD_TREE line.
511  if ( fold_tree_.is_simple_tree() ) {
513  }
514 }
515 
517  core::pose::Pose & pose
518 ) const {
519  using namespace core::chemical;
520  ResidueTypeSetCAP residue_set;
521  tr.Debug << "fill_pose: SilentStruct is " << ( fullatom() ? "fullatom" : "centroid" ) << std::endl;
522  if ( fullatom() ) {
524  } else {
526  }
527  fill_pose( pose, *residue_set );
528 } // fill_pose
529 
531  core::pose::Pose & pose,
532  core::chemical::ResidueTypeSet const & residue_set
533 ) const {
534 
535  runtime_assert( nres() != 0 );
536  runtime_assert( sequence() != "" );
537  if ( pose.annotated_sequence() != sequence()
538  || fullatom() != pose.is_fullatom() ) { //fpd
539  //fpd this function assumes an asymmetric conformation to start (which will later be symmetrized)
542  core::pose::make_pose_from_sequence( pose, sequence(), residue_set, false /*auto_termini*/ );
543  }
544 
545  //fpd ???
546  pose.energies().clear();
547 
548  // coords
551  core::Size nres_pose = nres();
552  if ( is_symmetric() )
553  nres_pose = symmetry_info()->num_total_residues_with_pseudo() ;
554  for ( Size seqpos = 1; seqpos <= nres_pose; ++seqpos ) {
555  int natoms_pose = pose.residue(seqpos).natoms() ;
556  int atm_seqpos = symmetry_info()->get_asymmetric_seqpos( seqpos ) ;
557  int natoms_struct = atm_coords_[atm_seqpos].size();
558  int natoms_total = std::min( natoms_pose , natoms_struct );
559 
560  if ( natoms_pose != natoms_struct) {
561  tr.Warning << "[ WARNING ] "
562  << "Number of atoms in pose and silent file disagree! "
563  << "Attempting to continue ..." << std::endl
564  << "[ WARNING ] (in residue " << seqpos
565  << " natoms_pose=" << natoms_pose
566  << "atm_seqpos " << atm_seqpos << " natoms_struct="
567  << natoms_struct << ")" << std::endl;
568  tr.flush();
569  }
570 
571  //natoms_pose = pose.residue(seqpos).natoms();
572  //natoms_total = std::min( natoms_pose, natoms_struct );
573 
574  for ( int j = 1; j <= natoms_total; ++j ){
575  id::AtomID id( j, seqpos );
576  //numeric::xyzVector< core::Real> atom_i(atm_coords_[atm_seqpos][j][0], atm_coords_[atm_seqpos][j][1], atm_coords_[atm_seqpos][j][2]);
577  //pose.set_xyz( id, atom_i );
578  atm_ids.push_back( id );
579  atm_xyzs.push_back(
580  numeric::xyzVector< core::Real>(atm_coords_[atm_seqpos][j][0], atm_coords_[atm_seqpos][j][1], atm_coords_[atm_seqpos][j][2]) );
581  }
582  pose.set_secstruct( seqpos, secstruct_[atm_seqpos] );
583  } // for ( seqpos )
584  pose.batch_set_xyz( atm_ids, atm_xyzs );
585 
586  tr.Debug << "FOLD TREE: " << fold_tree();
587  // set fold_tree
588  pose.fold_tree( fold_tree() );
589 
590  // SYMMETRY - setup up Symmetry stuff here.
591  //fpd As a note, this doesn't symmetrize the conformation like calling the constructor with symmdata would
592  //fpd Instead, this just adds symminfo to an already-symmetrized pose
593  //fpd When jumps are symmetrized the pose will also be symmetric
594  if( is_symmetric() ) {
596  }
597 
598  // set jumps
599  for ( Size nr = 1; nr <= fold_tree().num_jump(); nr++) {
600  if( is_symmetric() && !symmetry_info()->jump_is_independent(nr) ) continue;
601  if ( !bJumps_use_IntraResStub_ ) { //default modern file-format
602  pose.set_jump( nr, jump( nr ) );
603  } else { //support for rosetta++ format
604  Size start = fold_tree().jump_edge( nr ).start();
605  Size stop = fold_tree().jump_edge( nr ).stop();
606  id::StubID up_stub ( core::pose::named_stub_id_to_stub_id(id::NamedStubID( "CA", "N", "CA", "C", start < stop ? start : stop ), pose ) );
607  id::StubID down_stub( core::pose::named_stub_id_to_stub_id(id::NamedStubID( "CA", "N", "CA", "C", start < stop ? stop : start ), pose ) );
608  pose.conformation().set_stub_transform( up_stub, down_stub, jump( nr ) );
609  }
610  }
611 
612 
613  // fpd if symmetric 'nres' covers the ASU while 'sequence' covers the symmetric pose
614  tr.Debug << "nres = " << nres_pose << std::endl;
615  tr.Debug << "one_letter_sequence() = " << one_letter_sequence().length() << std::endl;
616 
617  if( nres_pose != one_letter_sequence().length() ){
618  utility_exit_with_message( "RuntimeAssert failed: nres() == one_letter_sequence().length()" );
619  }
620 
621 
622  if ( !chain_endings().empty() ) {
624  }
625 
626 
628 
629  finish_pose( pose );
630 } // fill_pose
631 
632 void
633 BinaryProteinSilentStruct::print_header( std::ostream & out ) const
634 {
636 }
637 
638 
640  std::ostream & output
641 ) const {
642  output << "REMARK BINARY SILENTFILE\n";
643 
644  // fold tree
645  // assume non-trivial fold_tree only if more than one edge, i.e., EDGE 1 <nres> -1?
646  // no -- can have a fold tree with a single jump, actually.
647  if ( fold_tree().size() > 1 || fold_tree().num_jump() > 1 ) {
648  output << "FOLD_TREE ";
650  it = fold_tree().begin(), it_end = fold_tree().end();
651  it != it_end; ++it
652  ) {
653  output << *it;
654  }
655  // output << fold_tree(); this produces a new-line --- wrong behaviour
656  // of fold_tree but I don't want to fix 1000 u-tracer unit-tests!
657  output << ' ' << decoy_tag() << "\n";
658  }
659  for ( Size i = 1; i <= fold_tree().num_jump(); i++ ) {
660  output << jump( i ) << ' ' << decoy_tag() << "\n";
661  }
662 
663  // sequence
664  output << "ANNOTATED_SEQUENCE: " << sequence() << " " << decoy_tag() << "\n"; //chu print annotated_sequence per decoy
665 
666  //lin print out the SYMMETRY_INFO line here
667  if( is_symmetric() ) {
668  output << *symmetry_info() << ' ' << decoy_tag() << "\n";
669  }
670 
671  //tr.Debug << "FOLD_TREE Size: " << fold_tree().size() << " " << fold_tree() << std::endl;
672 
673  // chain endings
674  if ( !chain_endings().empty() ) {
675  output << chain_endings_str() << ' ' << decoy_tag() << '\n';
676  }
677 
678  // fullatom flag
679  //int fullatom_flag = (fullatom_? 1 : 2);
680  std::string resline;
681  //encode6bit( (unsigned char*)&fullatom_flag, 4, resline );
682  //output << resline << "\n";
683 
684  using namespace basic::options;
685  if( option[ OptionKeys::run::write_failures ].user() && option[ OptionKeys::run::write_failures ] == false && decoy_tag().substr( 0, 8 ) == "FAILURE_" ) return;
686  // the encoded coordinates
687  for ( Size i = 1; i <= nres(); ++i ) {
688  //fpd symmetric residues are now trimmed in fill_struct()
689  //if( !symmetry_info()->is_asymmetric_seqpos(i) ) continue; //Symmetry only output asymmetric unit
690 
691  char this_secstr = secstruct_[i];
692  if (this_secstr < 'A' || this_secstr > 'Z') this_secstr = 'L';
693 
694  utility::encode6bit( (unsigned char*)&atm_coords_[i][1][0], atm_coords_[i].size()*12, resline ); // ASSUMES FLOAT == 4 BYTES!!! (eep!)
695  output << this_secstr << resline << ' ' << decoy_tag() << "\n";
696  } // for ( Size i = 1; i <= nres; ++i )
697 } // print_conformation
698 
699 
701  pose::Pose temp_pose;
702  ObjexxFCL::FArray2D< Real > rebuilt_coords ( 3, atm_coords_.size() ),
703  original_coords( 3, atm_coords_.size() );
704 
705  // build temp_pose from coordinates
706  fill_pose( temp_pose );
707 
708  for ( Size i = 1; i <= temp_pose.total_residue(); ++i ) {
709  for ( Size k = 1; k <= 3; ++k ) { // k = X, Y and Z
710  rebuilt_coords (k,i) = temp_pose.residue(i).xyz( "CA" )[k-1];
711  original_coords(k,i) = atm_coords_[i][2][k-1];
712  }
713  }
714 
715  Real rmsd = numeric::model_quality::rms_wrapper( temp_pose.total_residue(), rebuilt_coords, original_coords );
716  return rmsd;
717 }
718 
719 ObjexxFCL::FArray2D< Real >
721  core::Size n_residues = nres();
722  ObjexxFCL::FArray2D< Real > my_coords( 3, n_residues );
723  for ( Size i = 1; i <= n_residues; ++i ) { // i = n_residues
724  for ( Size k = 1; k <= 3; ++k ) { // k = X, Y and Z
725  my_coords(k,i) = atm_coords_[i][2][k-1];
726  } // k
727  } // i
728 
729  return my_coords;
730 } // get_CA_positions
731 
733  ObjexxFCL::FArray2D< Real > my_coords = get_CA_xyz();
734  ObjexxFCL::FArray2D< Real > other_coords = other_pss.get_CA_xyz();
735  Real rmsd = numeric::model_quality::rms_wrapper( nres(), my_coords, other_coords );
736 
737  return rmsd;
738 }
739 
742 )
743 {
744  utility_exit_with_message( "called BinaryProteinSilentStruct::operator=)" );
745  exit(1);
746 }
747 
748 } // namespace silent
749 } // namespace io
750 } // namespace core