Rosetta 3.5
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
ConstraintIO.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 IO-functionality for Constraints
11 /// @brief
12 /// @author Oliver Lange olange@u.washington.edu
13 
14 // Unit headers
16 
17 // Package headers
19 //#include <core/scoring/constraints/ConstraintForest.hh>
23 //#include <core/scoring/constraints/BindingSiteConstraint.hh>
29 // AUTO-REMOVED #include <core/scoring/constraints/MixtureFunc.hh>
30 // AUTO-REMOVED #include <core/scoring/constraints/ScalarWeightedFunc.hh>
31 
32 #include <basic/options/option.hh>
33 #include <basic/options/keys/constraints.OptionKeys.gen.hh>
34 
35 // Project headers
36 #include <core/types.hh>
38 #include <core/pose/Pose.hh>
39 #include <core/pose/PDBInfo.hh>
40 #include <core/id/AtomID.hh>
41 // AUTO-REMOVED #include <utility/excn/Exceptions.hh>
42 
43 // Utility Headers
44 #include <utility/pointer/ReferenceCount.hh>
45 #include <utility/io/izstream.hh>
46 #include <utility/io/ozstream.hh>
47 
48 #include <basic/Tracer.hh>
49 
50 #include <utility/vector1.hh>
51 
52 
53 static basic::Tracer tr("core.io.constraints");
54 
55 namespace core {
56 namespace scoring {
57 namespace constraints {
58 
59 ConstraintIO*
61  if ( instance_ == 0 ) {
62  instance_ = new ConstraintIO();
63  }
64  return instance_;
65 }
66 
68  return func_factory_;
69 }
70 
73 }
74 
77 //ConstraintFactory ConstraintIO::cst_factory_;
78 
79 
80 void
82  std::istream & data,
83  std::string & next_section_name,
84  ConstraintSet & cst_set,
85  pose::Pose const & pose
86 ) {
87  tr.Debug << "ConstraintIO::read_cst_atom_pairs" << std::endl;
88  std::string line;
89  while( getline( data, line ) ) {
90  Size res1, res2;
91  std::string tempres1, tempres2;
92  std::string name1, name2;
93  std::string func_type;
94  std::string type;
95  std::istringstream line_stream( line );
96  line_stream
97  >> name1 >> tempres1
98  >> name2 >> tempres2
99  >> func_type;
100 
101  parse_residue( pose, tempres1, res1 );
102  parse_residue( pose, tempres2, res2 );
103 
104  if ( name1.find("[" )!=std::string::npos ) { //end of this section
105  tr.Debug << "section end detected in line " << line << std::endl;
106  next_section_name = line;
107  return;
108  }
109  tr.Debug << "read: " << name1 << " " << name2 << " "
110  << res1 << " " << res2 << " func: " << func_type
111  << std::endl;
112 
113  if ( res1>pose.total_residue() || res2> pose.total_residue() ||
114  ( !pose.residue_type( res1 ).has_atom_name( name1 ) ) ||
115  ( !pose.residue_type( res2 ).has_atom_name( name2 ) )
116  ){
117 
118  tr.Error << "error in constraint (no such atom in pose!)"
119  << name1 << " " << name2 << " " << res1 << " " << res2 << " func: " << func_type << std::endl;
120  utility_exit_with_message ("Constraint data referred to atom which is not present in pose");
121  }
122 
123 
124  id::AtomID atom1( pose.residue_type( res1 ).atom_index( name1 ), res1 );
125  id::AtomID atom2( pose.residue_type( res2 ).atom_index( name2 ), res2 );
126 
127  FuncOP aFunc = func_factory_.func_types_[ func_type ]->clone();
128  aFunc->read_data( line_stream );
129 
130  if ( tr.Debug.visible() ) {
131  aFunc->show_definition( tr.Debug ); tr.Debug << std::endl;
132  }
133 
134  cst_set.add_constraint( new AtomPairConstraint( atom1, atom2, aFunc ) );
135  } // while getline
136  tr.Debug << "end of file reached" << std::endl;
137  next_section_name = "";
138 }
139 
141  std::istream & data,
142  core::pose::Pose pose
143 ) {
144  Size res1, res2;
145  std::string tempres1, tempres2;
146  std::string name1, name2;
147  std::string func_type;
148  std::string type;
149 
150  data
151  >> name1 >> tempres1
152  >> name2 >> tempres2
153  >> func_type;
154 
155  parse_residue( pose, tempres1, res1 );
156  parse_residue( pose, tempres2, res2 );
157 
158  tr.Info << "read: " << name1 << " " << name2 << " "
159  << res1 << " " << res2 << " func: " << func_type
160  << std::endl;
161  if ( res1>pose.total_residue() || res2> pose.total_residue() ) {
162  tr.Warning << "ignored constraint (no such atom in pose!)"
163  << name1 << " " << name2 << " " << res1 << " " << res2 << std::endl;
164  return NULL;
165  }
166 
167  id::AtomID atom1( pose.residue_type( res1 ).atom_index( name1 ), res1 );
168  id::AtomID atom2( pose.residue_type( res2 ).atom_index( name2 ), res2 );
169 
170  FuncOP aFunc = func_factory_.func_types_[ func_type ]->clone();
171  aFunc->read_data( data );
172 
173  if ( tr.Debug.visible() ) {
174  aFunc->show_definition( tr.Debug ); tr.Debug<<std::endl;
175  }
176 
177  ConstraintOP cst_op( new AtomPairConstraint( atom1, atom2, aFunc ) );
178  return cst_op;
179 } // parse_atom_pair_constraint
180 
181 void
183  std::istream & data,
184  std::string & next_section_name,
185  ConstraintSet & cst_set,
186  pose::Pose const & pose
187 ) {
188 
189  tr.Debug << "ConstraintIO::read_cst_coordinate" << std::endl;
190  std::string line;
191  while( getline( data, line ) ) {
192 
193  Real x, y, z;
194  Size res1, res2;
195  std::string name1, name2;
196  std::string func_type;
197  std::string type;
198 
199  std::istringstream line_stream( line );
200 
201  line_stream
202  >> name1;
203 
204  if ( name1.find("[" )!=std::string::npos ) { //end of this section
205  tr.Debug << "section end detected in line " << line << std::endl;
206  next_section_name = line;
207  return;
208  }
209 
210  line_stream >> res1
211  >> name2 >> res2
212  >> x >> y >> z
213  >> func_type;
214 
215  tr.Debug << "read: " << name1 << " " << name2 << " "
216  << res1 << " " << res2 << " func: " << func_type
217  << std::endl;
218 
219  if ( res1>pose.total_residue() || res2> pose.total_residue() ||
220  ( !pose.residue_type( res1 ).has_atom_name( name1 ) ) ||
221  ( !pose.residue_type( res2 ).has_atom_name( name2 ) )
222  ){
223  tr.Error << "error in constraint (no such atom in pose!)"
224  << name1 << " " << name2 << " " << res1 << " " << res2 << " func: " << func_type << std::endl;
225  utility_exit_with_message ("Constraint data referred to atom which is not present in pose");
226  }
227 
228 
229  id::AtomID atom1( pose.residue_type( res1 ).atom_index( name1 ), res1 );
230  id::AtomID atom2( pose.residue_type( res2 ).atom_index( name2 ), res2 );
231 
232  FuncOP aFunc = func_factory_.func_types_[ func_type ]->clone();
233  aFunc->read_data( line_stream );
234 
235  // if ( tr.Debug.visible() ) {
236  aFunc->show_definition( std::cout ); std::cout<<std::endl;
237  // }
238 
239  Vector transform( x, y, z );
240  cst_set.add_constraint( new CoordinateConstraint( atom1, atom2, transform, aFunc ) );
241 
242  } // while getline
243  tr.Debug << "end of file reached" << std::endl;
244  next_section_name = "";
245 }
246 
248  std::istream & data,
249  core::pose::Pose pose
250 ) {
251  Real x, y, z;
252  Size fixed_res, other_res;
253  std::string tempfixed_res, tempother_res;
254  std::string fixed_res_name, other_res_name;
255  std::string func_type;
256  std::string type;
257 
258  data
259  >> fixed_res_name >> tempfixed_res
260  >> other_res_name >> tempother_res
261  >> x >> y >> z
262  >> func_type;
263 
264  parse_residue( pose, tempfixed_res, fixed_res );
265  parse_residue( pose, tempother_res, other_res );
266 
267  tr.Debug << "read: " << fixed_res_name << " " << other_res_name << " "
268  << fixed_res << " " << other_res << " func: " << func_type << std::endl;
269  if ( fixed_res > pose.total_residue() || other_res > pose.total_residue() ) {
270  tr.Warning << "ignored constraint (no such atom in pose!)"
271  << fixed_res_name << " " << other_res_name << " "
272  << fixed_res << " " << other_res << std::endl;
273  return NULL;
274  }
275 
276  id::AtomID atom1( pose.residue_type( fixed_res ).atom_index( fixed_res_name ), fixed_res );
277  id::AtomID atom2( pose.residue_type( other_res ).atom_index( other_res_name ), other_res );
278 
279  FuncOP aFunc = func_factory_.func_types_[ func_type ]->clone();
280  aFunc->read_data( data );
281 
282  if ( tr.Debug.visible() ) {
283  aFunc->show_definition( tr.Debug ); tr.Debug << std::endl;
284  }
285 
286  Vector transform( x, y, z );
287  ConstraintOP cst_op( new CoordinateConstraint( atom1, atom2, transform, aFunc ) );
288  return cst_op;
289 } // parse_coordinate_constraint
290 
291 
292 void
294  std::istream & data,
295  std::string & next_section_name,
296  ConstraintSet & cst_set,
297  pose::Pose const & pose
298 ) {
299  tr.Debug << "ConstraintIO::read_cst_angles" << std::endl;
300  std::string line;
301  while( getline( data, line ) ) {
302  Size res1, res2, res3;
303  std::string tempres1, tempres2, tempres3;
304  std::string name1, name2, name3;
305  std::string func_type;
306  std::string type;
307  std::istringstream line_stream( line );
308  line_stream
309  >> name1 >> tempres1
310  >> name2 >> tempres2
311  >> name3 >> tempres3
312  >> func_type;
313 
314  parse_residue( pose, tempres1, res1 );
315  parse_residue( pose, tempres2, res2 );
316  parse_residue( pose, tempres3, res3 );
317 
318  if ( name1.find("[" )!=std::string::npos ) { //end of this section
319  tr.Debug << "section end detected in line " << line << std::endl;
320  next_section_name = line;
321  return;
322  }
323  id::AtomID atom1( pose.residue_type( res1 ).atom_index( name1 ), res1 );
324  id::AtomID atom2( pose.residue_type( res2 ).atom_index( name2 ), res2 );
325  id::AtomID atom3( pose.residue_type( res3 ).atom_index( name3 ), res3 );
326 
327  tr.Debug << "read: " << name1 << " " << res1 << " " << name2 << " "
328  << res2 << " " << name3 << " " << res3 << std::endl;
329  FuncOP aFunc = func_factory_.func_types_[ func_type ]->clone();
330  aFunc->read_data( line_stream );
331 
332  if ( tr.Debug.visible() ) {
333  aFunc->show_definition( tr.Debug ); tr.Debug<<std::endl;
334  }
335 
336  if ( res1 > pose.total_residue() || res2 > pose.total_residue() || res3 > pose.total_residue() ) {
337  tr.Warning << "ignored constraint" << name1 << " " << name2 << " "
338  << res1 << " " << res2 << std::endl;
339  continue;
340  }
341 
342  cst_set.add_constraint( new AngleConstraint( atom1, atom2, atom3, aFunc ) );
343  }// while getline
344  tr.Debug << "end of file reached" << std::endl;
345  next_section_name = "";
346 }
347 
348 /*
349 void
350 ConstraintIO::read_cst_bindingsites(
351  std::istream & data,
352  std::string & next_section_name,
353  ConstraintSet & cst_set,
354  pose::Pose const & pose
355 ) {
356  tr.Debug << "ConstraintIO::read_cst_angles" << std::endl;
357  std::string line;
358  while( getline( data, line ) ) {
359  Size res;
360  std::string tempres;
361  std::string name;
362  std::istringstream line_stream( line );
363 
364  if ( line.find("[" )!=std::string::npos ) { //end of this section
365  tr.Debug << "section end detected in line " << line << std::endl;
366  next_section_name = line;
367  return;
368  }
369 
370  // to do? atm name -> centroid conversion
371  utility::vector1< id::AtomID > atms;
372  tr.Debug << "read: ";
373  while ( line_stream >> name >> tempres ) {
374 
375  parse_residue( pose, tempres, res );
376 
377  tr.Debug << " " << name << " " << res ;
378 
379  atms.push_back( id::AtomID( pose.residue_type( res ).atom_index( name ), res ) );
380  if ( res > pose.total_residue() ) {
381  tr.Debug << "** ignored **";
382  continue;
383  }
384  }
385  tr.Debug << std::endl;
386 
387  cst_set.add_constraint( new BindingSiteConstraint( atms , pose ) );
388  }// while getline
389  tr.Debug << "end of file reached" << std::endl;
390  next_section_name = "";
391 }
392 */
393 
396  if ( line.size() == 0 ) return line;
397  std::istringstream line_stream( line );
398  std::string tok;
399  line_stream >> tok;
400  int start = 0;
401  if ( tok == "[" ) { //
402  line_stream >> tok;
403  start = 0;
404  } else {
405  std::string::size_type start = tok.find("[");
406  if ( start != 0 ) return "NO_SECTION";
407  //utility_exit_with_message (" reading constraints file, expected: [ section ] ");
408  start = 1;
409  }
410 
411  std::string::size_type loc = tok.find("]");
412  if ( loc != std::string::npos ) {
413  return tok;
414  } else {
415  return tok.substr(start,loc);
416  }
417 }
418 
419 void
421  std::istream & data,
422  std::string & next_section_name,
423  ConstraintSet & cst_set,
424  pose::Pose const & pose
425 ) {
426  tr.Debug << "ConstraintIO::read_cst_angles" << std::endl;
427  std::string line;
428  while( getline( data, line ) ) {
429  //mjo commenting out 'res' because it is unused and causes a warning
430  //Size res;
431  std::string name;
432  std::istringstream line_stream( line );
433  if ( line.find("[" )!=std::string::npos ) { //end of this section
434  tr.Debug << "section end detected in line " << line << std::endl;
435  next_section_name = line;
436  return;
437  }
438 
439  // to do? atm name -> centroid conversion
440  /*utility::vector1< id::AtomID > atms;
441  tr.Debug << "read: ";
442  while ( line_stream >> name >> res ) {
443  tr.Debug << " " << name << " " << res ;
444  atms.push_back( id::AtomID( pose.residue_type( res ).atom_index( name ), res ) );
445  if ( res > pose.total_residue() ) {
446  tr.Debug << "** ignored **";
447  continue;
448  }
449  }
450  tr.Debug << std::endl;
451  cst_set.add_constraint( new BindingSiteConstraint( atms , pose ) );*/
452 
454  bsc->read_def( line_stream, pose, get_func_factory() );
455  cst_set.add_constraint( bsc );
456  }// while getline
457  tr.Debug << "end of file reached" << std::endl;
458  next_section_name = "";
459 }
460 
462  std::istream & data,
463  ConstraintSetOP cset,
464  pose::Pose const& pose
465 ) {
466  std::string line;
467  std::streampos original_pos = data.tellg();
468  getline(data,line); // header line
470  std::string pre_read;
471  while ( section.size() ) {
472  tr.Info << "read constraints section --" << section << "---" << std::endl;
473  if ( section == "atompairs" ) {
474  read_cst_atom_pairs( data, pre_read, *cset, pose );
475  } else if ( section == "coordinates" ) {
476  read_cst_coordinates( data, pre_read, *cset, pose );
477  } else if ( section == "angles" ) {
478  read_cst_angles( data, pre_read, *cset, pose );
479  } else if ( section == "bindingsites" ) {
480  read_cst_bindingsites( data, pre_read, *cset, pose );
481  } else if ( section == "NO_SECTION" ) {
482  tr.Info << " no section header [ xxx ] found, try reading line-based format... DON'T MIX"
483  << std::endl;
484  /// izstreams cannot be rewound with seekg()
485  /// never call this function if you have constructed an izstream
486  /// and you haven't deteremined that indeed the file format its representing
487  /// is the old style (as opposed to the new style) constraint format.
488  assert( dynamic_cast< zlib_stream::zip_istream * > ( &data ) == 0 );
489 
490  data.seekg( original_pos );
491  return read_constraints_new( data, cset, pose );
492  } else { //section header, but unknown name
493  utility_exit_with_message(
494  "constraint-file: section " + section + " not recognized!"
495  );
496  }
497  tr.Trace << "pre_read: " << pre_read << std::endl;
498  section = get_section_name ( pre_read );
499  }
500 // pose.constraint_set( cset );
501  return cset;
502 }
503 
504 /// @details All the heavy lifting is done by read_constraints( istream &, ConstraintSetOP, Pose const & ), or
505 /// by read_constraints_new( istream &, ConstraintSetOP, Pose const & ), but the logic for deciding which of
506 /// two execution paths to follow that lives inside read_constraints( isteam &, ... ) will not work if given
507 /// an izstream constructed from a zipped file. SO instead, we check the file format of the input constraint
508 /// file here and then rewind to the beginning of the file using the izstream seek_beg() function.
511  std::string const & fname,
512  ConstraintSetOP cset,
513  pose::Pose const & pose
514 ) {
515  utility::io::izstream data( fname.c_str() );
516  tr.Info << "read constraints from " << fname << std::endl;
517  if ( !data ) {
518  utility_exit_with_message( "[ERROR] Unable to open constraints file: "+ fname );
519  }
520 
521  std::string line;
522  getline(data,line); // header line
524  data.seek_beg();
525  if ( section == "NO_SECTION" ) {
526  return read_constraints_new( data, cset, pose );
527  } else {
528  return read_constraints( data, cset, pose );
529  }
530 
531  return read_constraints( data, cset, pose );
532 } // read_constraints
533 
534 /////////////////////////////////////////////////////////////////////////////////////////////////////
535 /// @details read in constraints with new format from a file
538  std::string const & fname,
539  ConstraintSetOP cset,
540  pose::Pose const & pose
541 ) {
542  utility::io::izstream data( fname.c_str() );
543  tr.Info << "read constraints from " << fname << std::endl;
544  if ( !data ) {
545  utility_exit_with_message("[ERROR] Unable to open constraints file: " + fname );
546  }
547  return read_constraints_new( data, cset, pose );
548 }
551  std::istream & data,
552  ConstraintSetOP cset,
553  pose::Pose const & pose
554 ) {
555  Size count_constraints(0);
556  while( data.good() ) { // check if we reach the end of file or not
557  // read in each constraint and add it constraint_set
558  ConstraintOP cst_op;
559  cst_op = read_individual_constraint_new( data, pose, get_func_factory() );
560  if ( cst_op ) {
561  ++count_constraints;
562  cset->add_constraint( cst_op );
563  } else if ( ! data.eof() ) { // not end of line
564  tr.Error << "ERROR: reading constraints from file" << std::endl;
565  break;
566  }
567  } // while
568  tr.Info << "Read in " << count_constraints << " constraints" << std::endl;
569  return cset;
570 } // read_constraints_new
571 
574  std::istream & data,
575  pose::Pose const& pose,
576  FuncFactory const & func_factory,
577  std::string tag
578 )
579 {
580  ConstraintOP cst_op;
581  cst_op = get_cst_factory().newConstraint( tag );
582 
583  std::string error_msg("");
584  // bool error_seen( false );
585 
586  if ( cst_op ) {
587  // try {
588  cst_op->read_def( data, pose, func_factory );
589  // } catch ( utility::excn::EXCN_Exception &excn ) {
590 // tr.Error << "ERROR: reading of " + tag + " failed.\n" << excn << std::endl;
591 // cst_op = NULL;
592  //}
593  if ( !data.good() && !data.eof()) {
594  error_msg += "ERROR: reading of " + tag + " failed.\n";
595  tr.Error << error_msg << std::endl;
596  cst_op = NULL;
597  }
598  } else {
599  error_msg += "ERROR: constraint type " + tag + " not known.\n";
600  tr.Error << error_msg << std::endl;
601  cst_op = NULL;
602  }
603  if ( !cst_op ) {
604  using namespace basic::options;
605  using namespace basic::options::OptionKeys;
606  if ( option[ OptionKeys::constraints::exit_on_bad_read ]() ) { //OL Aug 12 2010,
607  //changed option default from 'true' to 'false'. This was way confusing!
608  //hard exits can be rather annoying... after waiting for 24h in the queue of a cluster.
609  utility_exit_with_message( error_msg );
610  }
611  }
612  return cst_op;
613 }
614 
615 ////////////////////////////////////////////////////////////////////////////////////////////////////
616 /// @details read in each individual constraint. The constraints could be single-line ones such as AtomPair,
617 /// Angle and Diehedral, or multi-line ones such as Multiconstraint and Ambiguous. Return owing pointer of the
618 /// constraint if read in successfully, otherwise return NULL. Identify the type of constraint and call
619 /// each constraint's read_def function to finish reading. Skip lines beginning with '#' or '\n'
620 /// May be called recursively in the case of Multiconstraint and AmbiguousConstraint.
621 /// @note the istream data should point to the beginning of a line when this function is called.
624  std::istream & data,
625  pose::Pose const& pose,
626  FuncFactory const & func_factory
627 )
628 {
629  std::string tag, dummy_line;
630  // get the ConstraintType tag
631  while( true ) {
632  char c = data.peek(); // get first char of the line but not moving istream pointer
633  if ( c == '#' || c == '\n' ) { //ignore # comment line and empty line
634  while( data.good() && (data.get() != '\n') ) {}
635  continue;
636  }
637  if ( data.eof() ) return NULL;
638  data >> tag;
639  if ( data.fail() ) {
640  tr.Error << "can't read constraint type" << std::endl;
641  return NULL;
642  }
643  break;
644  }
645  if (( tag.substr(0,3) == "END" )||( tag.substr(0,3) == "End" )) return NULL; // stopper for MultiConstraint or AmbiguousConstraint
646  return read_individual_constraint_new( data, pose, func_factory, tag );
647 }
648 ////////////////////////////////////////////////////////////////////////////////////////////////////
649 void
650 ConstraintIO::write_constraints( std::ostream& out, ConstraintSet const& cst_set, pose::Pose const& pose ) {
651  cst_set.show_definition( out, pose );
652 }
653 
654 void
656  utility::io::ozstream dump_cst( filename );
657  write_constraints( dump_cst, cst_set, pose );
658 }
659 
660 
661 //ConstraintForestOP
662 //ConstraintIO::read_constraint_forest( std::string const & fname, pose::Pose & pose ) {
663 // utility::io::izstream data( fname.c_str() );
664 // tr.Info << "read ConstraintForest from " << fname << std::endl;
665 // if ( !data ) {
666 // utility_exit_with_message( "[ERROR] Unable to open ConstraintForest file: "+fname );
667 // }
668 //
669 // ConstraintForestOP cf = new ConstraintForest();
670 // cf->read_forest(data, pose);
671 // return cf;
672 //}
673 
674 
675 void
676 ConstraintIO::parse_residue( pose::Pose const& pose, std::string const residue_string, Size & residue_num )
677 {
678  std::stringstream data;
679  char chain;
680  Size resnum;
681 
682  data.str( residue_string );
683 
684  data >> resnum;
685 
686  if ( !(data >> chain).fail() ) {
687  residue_num = pose.pdb_info()->pdb2pose( chain, resnum );
688  } else residue_num = resnum;
689 }
690 
691 } //constraints
692 } //scoring
693 } //core
694