Rosetta 3.5
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
residue_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 //
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 residue_io.cc
11 /// @brief
12 /// @author Phil Bradley
13 
14 // Unit header
16 
17 
18 // Rosetta headers
22 
23 #include <core/chemical/Atom.hh>
26 // AUTO-REMOVED #include <core/chemical/orbitals/OrbitalType.hh>
27 
28 // Commented by inclean daemon #include <core/chemical/Adduct.hh>
29 
30 #include <core/id/AtomID.hh>
31 // AUTO-REMOVED #include <core/id/DOF_ID.hh>
32 #include <core/kinematics/Stub.hh>
33 // AUTO-REMOVED #include <core/kinematics/AtomTree.hh>
34 //#include <core/pack/dunbrack/SingleLigandRotamerLibrary.hh>
35 
36 // Commented by inclean daemon #include <basic/basic.hh>
37 #include <basic/Tracer.hh>
38 
39 // ObjexxFCL headers
40 // AUTO-REMOVED #include <ObjexxFCL/ObjexxFCL.hh>
41 #include <ObjexxFCL/string.functions.hh>
42 
43 // Utility headers
44 //#include <utility/io/izstream.hh>
45 // Commented by inclean daemon #include <utility/vector1.hh>
46 #include <utility/file/FileName.hh>
47 #include <utility/file/file_sys_util.hh>
48 
49 // Numeric headers
50 #include <numeric/conversions.hh>
51 
52 //Auto Headers
53 #include <platform/types.hh>
54 #include <core/id/DOF_ID.fwd.hh>
55 #include <core/kinematics/Jump.hh>
56 #include <utility/Bound.hh>
57 #include <utility/vector1.hh>
58 #include <utility/io/izstream.hh>
59 #include <utility/keys/AutoKey.hh>
60 #include <utility/keys/SmallKeyVector.hh>
61 #include <numeric/xyz.functions.hh>
62 #include <ObjexxFCL/Dimension.hh>
63 #include <ObjexxFCL/DynamicIndexRange.hh>
64 #include <ObjexxFCL/FArray.hh>
65 #include <ObjexxFCL/FArray2D.hh>
66 #include <basic/options/keys/corrections.OptionKeys.gen.hh>
67 #include <basic/options/keys/in.OptionKeys.gen.hh>
68 #include <basic/options/option.hh>
69 #include <boost/foreach.hpp>
70 
71 //Auto Headers
72 #define foreach BOOST_FOREACH
73 
74 //Auto using namespaces
75 namespace ObjexxFCL { } using namespace ObjexxFCL; // AUTO USING NS
76 //Auto using namespaces end
77 
78 
79 
80 // C++ headers
81 // Commented by inclean daemon #include <iostream>
82 // Commented by inclean daemon #include <sstream>
83 // Commented by inclean daemon #include <fstream>
84 
85 namespace core {
86 namespace chemical {
87 
88 static basic::Tracer tr("core.chemical");
89 
90 
91 // /// must be a better place for this, probably already exists!
92 // inline
93 // std::string
94 // strip_whitespace( std::string const & name )
95 // {
96 // std::string trimmed_name( name );
97 // left_justify( trimmed_name ); trim( trimmed_name ); // simpler way to dothis?
98 // return trimmed_name;
99 // }
100 
101 ///////////////////////////////////////////////////////////////////////////////
102 /// helper fxn
103 
104 id::AtomID
106  std::string const name,
107  ResidueType const & rsd
108 )
109 {
110  using id::AtomID;
111  ICoorAtomID id( name, rsd );
112 
113  switch ( id.type() ) {
115  return AtomID( id.atomno(), 1 );
116  case ICoorAtomID::CONNECT:
117  return AtomID( id.atomno(), 2 );
118  case ICoorAtomID::POLYMER_LOWER:
119  return AtomID( 1, 3 );
120  case ICoorAtomID::POLYMER_UPPER:
121  return AtomID( 2, 3 );
122  default:
123  utility_exit_with_message( "unrecognized stub atom id type!" );
124  }
125  return id::BOGUS_ATOM_ID;
126 }
127 
128 
131  std::string const & filename,
132  chemical::AtomTypeSetCAP atom_types,
133  chemical::ElementSetCAP elements,
134  chemical::MMAtomTypeSetCAP mm_atom_types,
135  chemical::orbitals::OrbitalTypeSetCAP orbital_atom_types,
136 // chemical::CSDAtomTypeSetCAP csd_atom_types kwk commenting out csd_atom_types until I have a chance to fully implement them.
137  chemical::ResidueTypeSetCAP rsd_type_set
138 )
139 {
140  if( ! utility::file::file_exists( filename ) ) {
141  utility_exit_with_message("Cannot find file '"+filename+"'");
142  }
143  utility::io::izstream data( filename.c_str() );
144  if ( !data.good() ) {
145  utility_exit_with_message("Cannot open file '"+filename+"'");
146  }
147  return read_topology_file(data, atom_types, elements, mm_atom_types, orbital_atom_types, rsd_type_set);
148 }
149 
150 ///////////////////////////////////////////////////////////////////////////////
151 /// @details construct a ResidueType from a file. Example files are currently in
152 /// rosetta_database/chemical/residue_type_sets/fa_standard/residue_types/???.params
153 /// These files contain information
154 /// about each basic ResidueType which can be patched to created various
155 /// variant types.
158  utility::io::izstream & data,
159  chemical::AtomTypeSetCAP atom_types,
160  chemical::ElementSetCAP elements,
161  chemical::MMAtomTypeSetCAP mm_atom_types,
162  chemical::orbitals::OrbitalTypeSetCAP orbital_atom_types,
163 // chemical::CSDAtomTypeSetCAP csd_atom_types kwk commenting out until they have been fully implemented
164  chemical::ResidueTypeSetCAP rsd_type_set
165 )
166 {
167  using id::AtomID;
168  using id::DOF_ID;
169  using numeric::conversions::radians;
170  using numeric::conversions::degrees;
171 
172  using namespace basic;
173 
174  std::string filename = data.filename();
175  // read the file
176  std::string line;
178  {
179 // utility::io::izstream data( filename );
180  while ( getline( data, line ) ) {
181  std::istringstream l( line );
182  //if ( line.size() < 1 || line[0] == '#' ) continue;
183  if ( line.size() < 1 ) continue;
184  std::string::size_type pound= line.find('#', 0);
185  if( pound == std::string::npos ) lines.push_back( line );
186  else{
187  std::string no_comment_line= line.substr(0, pound);
188  lines.push_back(no_comment_line);
189  }
190  }
191  tr.Debug << "Read " << lines.size() << " lines from file: " <<
192  filename << std::endl;
193  data.close();
194  }
195 
196 
197  // decide what type of Residue to instantiate
198  // would scan through for the TYPE line, to see if polymer or ligand...
199  //
200  // Residue needs a pointer to the AtomTypeSet object for setting up
201  // atom-type dependent data
202  //
203  // You may be asking yourself, at least I was, why the hell do we scan this file more than once?
204  // The problem is that while reading the params (topology file), we need to assign private member variable
205  // data in ResidueType. We want to make sure that we get the correct number of atoms assigned
206  // before we start adding bonds, icoor, etc. This allows to provide checks to make sure certain
207  // things are being assigned correctly, ie adding bonds correctly, setting icoor values with correct placement
208  // of stub atoms, etc etc.
209 
210  ResidueTypeOP rsd( new ResidueType( atom_types, elements, mm_atom_types, orbital_atom_types ) ); //kwk commenting out until atom types are fully implemented , csd_atom_types ) );
211  rsd->residue_type_set( rsd_type_set ); // give this rsd_type a backpointer to its set
212 
213  // add the atoms
214  Size const nlines( lines.size() );
215  Size natoms(0);//, norbitals(0);
216  for (Size i=1; i<= nlines; ++i ) {
217  std::string line( lines[i] );
218  if (line.size() > 0) {
219  while (line.substr(line.size()-1) == " ") {
220  line = line.substr(0,line.size()-1);
221  if (line.size() == 0) break;
222  }
223  }
224 
225  std::istringstream l( line );
226  std::string tag;
227 
228  l >> tag;
229  // if ( line.size() < 5 || line.substr(0,5) != "ATOM " ) continue;
230  if ( tag != "ATOM" ) continue;
231 
232  // the atom name for this atom
233  std::string const atom_name( line.substr(5,4) );
234  l >> tag; // std::string const atom_name( tag );
235 
236  // the atom type name -- must match one of the atom types
237  // for which force-field parameters exist
238  // std::string const atom_type_name( line.substr(10,4) );
239  l >> tag; std::string const atom_type_name( tag );
240 
241  // read in the Molecular mechanics atom type
242  // std::string const mm_atom_type_name( line.substr(15,4) );
243  l >> tag; std::string const mm_atom_type_name( tag );
244 
245  // the atomic charge
246  float charge;
247  // std::istringstream l( line.substr(20) );
248  l >> charge;
249  float parse_charge(charge);
250  if (!l.eof()) {
251  l >> parse_charge;
252  }
253 
254  if ( ! basic::options::option[ basic::options::OptionKeys::corrections::chemical::parse_charge ]() ) {
255  rsd->add_atom( atom_name, atom_type_name, mm_atom_type_name, charge );
256  }
257  else {
258  rsd->add_atom( atom_name, atom_type_name, mm_atom_type_name, parse_charge );
259  }
260 
261  ++natoms;
262  }
263 
264  // No ATOM lines probably means an invalid file. Perhaps someone made a mistake with an -extra_res_fa flag.
265  // Fail gracefully now, versus a segfault later.
266  if(natoms == 0) {
267  utility_exit_with_message("Residue topology file '" + filename + "' does not contain valid ATOM records.");
268  }
269 
270  // add the bonds, parse rest of file
271  bool found_AA_record = false;
272  bool found_PDB_ROTAMERS_record = false;
273  std::string pdb_rotamers_filename = "";
274  for (Size i=1; i<= nlines; ++i ) {
275  std::string const & line( lines[i] );
276  std::istringstream l( line );
277  std::string tag,atom1,atom2,atom3,atom4, rotate, orbitals_tag, orbital;
278  l >> tag;
279  if ( l.fail() ) continue;
280  if ( tag == "CONNECT" ) {
281  l >> atom1;
282  l >> rotate; // not used here
283  rsd->add_residue_connection( atom1);
284  //std::cout << "CONNECT record deprecated " << std::endl;
285  } else if ( tag == "TYPE" ) {
286  // will probably handle this differently later on
287  l >> tag;
288  if ( tag == "POLYMER" ) {
289  rsd->add_property( tag );
290  } else if ( tag == "LIGAND" ) {
291  rsd->add_property( tag );
292  }
293  // want to know if we're a polymer for other setup decisions
294 // } else if ( tag == "CSD_TYPE" ) { //kwk commenting out until CSD types have been fully implemented
295 // l >> atom1 >> atom2;
296 // rsd->set_csd_atom_type( atom1, atom2 );
297 //
298  } else if ( tag == "BOND" ) {
299  l >> atom1 >> atom2;
300  rsd->add_bond( atom1, atom2 );
301 
302  } else if ( tag == "CUT_BOND" ) {
303  l >> atom1 >> atom2;
304  rsd->add_cut_bond( atom1, atom2 );
305 
306  } else if ( tag == "CHI" ) {
307  Size chino;
308  l >> chino >> atom1 >> atom2 >> atom3 >> atom4;
309  rsd->add_chi( chino, atom1, atom2, atom3, atom4 );
310  } else if ( tag == "PROTON_CHI") {
311  Size chino, nsamples, nextra_samples;
312  std::string dummy;
313  l >> chino;
314  l >> dummy; // should be "SAMPLES"
315  l >> nsamples;
316  utility::vector1< Real > samples( nsamples );
317  for ( Size ii = 1; ii <= nsamples; ++ii ) {
318  l >> samples[ ii ];
319  }
320  l >> dummy; // should be "EXTRA"
321  l >> nextra_samples;
322  utility::vector1< Real > extra_samples( nextra_samples );
323  for ( Size ii = 1; ii <= nextra_samples; ++ii ) {
324  l >> extra_samples[ ii ];
325  }
326  rsd->set_proton_chi( chino, samples, extra_samples );
327 
328  } else if ( tag == "NBR_ATOM" ) {
329  l >> atom1;
330  rsd->nbr_atom( atom1 );
331 
332  } else if ( tag == "NBR_RADIUS" ) {
333  Real radius;
334  l >> radius;
335  rsd->nbr_radius( radius );
336  } else if ( tag == "ORIENT_ATOM" ) {
337  l >> tag;
338  if ( tag == "NBR" ) {
339  rsd->force_nbr_atom_orient(true);
340  } else if ( tag == "DEFAULT" ) {
341  rsd->force_nbr_atom_orient(false);
342  } else {
343  utility_exit_with_message("Unknown ORIENT_ATOM mode: " + tag );
344  }
345  } else if ( tag == "PROPERTIES" ) {
346  l >> tag;
347  while ( !l.fail() ) {
348  rsd->add_property( tag );
349  l >> tag;
350  }
351 
352  } else if ( tag == "VARIANT" ) {
353  l >> tag;
354  while ( !l.fail() ) {
355  rsd->add_variant_type( tag );
356  l >> tag;
357  }
358  } else if ( tag == "FIRST_SIDECHAIN_ATOM" ) {
359  // note-- atoms are sidechain by default
360  l >> tag;
361  if ( tag == "NONE" ) {
362  // set all atoms to backbone
363  for ( Size j=1; j<= rsd->natoms(); ++j ) {
364  rsd->set_backbone_heavyatom( rsd->atom_name(j) );
365  }
366  } else if ( rsd->has( tag ) ) {
367  for ( Size j=1; j< rsd->atom_index( tag ); ++j ) {
368  rsd->set_backbone_heavyatom( rsd->atom_name(j) );
369  }
370  }
371 
372  } else if ( tag == "IO_STRING" ) {
373  assert( line.size() >= 15 );
374  std::string const three_letter_code( line.substr(10,3) ),
375  one_letter_code( line.substr(14,1) );
376  rsd->name3( three_letter_code );
377  rsd->name1( one_letter_code[0] );
378 
379  } else if ( tag == "AA" ) {
380  l >> tag;
381  rsd->aa( tag );
382  found_AA_record = true;
383 
384  } else if ( tag == "ROTAMER_AA" ) {
385  l >> tag;
386  rsd->rotamer_aa( tag );
387 
388  } else if ( tag == "NAME" ) {
389  l >> tag;
390  rsd->name( tag );
391 
392  } else if ( tag == "CHI_ROTAMERS" ) {
393  Size chino;
394  Real mean, sdev;
395  l >> chino;
396  l >> mean >> sdev;
397  while ( !l.fail() ) {
398  rsd->add_chi_rotamer( chino, mean, sdev );
399  l >> mean >> sdev;
400  }
401  } else if ( tag == "PDB_ROTAMERS" ) {
402  found_PDB_ROTAMERS_record = true;
403  l >> pdb_rotamers_filename;
404  } else if ( tag == "ACT_COORD_ATOMS" )
405  {
406  while ( l ) {
407  l >> atom1;
408  if ( atom1 == "END") break;
409  rsd->add_actcoord_atom( atom1 );
410  }
411  } else if ( tag == "LOWER_CONNECT" ) {
412  l >> atom1;
413  rsd->set_lower_connect_atom( atom1 );
414  } else if ( tag == "UPPER_CONNECT" ) {
415  l >> atom1;
416  rsd->set_upper_connect_atom( atom1 );
417  } else if ( tag == "ADDUCT" ) {
418  std::string adduct_name, adduct_atom_name, adduct_atom_type, adduct_mm_type;
419  Real adduct_q, adduct_d, adduct_theta, adduct_phi;
420  l >> adduct_name >> adduct_atom_name;
421  l >> adduct_atom_type >> adduct_mm_type;
422  l >> adduct_q >> adduct_phi >> adduct_theta >> adduct_d;
423  l >> atom1 >> atom2 >> atom3;
424  ObjexxFCL::lowercase(adduct_name);
425  Adduct new_adduct( adduct_name, adduct_atom_name,
426  adduct_atom_type, adduct_mm_type, adduct_q,
427  adduct_phi, adduct_theta, adduct_d,
428  atom1, atom2, atom3 );
429  rsd->add_adduct( new_adduct );
430  } else if ( tag == "NCAA_ROTLIB_PATH" ) {
431  std::string path;
432  l >> path;
433  rsd->set_ncaa_rotlib_path( path );
434  rsd->set_use_ncaa_rotlib( true );
435  } else if ( tag == "NCAA_ROTLIB_NUM_ROTAMER_BINS" ) {
436  Size n_rots(0);
437  utility::vector1<Size> n_bins_per_rot;
438  l >> n_rots;
439  rsd->set_ncaa_rotlib_n_rotameric_bins( n_rots );
440  n_bins_per_rot.resize( n_rots );
441  for( Size i = 1; i <= n_rots; ++i ) {
442  Size bin_size(0);
443  l >> bin_size;
444  n_bins_per_rot[i] = bin_size;
445  }
446  rsd->set_ncaa_rotlib_n_bin_per_rot( n_bins_per_rot );
447  } /*else if( tag== "ORBITALS" ){ //begin parsing orbital information
448  if(basic::options::option[ basic::options::OptionKeys::in::add_orbitals]){
449 
450 
451  l >> orbitals_tag; //looking at the second set of text of the params file
452  if(orbitals_tag == "BOND"){ //add pseudo bonds that will be used for iccor
453  l >> atom1 >> orbital;
454  rsd->add_orbital_bond( atom1, orbital );
455  } else if( orbitals_tag == "ICOOR_INTERNAL"){
456  Real phi, theta, d;
457  std::string child_atom(""), parent_atom(""), angle_atom(""), torsion_atom("");
458  l >> child_atom >> phi >> theta >> d >> parent_atom >> angle_atom >> torsion_atom;
459 
460  phi = radians(phi); theta = radians(theta);
461  rsd->set_orbital_icoor_id(child_atom, phi, theta, d, parent_atom, angle_atom, torsion_atom);
462  }
463  else { //assign the name of the orbital and the orbital type. This actually happens first
464  std::string orbital_type_name("");
465  //std::string orbital_name(l);
466  //
467 
468  l >> orbital_type_name; //the orbital type, which is defined in OrbitalType.hh
469 
470  rsd->add_orbital( orbitals_tag, orbital_type_name); //orbitals tag is the name of the orbital
471  ++norbitals;
472  }
473  }
474 
475  }*/
476 
477  } // i=1,nlines
478 
479  //rsd->print_bonded_orbitals(); check to see if orbitals are being bonded
480 
481 
482  if ( !found_AA_record ) {
483  basic::Warning() << "No AA record found for " << rsd->name() << "; assuming " << name_from_aa( rsd->aa() ) << std::endl;
484  }
485 
486 
487  // set icoor coordinates, store information about polymer links
488  // also sets up base_atom
489  {
490 
491  std::map< std::string, Vector > rsd_xyz;
492 
493  for ( Size i=1; i<= nlines; ++i ) {
494 
495  std::string const & line( lines[i] );
496  std::istringstream l( line );
497  std::string tag, child_atom, parent_atom, angle_atom, torsion_atom;
498 
499  Real phi, theta, d;
500  l >> tag;
501 
502  if ( tag != "ICOOR_INTERNAL" ) continue;
503 
504  l >> child_atom >> phi >> theta >> d >> parent_atom >> angle_atom >> torsion_atom;
505 
506  phi = radians(phi); theta = radians(theta); // in degrees in the file for human readability
507 
508  //This code should probably be extracted to a util function
509  if ( natoms > 1 ) {
510  /// build the cartesian coords for the new atom:
511  if ( child_atom == parent_atom ) {
512  assert( rsd_xyz.empty() ); // first atom
513  rsd_xyz[ child_atom ] = Vector( 0.0 );
514 
515  } else if ( child_atom == angle_atom ) {
516  assert( rsd_xyz.size() == 1 && rsd_xyz.count( parent_atom ) ); // second atom
517  rsd_xyz[ child_atom ] = Vector( d, 0.0, 0.0 );
518 
519  } else {
520  Vector torsion_xyz;
521  if ( child_atom == torsion_atom ) {
522  assert( rsd_xyz.size() == 2 );
523  assert( rsd_xyz.count( parent_atom ) );
524  assert( rsd_xyz.count( angle_atom ) ); // third atom
525  torsion_xyz = Vector( 1.0, 1.0, 0.0 );
526  } else {
527  assert( rsd_xyz.count( parent_atom ) && rsd_xyz.count( angle_atom ) && rsd_xyz.count( torsion_atom ) );
528  torsion_xyz = rsd_xyz[ torsion_atom ];
529  }
530  kinematics::Stub const stub( rsd_xyz[ parent_atom ], rsd_xyz[ angle_atom ], torsion_xyz );
531  rsd_xyz[ child_atom ] = stub.spherical( phi, theta, d );
532  }
533  }
534 
535 
536  // set atom_base
537  if ( child_atom != "UPPER" && child_atom != "LOWER" && child_atom.substr(0,4) != "CONN" ) {
538  // atom base only valid for genuine atoms of this residue
539  if ( child_atom == parent_atom ) {
540  // root of the tree
541  if ( natoms == 1 ) {
542  rsd->set_atom_base( child_atom, child_atom ); // 1st child of root atom
543  } else {
544  rsd->set_atom_base( child_atom, angle_atom ); // 1st child of root atom
545  }
546  } else {
547  rsd->set_atom_base( child_atom, parent_atom );
548  }
549  }
550 
551  // set icoor
552  rsd->set_icoor( i, child_atom, phi, theta, d, parent_atom, angle_atom, torsion_atom );
553 
554 
555  } // loop over file lines looking for ICOOR_INTERNAL lines
556 
557 
558  // fill in the rsd-xyz values
559  if ( natoms == 1 ) {
560  std::string const name( rsd->atom_name(1) );
561  rsd->set_ideal_xyz( name, Vector(0.0) );
562 
563  } else {
564  // now fill in the icoor values -- in principle the rsd itself could be doing this...
565  for ( Size i=1; i<= natoms; ++i ) {
566  std::string name( rsd->atom_name(i) );
567  strip_whitespace( name );
568  assert( rsd_xyz.count( name ) );
569  rsd->set_ideal_xyz( name, rsd_xyz[ name ] );
570  //rsd->set_xyz( rsd->atom_name(i), atom_tree.xyz( id::AtomID(i,1) ) );
571  //rsd->atom(i).xyz( atom_tree.xyz( id::AtomID(i,1) ) );
572  }
573  }
574 
575 
576  // if polymer, fill in upper/lower connect and mainchain info
577  if ( rsd->is_polymer() ) {
578  uint upper_connect( rsd->upper_connect_atom() ), lower_connect( rsd->lower_connect_atom() );
579 
580  // fill in the mainchain info -- shortest path between upper connect and lower connect
581  if ( upper_connect && lower_connect ) {
582  AtomIndices mainchain;
583  FArray2D_int D( get_residue_path_distances( *rsd ) );
584  uint atom( lower_connect );
585  while ( atom != upper_connect ) {
586  mainchain.push_back( atom );
587  AtomIndices const & nbrs( rsd->nbrs( atom ) );
588  int min_d( D( atom, upper_connect ) );
589  uint next_atom( atom );
590  //std::cout << "setup mainchain: " << rsd->name() << ' ' << rsd->atom_name( atom ) << ' ' <<
591  // min_d << std::endl;
592 
593  for ( uint i=1; i<= nbrs.size(); ++i ) {
594  uint const nbr( nbrs[i] );
595  if ( D( nbr, upper_connect ) < min_d ) {
596  min_d = D( nbr, upper_connect );
597  next_atom = nbr;
598  }
599  }
600  assert( next_atom != atom );
601 
602  atom = next_atom;
603  }
604  mainchain.push_back( upper_connect );
605  rsd->set_mainchain_atoms( mainchain );
606  }
607  }
608 
609  ////////////////////////////////////////////////////////
610  ////////////////////////////////////////////////////////
611  ////////////////////////////////////////////////////////
612  ////////////////////////////////////////////////////////
613 
614 
615  // now also need to store the information about the geometry
616  // at the links...
617 
618  } // scope
619 
620 // AtomID
621 // child_atom_id ( atom_id_from_icoor_line( child_atom, *rsd ) ),
622 // parent_atom_id ( atom_id_from_icoor_line( parent_atom, *rsd ) ),
623 // angle_atom_id ( atom_id_from_icoor_line( angle_atom, *rsd ) ),
624 // torsion_atom_id( atom_id_from_icoor_line( torsion_atom, *rsd ) );
625 
626 // bool child_is_bonded_atom( true );
627 // if ( atom_tree.has( parent_atom_id ) ) {
628 // // not the root of the tree
629 // atom_tree.add_atom( child_atom_id, parent_atom_id, child_is_bonded_atom, false /* by xyz */ );
630 // } else {
631 // // root of the tree
632 // child_is_bonded_atom = false;
633 // atom_tree.add_atom( child_atom_id, id::BOGUS_ATOM_ID, child_is_bonded_atom, false /* by xyz */);
634 // }
635 
636 // if ( child_is_bonded_atom ) {
637 // // set the internal coordinates in the atom_tree
638 // atom_tree.set_dof( DOF_ID( child_atom_id, id::THETA ), theta );
639 // atom_tree.set_dof( DOF_ID( child_atom_id, id::D ), d );
640 
641 // if ( ( child_atom_id == angle_atom_id ) || ( child_atom_id == torsion_atom_id ) ) {
642 // // one of the first three atoms in the tree, some internal coords not defined
643 // assert( std::abs( phi ) < 1e-3 );
644 // atom_tree.set_dof( DOF_ID( child_atom_id, id::PHI ), phi );
645 // } else if ( ( parent_atom_id == angle_atom_id ) ||
646 // ( parent_atom_id == torsion_atom_id ) ||
647 // ( angle_atom_id == torsion_atom_id ) ) {
648 // // this would not be good for set_torsion_angle
649 // // should be special case for single-atom residue
650 // // we are not going to use the xyz's from the atomtree anyhow, so we dont need to do anything
651 // assert( natoms == 1 );
652 // } else {
653 // atom_tree.set_dof( DOF_ID( child_atom_id, id::PHI ), 0.0 /*temporary value*/ );
654 // atom_tree.set_torsion_angle( child_atom_id, parent_atom_id, angle_atom_id, torsion_atom_id, phi );
655 // }
656 // } // is the child atom a bonded atom, ie is it not the root of the tree?
657 
658 
659 
660 // // set icoor coordinates, store information about polymer links
661 // // also sets up base_atom
662 // {
663 // Size root_atomno, anchor_atomno;
664 
665 // bool first_line( true );
666 // for ( Size i=1; i<= nlines; ++i ) {
667 // std::string const & line( lines[i] );
668 // std::istringstream l( line );
669 // std::string tag, child_atom, parent_atom;
670 // Real phi, theta, d;
671 // l >> tag;
672 // if ( tag != "ICOOR_INTERNAL" ) continue;
673 // l >> child_atom >> parent_atom >> phi >> theta >> d;
674 // phi = radians(phi); theta = radians(theta);
675 // // if ( parent_atom[0] == '-' ) {
676 // // assert( rsd->is_polymer() );
677 // // // anchor atom in previous residue
678 // // continue;
679 // // }
680 // Size child_rsd(1), parent_rsd(1);
681 // if ( parent_atom[0] == '-' ) {
682 // continue; // do nothing, temporarily
683 // // parent_rsd = 0;
684 // // parent_atom.erase(0,1);
685 // } else if ( child_atom[0] == '+' ) {
686 // child_rsd = 2;
687 // child_atom.erase(0,1);
688 // } else {
689 // rsd->set_atom_base( child_atom, parent_atom );
690 // if ( first_line ) {
691 // rsd->set_atom_base( parent_atom, child_atom );
692 // }
693 // }
694 
695 // AtomID
696 // child_id ( rsd->atom_index( child_atom ), child_rsd ),
697 // parent_id( rsd->atom_index( parent_atom ), parent_rsd );
698 
699 // if ( first_line ) {
700 // atom_tree.add_atom( parent_id, id::BOGUS_ATOM_ID, false,
701 // false /* by xyz */ );
702 // root_atomno = parent_id.atomno();
703 // first_line = false;
704 // } else if ( child_rsd == 2 ) {
705 // anchor_atomno = parent_id.atomno();
706 // }
707 
708 // atom_tree.add_atom( child_id, parent_id, true /* bonded */,
709 // false /* by xyz */ );
710 // atom_tree.set_dof( DOF_ID( child_id, id::PHI ), phi );
711 // atom_tree.set_dof( DOF_ID( child_id, id::THETA ), theta );
712 // atom_tree.set_dof( DOF_ID( child_id, id::D ), d );
713 // }
714 
715 // if ( rsd->is_polymer() ) {
716 // // fill in the mainchain info
717 // AtomIndices mainchain;
718 // mainchain.push_back( anchor_atomno );
719 // while ( true ) {
720 // anchor_atomno = rsd->atom_base( anchor_atomno );
721 // if ( std::find( mainchain.begin(), mainchain.end(), anchor_atomno ) !=
722 // mainchain.end() ) {
723 // utility_exit_with_message("failure deriving mainchain from atom_base");
724 // }
725 // mainchain.insert( mainchain.begin(), anchor_atomno );
726 // if ( anchor_atomno == root_atomno ) break;
727 // }
728 // rsd->set_mainchain_atoms( mainchain );
729 // }
730 
731 
732 // // fill in the icoor values
733 // for ( Size i=1; i<= natoms; ++i ) {
734 // rsd->atom(i).xyz( atom_tree.xyz( id::AtomID(i,1) ) );
735 // }
736 
737 // // now also need to store the information about the geometry
738 // // at the links...
739 // }
740 
741 
742  // calculate any remaining derived data
743  rsd->finalize();
744 
745  // If we found a PDB_ROTAMERS library, load them now that the ResidueType
746  // is totally initialized:
747  if( found_PDB_ROTAMERS_record ) {
748  using namespace utility::file;
749  // Assume name of rotamers file has no path info, etc
750  // and is in same directory as the residue parameters file.
751  FileName this_file( filename ), rot_file( pdb_rotamers_filename );
752  rot_file.vol( this_file.vol() );
753  rot_file.path( this_file.path() );
754 
755  rsd->set_RotamerLibraryName( rot_file() );
756 
757  tr.Debug << "Setting up conformer library for " << rsd->name() << std::endl;
758  /*using namespace core::pack::dunbrack;
759  using namespace utility::file;
760  SingleLigandRotamerLibraryOP pdb_rotamers = new SingleLigandRotamerLibrary();
761  // Assume name of rotamers file has no path info, etc
762  // and is in same directory as the residue parameters file.
763 
764  pdb_rotamers->init_from_file( rot_file.name(), rsd );
765  rsd->set_RotamerLibrary( pdb_rotamers );*/
766  }
767 
768  return rsd;
769 }
770 
771 
772 /// @brief function to write out a topology file given a residue type, can be used to
773 /// @brief debug on the fly generated residue types. Note: not perfect yet, the enums for
774 /// @brief the connection types are given in numbers instead of names
775 void
777  ResidueType const & rsd
778 )
779 {
780 
781  using numeric::conversions::radians;
782  using numeric::conversions::degrees;
783 
784  std::string filename = rsd.name() + ".params";
785 
786  std::ofstream out( filename.c_str() );
787 
788  out << "#rosetta residue topology file \n";
789  out << "#version ??? \n";
790  out << "#This automatically generated file is not really formatted, but should work, excpet that enums for connection types \n# are given in numbers and not strings. \n";
791 
792  //first write out all the general tags
793  out << "NAME " << rsd.name() << " \n";
794  out << "IO_STRING " << rsd.name3() << " " << rsd.name1() << " \n";
795  if( rsd.is_polymer() ) { out << "TYPE POLYMER \n"; }
796  else if ( rsd.is_ligand() ) { out << "TYPE LIGAND \n"; }
797  else if ( rsd.is_surface() ) { out << "TYPE SURFACE \n"; }
798  out << "AA " << rsd.aa() << " \n";
799 
800  //then write out the atoms
801  for(Size i=1; i <= rsd.natoms(); i++){
802 
803  std::string atom_out = "ATOM " + rsd.atom_name( i ) + " " + rsd.atom_type( i ).name() + " ";
804  atom_out = atom_out + rsd.mm_atom_type(i).name();
805  out << atom_out << " " << rsd.atom(i).charge() << " \n";
806 
807  } //atom write out
808 
809  if( rsd.is_polymer() ) {
810  if( !rsd.is_lower_terminus() ) { out << "LOWER_CONNECT " << rsd.atom_name( rsd.lower_connect().atomno() ) << " \n"; }
811  if( !rsd.is_upper_terminus() ) { out << "UPPER_CONNECT " << rsd.atom_name( rsd.upper_connect().atomno() ) << " \n";}
812  }
813 
814  //then all the bonds
815  for(Size i=1; i <= rsd.natoms(); i++){
816  foreach(Size atom_index, rsd.nbrs(i)){// bond_this_atom
817  if( atom_index > i ) { //don't write out bonds more than once
818  out << "BOND " << rsd.atom_name( i ) << " " << rsd.atom_name( atom_index ) << " \n";
819  }
820  }
821  } // bond write out
822 
823 
824  //now the chis
825  for(Size i=1; i <= rsd.nchi(); i++){
826  out << "CHI " << i ;
827  AtomIndices atoms_this_chi = rsd.chi_atoms( i );
828  for(AtomIndices::iterator at_it = atoms_this_chi.begin(); at_it != atoms_this_chi.end(); at_it++ ){
829  out << " " << rsd.atom_name( *at_it );
830  }
831  out << " \n";
832  } //chi write out
833 
834  //and now the proton chis
835  Size n_proton_chi(0);
836  for(Size i=1; i <= rsd.nchi(); i++){
837  if( rsd.is_proton_chi( i ) ){
838 
839  n_proton_chi++;
840  out << "PROTON_CHI " << i << " SAMPLES ";
841  utility::vector1< Real > pchi_samples = rsd.proton_chi_samples( n_proton_chi );
842  utility::vector1< Real > pchi_extra = rsd.proton_chi_extra_samples( n_proton_chi );
843  out << pchi_samples.size() ;
844  for( Size j = 1; j <= pchi_samples.size(); j++){ out << " " << pchi_samples[j]; }
845  out << " EXTRA " << pchi_extra.size();
846  for( Size j = 1; j <= pchi_extra.size(); j++){ out << " " << pchi_extra[j]; }
847  out << " \n";
848 
849  }
850  }//proton chi write out
851 
852  //now all the properties
853  out << "PROPERTIES";
854  if(rsd.is_protein() ) { out << " PROTEIN"; }
855  if(rsd.is_DNA() ) { out << " DNA"; }
856  if(rsd.is_RNA() ) { out << " RNA"; }
857  if(rsd.is_polar() ) { out << " POLAR"; }
858  if(rsd.is_charged() ) { out << " CHARGED"; }
859  if(rsd.is_aromatic() ) { out << " AROMATIC"; }
860  if(rsd.is_lower_terminus() ) { out << " LOWER_TERMINUS"; }
861  if(rsd.is_upper_terminus() ) { out << " UPPER_TERMINUS"; }
862  if(rsd.is_terminus() ) { out << " TERMINUS"; }
863  out << " \n";
864 
865  out << "NBR_ATOM " << rsd.atom_name( rsd.nbr_atom() ) << " \n";
866  out << "NBR_RADIUS " << rsd.nbr_radius() << " \n";
867  if (rsd.force_nbr_atom_orient()) { out << "ORIENT_ATOM NBR\n"; }
868 
869  //actcoord atoms
870  if( rsd.actcoord_atoms().size() > 0 ){
871  out << "ACT_COORD_ATOMS ";
872  AtomIndices act_atoms = rsd.actcoord_atoms();
873  for(AtomIndices::iterator at_it = act_atoms.begin(); at_it != act_atoms.end(); at_it++ ){
874  out << rsd.atom_name( *at_it ) << " ";
875  }
876  out << "END \n";
877  }
878 
879 
880  //last but not least the internal coordinates
881  for(Size i=1; i <= rsd.natoms(); i++){
882  AtomICoor cur_icoor = rsd.icoor( i );
883  out << "ICOOR_INTERNAL " << rsd.atom_name( i ) << " " << degrees( cur_icoor.phi() ) << " ";
884  out << degrees( cur_icoor.theta() ) << " " << cur_icoor.d();
885  if( ( cur_icoor.stub_atom1().atomno() <= rsd.natoms() ) && ( cur_icoor.stub_atom1().atomno() > 0 ) ) {
886  out << " " << rsd.atom_name( cur_icoor.stub_atom1().atomno() );
887  }
888  else{ out << " " << cur_icoor.stub_atom1().type(); }
889 
890  if( ( cur_icoor.stub_atom2().atomno() <= rsd.natoms() ) && ( cur_icoor.stub_atom2().atomno() > 0 )){
891  out << " " << rsd.atom_name( cur_icoor.stub_atom2().atomno() );
892  }
893  else{ out << " " << cur_icoor.stub_atom2().type();}
894 
895  if( ( cur_icoor.stub_atom3().atomno() <= rsd.natoms() ) && ( cur_icoor.stub_atom3().atomno() > 0 )){
896  out << " " << rsd.atom_name( cur_icoor.stub_atom3().atomno() );
897  }
898  else{ out << " " << cur_icoor.stub_atom3().type() ;}
899 
900  out << " \n";
901 
902  } //atom icoor write out
903 
904  //now write out icoors for connections (polymer, other)
905 
906  //TO DO
907 
908  out.close();
909 
910 } //write_topology_file
911 
912 
913 
914 
915 
916 } // chemical
917 } // core