Rosetta 3.5
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
pose_io.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
12 ///
13 /// @brief
14 /// @author
15 
16 // Unit headers
17 #include <core/io/pdb/pose_io.hh>
18 
19 #include <core/types.hh>
20 
21 #include <core/pose/Pose.hh>
22 #include <core/pose/util.hh>
23 
24 // AUTO-REMOVED #include <core/chemical/ResidueTypeSet.hh>
25 // AUTO-REMOVED #include <core/chemical/ChemicalManager.hh>
26 #include <core/chemical/AA.hh>
29 // AUTO-REMOVED #include <core/chemical/orbitals/OrbitalType.hh>
32 // AUTO-REMOVED #include <core/kinematics/FoldTree.hh>
33 #include <core/scoring/Energies.hh>
34 
35 
36 #include <ObjexxFCL/format.hh>
37 
38 #include <basic/Tracer.hh>
39 #include <basic/options/option.hh>
40 
41 // option key includes
42 
43 #include <basic/options/keys/out.OptionKeys.gen.hh>
44 
45 // Utility headers
46 #include <utility/exit.hh>
47 // AUTO-REMOVED #include <utility/string_util.hh>
48 // AUTO-REMOVED #include <utility/io/izstream.hh>
49 #include <utility/io/ozstream.hh>
50 
51 #include <utility/vector1.hh>
52 #include <boost/foreach.hpp>
53 
54 //Auto Headers
57 
58 #define foreach BOOST_FOREACH
59 
60 //Auto using namespaces
61 namespace ObjexxFCL { namespace fmt { } } using namespace ObjexxFCL::fmt; // AUTO USING NS
62 //Auto using namespaces end
63 
64 
65 
66 
67 //#include <fstream>
68 
69 /// A temporary copy of the pose_from_pdb code from the demo directory.
70 /// Will be phased out in favor of file_data routines soon.
71 ///
72 
73 namespace core {
74 namespace io {
75 namespace pdb {
76 
77 
78 /// special Tracer instance acting as special param for all traced_dump_pdb functions
79 basic::Tracer TR_dump_pdb_dummy( "core.io.pdb.pose_io.dump_pdb_dummy" );
80 
81 basic::Tracer TR("core.io.pose_io");
82 
83 using utility::vector1;
84 
85 void
87  pose::Pose const & pose,
88  std::ostream & out,
89  id::AtomID_Mask const & mask,
90  std::string const & tag
91 ) {
92  Size const nres( pose.total_residue() );
93 
94  Size number(0);
95 
96  static std::string const chains( " ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890" );
97 
98  out << "MODEL " << tag << "\n";
99  for ( Size i=1; i<= nres; ++i ) {
100  conformation::Residue const & rsd( pose.residue(i) );
101  for ( Size j=1; j<= rsd.natoms(); ++j ) {
102  conformation::Atom const & atom( rsd.atom(j) );
103 
104  if ( ! mask[ id::AtomID( j,i ) ] ) continue;
105 
106  //skip outputting virtual atom unless specified.
107  //fixed so that the last atom in atom type set can be something other than a virtual atom --steven combs
108  if ( !basic::options::option[ basic::options::OptionKeys::out::file::output_virtual ]() &&
109  rsd.atom_type(j).is_virtual() ) continue;
110 
111  ++number;
112  runtime_assert( rsd.chain() < chains.size() ); // silly restriction
113  char const chain( chains[ rsd.chain() ] );
114  out << "ATOM " << I(5,number) << ' ' << rsd.atom_name(j) << ' ' <<
115  rsd.name3() << ' ' << chain << I(4,rsd.seqpos() ) << " " <<
116  F(8,3,atom.xyz()(1)) <<
117  F(8,3,atom.xyz()(2)) <<
118  F(8,3,atom.xyz()(3)) <<
119  F(6,2,1.0) << F(6,2,1.0) << '\n';
120 
121  //now add orbitals if the atom type has orbitals
122  if(basic::options::option[ basic::options::OptionKeys::out::file::output_orbitals] &&
123  rsd.atom_type(j).atom_has_orbital()){
124  utility::vector1<core::Size> const & orbital_indices(rsd.bonded_orbitals(j));
125  foreach(core::Size orbital_index, orbital_indices){
126  ++number;
127  Vector orbital_xyz(rsd.orbital_xyz(orbital_index));
128  out << "ATOM " << I(5,number) << ' ' << rsd.orbital_name(orbital_index) << ' ' <<
129  rsd.name3() << ' ' << chain << I(4,rsd.seqpos() ) << " " <<
130  F(8,3,orbital_xyz.x()) <<
131  F(8,3,orbital_xyz.y()) <<
132  F(8,3,orbital_xyz.z()) <<
133  F(6,2,1.0) << F(6,2,1.0) << '\n';
134  }
135 
136 
137  }
138 
139 
140 
141  }
142  }
143  out << "ENDMDL\n";
144 }
145 
146 
147 ///////////////////////////////////////////////////////////////////////////////
148 void
150  pose::Pose const & pose,
151  id::AtomID_Map< Real > const & bfactor,
152  std::ostream & out,
153  std::string const & tag
154 )
155 {
156  int const nres( pose.total_residue() );
157 
158  int number(0);
159 
160  static std::string const chains( " ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890" );
161 
162  if(tag!="NO_MODEL_LINE_IN_OUTPUT") out << "MODEL " << tag << "\n";
163  for ( int i=1; i<= nres; ++i ) {
164  conformation::Residue const & rsd( pose.residue(i) );
165  for ( Size j=1; j<= rsd.natoms(); ++j ) {
166  conformation::Atom const & atom( rsd.atom(j) );
167 
168  ++number;
169  runtime_assert( rsd.chain() < chains.size() ); // silly restriction
170  char const chain( chains[ rsd.chain() ] );
171  out << "ATOM " << I(5,number) << ' ' << rsd.atom_name(j) << ' ' <<
172  rsd.name3() << ' ' << chain << I(4,rsd.seqpos() ) << " " <<
173  F(8,3,atom.xyz()(1)) <<
174  F(8,3,atom.xyz()(2)) <<
175  F(8,3,atom.xyz()(3)) <<
176  F(6,2,1.0) << F(6,2, bfactor[ id::AtomID(j,i) ] ) << '\n';
177 
178  //now add orbitals if the atom type has orbitals
179  if(basic::options::option[ basic::options::OptionKeys::out::file::output_orbitals] &&
180  rsd.atom_type(j).atom_has_orbital()){
181  utility::vector1<core::Size> const & orbital_indices(rsd.bonded_orbitals(j));
182  foreach(core::Size orbital_index, orbital_indices){
183  ++number;
184  Vector orbital_xyz(rsd.orbital_xyz(orbital_index));
185  out << "ATOM " << I(5,number) << ' ' << rsd.orbital_name(orbital_index) << ' ' <<
186  rsd.name3() << ' ' << chain << I(4,rsd.seqpos() ) << " " <<
187  F(8,3,orbital_xyz.x()) <<
188  F(8,3,orbital_xyz.y()) <<
189  F(8,3,orbital_xyz.z()) <<
190  F(6,2,1.0) << F(6,2,1.0) << '\n';
191  }
192 
193 
194  }
195 
196 
197  } // for ( int i=1; i<= nres; ++i )
198  } // for ( Size j=1; j<= rsd.natoms(); ++j )
199  if(tag!="NO_MODEL_LINE_IN_OUTPUT") out << "ENDMDL\n";
200 } // dump_bfactor_pdb
201 
202 
203 ///////////////////////////////////////////////////////////////////////////////
204 void
206  conformation::Residue const & rsd,
207  Size & atom_number,
208  std::ostream & out
209 ) {
210 
211  static std::string const chains( " ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890" );
212 
213  for ( Size j=1; j<= rsd.natoms(); ++j ) {
214  conformation::Atom const & atom( rsd.atom(j) );
215 
216  ++atom_number;
217  runtime_assert( rsd.chain() < chains.size() ); // silly restriction
218  char const chain( chains[ rsd.chain() ] );
219  out << "ATOM " << I(5,atom_number) << ' ' << rsd.atom_name(j) << ' ' <<
220  rsd.name3() << ' ' << chain << I(4,rsd.seqpos() ) << " " <<
221  F(8,3,atom.xyz()(1)) <<
222  F(8,3,atom.xyz()(2)) <<
223  F(8,3,atom.xyz()(3)) <<
224  F(6,2,1.0) << F(6,2,0.0) << '\n';
225  if(basic::options::option[ basic::options::OptionKeys::out::file::output_orbitals] &&
226  rsd.atom_type(j).atom_has_orbital()){
227  utility::vector1<core::Size> const & orbital_indices(rsd.bonded_orbitals(j));
228 
229  foreach(core::Size orbital_index, orbital_indices){
230  Vector orbital_xyz(rsd.orbital_xyz(orbital_index));
231  out << "ATOM " << I(5,atom_number) << ' ' << rsd.orbital_name(orbital_index) << ' ' <<
232  rsd.name3() << ' ' << chain << I(4,rsd.seqpos() ) << " " <<
233  F(8,3,orbital_xyz.x()) <<
234  F(8,3,orbital_xyz.y()) <<
235  F(8,3,orbital_xyz.z()) <<
236  F(6,2,1.0) << F(6,2,1.0) << '\n';
237  }
238 
239 
240  }
241 
242  }
243 }
244 
245 
246 
247 ///////////////////////////////////////////////////////////////////////////////
248 void
250  pose::Pose const & pose,
251  std::ostream & out,
252  std::string const & tag
253 ) {
254  pose.dump_pdb(out, tag);
255 }
256 
257 
258 void
260  pose::Pose const & pose,
261  std::string const & filename,
262  std::string const & tag
263 ) {
264  pose.dump_pdb(filename, tag);
265  /*
266  std::ofstream out( filename.c_str() );
267  dump_pdb( pose, out );
268  out.close();
269  */
270 }
271 
272 
273 /// @brief dump_pdb depending on visibility of tracer
274 /// @param[in] tr output performed if tracer is visible or if passed dummy
275 /// tracer core::io::pdb::TR_dump_pdb_dummy
276 void
278  basic::Tracer const & tr,
279  pose::Pose const & pose,
280  std::ostream & out,
281  std::string const & tag
282 )
283 {
284  if ( ( &tr ) != ( &core::io::pdb::TR_dump_pdb_dummy ) ) {
285  if ( !tr.visible() ) {
286  return;
287  }
288  }
289 
290  pose.dump_pdb( out, tag );
291 }
292 
293 
294 /// @brief dump_pdb depending on visibility of tracer
295 /// @param[in] tr output performed if tracer is visible or if passed dummy
296 /// tracer core::io::pdb::TR_dump_pdb_dummy
297 void
299  basic::Tracer const & tr,
300  pose::Pose const & pose,
301  std::string const & filename,
302  std::string const & tag
303 )
304 {
305  if ( ( &tr ) != ( &core::io::pdb::TR_dump_pdb_dummy ) ) {
306  if ( !tr.visible() ) {
307  return;
308  }
309  }
310 
311  pose.dump_pdb( filename, tag );
312 }
313 
314 
315 // the old way: build termini variants after appending non-terminus residues onto the pose in from the pdb...
316 
317 // void
318 // core::import_pose::pose_from_pdb(
319 // pose::Pose & pose,
320 // chemical::ResidueTypeSet const & residue_set,
321 // std::string const & filename
322 // )
323 // {
324 // //using namespace core;
325 // using namespace conformation;
326 
327 // typedef numeric::xyzVector< Real > Vector;
328 
329 // // reset current data
330 // pose.clear();
331 
332 // Coords coords;
333 // Strings resids, sequence, pose_resids;
334 
335 // read_pdb( filename, resids, sequence, coords );
336 
337 // int const nres_pdb( resids.size() );
338 
339 // char prev_chain('?');
340 
341 
342 // for ( int i=1; i<= nres_pdb; ++i ) {
343 // std::string const pdb_name( sequence[i] );
344 // std::string const resid( resids[i] );
345 // runtime_assert( resid.size() == 6 );
346 // char const chain( resid[5] );
347 
348 // ResidueCoords const & xyz( coords.find( resid )->second );
349 
350 // ResidueTypeCOPs const & rsd_type_list( residue_set.name3_map( pdb_name ) );
351 // if ( rsd_type_list.empty() ) {
352 // std::cout << "Unrecognized aa: " << pdb_name << '\n';
353 // continue;
354 // }
355 
356 // // look for perfect match:
357 // bool matched( false );
358 // for ( Size j=1; j<= rsd_type_list.size(); ++j ) {
359 // ResidueType const & rsd_type( *(rsd_type_list[j]) );
360 
361 // if ( rsd_type.is_terminus() ) continue; // no termini at this stage
362 
363 // int rsd_missing(0), xyz_missing(0);
364 
365 // for ( Size k=1; k<= rsd_type.natoms(); ++k ) {
366 // if ( xyz.count( rsd_type.atom_name(k) ) == 0 ) ++xyz_missing;
367 // }
368 
369 // for ( ResidueCoords::const_iterator iter=xyz.begin(), iter_end=xyz.end(); iter!= iter_end; ++iter ) {
370 // if ( !rsd_type.has( iter->first ) ) ++rsd_missing;
371 // }
372 
373 // if ( rsd_missing ) continue;
374 
375 // std::cout << "match: " << i << ' ' << rsd_type.name() << ' ' << xyz_missing << std::endl;
376 
377 // matched = true;
378 
379 // // found a perfect match! fill in the coords
380 // ResidueOP new_rsd( ResidueFactory::create_residue( rsd_type ) );
381 
382 // for ( ResidueCoords::const_iterator iter=xyz.begin(), iter_end=xyz.end(); iter!= iter_end; ++iter ) {
383 // new_rsd->atom( iter->first ).xyz( iter->second );
384 // }
385 
386 
387 // if ( chain != prev_chain && pose.total_residue() ) {
388 // pose.append_residue( new_rsd, true, pose.total_residue() );
389 // } else {
390 // pose.append_residue( new_rsd );
391 // }
392 // pose_resids.push_back( resid );
393 
394 // break;
395 // } // j=1,rsd_type_list.size()
396 
397 
398 // if ( !matched ) {
399 // // unforgiving for testing purposes
400 // std::cout << "Unrecognized residue: " << pdb_name << std::endl;
401 // utility_exit();
402 // }
403 
404 // // handle termini
405 // if ( chain != prev_chain ) {
406 // prev_chain = chain;
407 // int const seqpos( pose.total_residue() );
408 // if ( seqpos > 1 ) {
409 // pose.conformation().insert_chain_ending( seqpos - 1 );
410 // // make previous residue a terminus
411 // make_upper_terminus( pose, residue_set, seqpos-1 );
412 // }
413 // make_lower_terminus( pose, residue_set, seqpos );
414 
415 // }
416 
417 // } // i=1,nres_pdb
418 
419 // make_upper_terminus( pose, residue_set, pose.total_residue() );
420 
421 // // now handle missing atoms
422 // id::AtomID_Mask missing( false );
423 
424 // id::initialize( missing, pose ); // dimension the missing-atom mask
425 
426 // for ( Size i=1; i<= pose.total_residue(); ++i ) {
427 // ResidueCoords const & xyz( coords.find( pose_resids[i] )->second );
428 // Residue const & rsd( pose.residue(i) );
429 // for ( Size j=1; j<= rsd.natoms(); ++j ) {
430 // if ( xyz.count( rsd.atom_name(j) ) == 0 ) missing[ id::AtomID( j, i ) ] = true;
431 // }
432 // }
433 
434 // pose.conformation().fill_missing_atoms( missing );
435 // }
436 
437 /// @brief Utility function to round a real value to the given precisions (number of digits after the decimal place) for output.
438 /// For use solely by extract_scores()
439 /// @details Apparently, there isn't an easy way to do this in C++, or even the general goal
440 /// of limiting the precision in output streams. (setprecision() with default formatting doesn't
441 /// correctly handle very small numbers, and with fixed precision outputs superfluous zeros.)
442 
444 {
445  if( inval >= 1 || inval <= -1 ) { // Don't alter value, as the default precision of 6 works fine, and we avoid rounding artifacts
446  return inval;
447  }
448  core::Real outval;
449  std::stringstream temp;
450  temp << std::fixed << std::setprecision(5) << inval;
451  temp >> outval;
452  return outval;
453 }
454 
455 // @brief Write energies information into an output stream (e.g. the tail of a pdb file)
457  core::pose::Pose const & pose,
458  utility::io::ozstream & out
459 )
460 {
461 // if(!pose.energies().energies_updated()){
462 // out << "Pose's energies were not current, PDBJobOutputter will not force update" << std::endl;
463 // return;
464 // }
465 
466  //This is shamelessly refactored from the older JobDistributor; Jobdistributors.hh:1018; SVN 25940
467  // APL: Moving this job-independent code into a central location.
468  // Which score terms to use
469  core::scoring::EnergyMap weights = pose.energies().weights();
470  typedef utility::vector1<core::scoring::ScoreType> ScoreTypeVec;
471  ScoreTypeVec score_types;
472  for(int i = 1; i <= core::scoring::n_score_types; ++i) {
474  if ( weights[ii] != 0 ) score_types.push_back(ii);
475  }
476  // This version is formatted for easy parsing by R, Excel, etc.
477  out << "# All scores below are weighted scores, not raw scores.\n";
478  out << "#BEGIN_POSE_ENERGIES_TABLE " << out.filename() << "\n";
479  out << "label";
480  foreach(core::scoring::ScoreType score_type, score_types){
481  out << " " << name_from_score_type(score_type);
482  }
483  out << " total\n";
484  out << "weights";
485  foreach(core::scoring::ScoreType score_type, score_types){
486  out << " " << weights[score_type];
487  }
488  out << " NA\n";
489  out << "pose";
490  core::Real pose_total = 0.0;
491  if ( pose.energies().energies_updated() ) {
492  foreach(core::scoring::ScoreType score_type, score_types){
493  core::Real score = (weights[score_type] * pose.energies().total_energies()[ score_type ]);
494  out << " " << restrict_prec(score);
495  pose_total += score;
496  }
497  out << " " << restrict_prec(pose_total) << "\n";
498  for(core::Size j = 1, end_j = pose.total_residue(); j <= end_j; ++j) {
499  core::Real rsd_total = 0.0;
500  out << pose.residue(j).name() << "_" << j;
501  foreach(core::scoring::ScoreType score_type, score_types){
502  core::Real score = (weights[score_type] * pose.energies().residue_total_energies(j)[ score_type ]);
503  out << " " << restrict_prec(score);
504  rsd_total += score;
505  }
506  out << " " << restrict_prec(rsd_total) << "\n";
507  }
508  }
509  out << "#END_POSE_ENERGIES_TABLE " << out.filename() << "\n";
510 }
511 
512 
513 /////////////////////////////////////////////////////////////////////
514 void
516  pose::Pose const & pose,
517  std::ostream & out,
518  std::map< id::AtomID, Size > & atom_id_output ){
519 
520  // It might be better to put this in file_data.cc, and to make use of the file_data to get the
521  // numbering exactly right.
522  Real const CUTOFF( 3.0 );
523  for ( Size i=1; i<= pose.total_residue(); ++i ) {
524 
525  conformation::Residue const & rsd( pose.residue(i) );
526 
527  for ( Size j=1; j<= rsd.natoms(); ++j ) {
528 
529  id::AtomID const atom_id( j, i );
530 
531  if ( !atom_id_output[ atom_id ] ) continue;
532 
533  utility::vector1<core::id::AtomID> const & nbr_ids( pose.conformation().bonded_neighbor_all_res( atom_id, true /*virt*/) );
534  for ( Size n = 1; n <= nbr_ids.size(); n++ ) {
535 
536  id::AtomID const & nbr_id = nbr_ids[ n ];
537 
538  if ( !atom_id_output[ nbr_id ] ) continue;
539 
540  if ( atom_id.rsd() > nbr_id.rsd() ) continue;
541  if ( atom_id.rsd() == nbr_id.rsd() && atom_id.atomno() > nbr_id.atomno() ) continue;
542 
543  if ( ( pose.xyz( atom_id ) - pose.xyz( nbr_id ) ).length() < CUTOFF ) continue;
544 
545  // Final check: actually look for a connection in the atom tree.
548 
549  if( ( nbr->parent() != atom ) && ( atom->parent() != nbr ) ) continue;
550 
551  out << "CONECT" << I(5,atom_id_output[ atom_id ]) << I(5,atom_id_output[ nbr_id ]) << std::endl;
552 
553  }
554 
555  }
556  }
557 
558  }
559 
560 /////////////////////////////////////////////////////////////////////
561 // useful for centroid poses -- spit out "CONECT" information on bonded atoms
562 // that might otherwise be ignored by pymol/rasmol.
563 void
565  pose::Pose const & pose,
566  std::ostream & out ){
567 
568  std::map< id::AtomID, Size > atom_id_output;
569 
570  // It might be better to put this in file_data.cc, and to make use of the file_data to get the
571  // numbering exactly right.
572  Size count( 0 );
573 
574  for ( Size i=1; i<= pose.total_residue(); ++i ) {
575  conformation::Residue const & rsd( pose.residue(i) );
576  for ( Size j=1; j<= rsd.natoms(); ++j ) {
577 
578  //skip outputting virtual atom unless specified
579  atom_id_output[ id::AtomID(j,i) ] = 0;
580 
581  if ( !basic::options::option[ basic::options::OptionKeys::out::file::output_virtual ]() && rsd.is_virtual( j ) ) continue;
582 
583  count++;
584  atom_id_output[ id::AtomID(j,i) ] = count;
585 
586  }
587  }
588 
589  dump_connect_info( pose, out, atom_id_output );
590 
591 }
592 
593 } // namespace pdb
594 } // namespace io
595 } // namespace core