Rosetta 3.5
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
read_patchdock.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 devel/protein_interface_design/design_utils.cc
11 /// @brief various utilities for interface design.
12 /// @author Sarel Fleishman (sarelf@u.washington.edu)
13 
14 // Project Headers
16 #include <core/pose/Pose.hh>
21 #include <basic/Tracer.hh>
22 
23 #include <numeric/random/random.hh>
24 
25 // Utility Headers
26 #include <utility/vector1.hh>
27 #include <ObjexxFCL/string.functions.hh>
28 #include <utility/io/izstream.hh>
29 
30 // Unit Headers
31 
32 // C++ headers
33 #include <map>
34 
35 // option key includes
36 #include <basic/options/option.hh>
37 #include <basic/options/keys/out.OptionKeys.gen.hh>
38 #include <basic/options/keys/parser.OptionKeys.gen.hh>
39 #include <basic/options/keys/in.OptionKeys.gen.hh>
40 
41 #include <numeric/xyz.functions.hh>
42 
43 
44 
45 using namespace core;
46 using namespace core::scoring;
47 
48 static basic::Tracer TR( "protocols.protein_interface_design.read_patchdock" );
49 static numeric::random::RandomGenerator RG( 15031972 ); // <- Magic number, do not change it!!!
50 
52 {
53  typedef core::Real Real;
54 
55  Real alpha, beta, gamma; // Euler angles
57 };
58 
59 namespace protocols {
60 namespace protein_interface_design {
61 
62 PatchdockReader::PatchdockReader(){
63  clear_internals();
64 }
65 PatchdockReader::~PatchdockReader() {}
66 
67 void
68 PatchdockReader::clear_internals()
69 {
70  patchdock_fname_ = "";
71  patchdock_entry_num_ = 0;
72  saved_input_tag_ = "";
73  saved_native_tag_ = "";
74  saved_input_pose_ = saved_native_pose_ = NULL;
75  saved_transformations_.clear();
76 }
77 
78 ///@detailed how many entries are there in the patchdock file?
80 PatchdockReader::number_of_patchdock_entries()
81 {
82  core::Size const saved_patchdock_entry_num( patchdock_entry_num_ );
83  patchdock_entry_num_ = 1; // to ensure validity of patchdock_entry_num_
84  read_patchdock_entry(); // to ensure that saved_transformations_ is set
85  patchdock_entry_num_ = saved_patchdock_entry_num;
86  return( saved_transformations_.size() );
87 }
88 
89 ///@detailed read a rigid-body transformation from a patchdock file.
90 /// caches transformations in saved_transformations_ to avoid multiple disk access
92 PatchdockReader::read_patchdock_entry()
93 {
94  runtime_assert( patchdock_entry_num_ );
95  if( saved_transformations_.size() )
96  return( saved_transformations_[ patchdock_entry_num_ ] );
97 
98  utility::io::izstream data( patchdock_fname_ );
99  if ( !data )
100  utility_exit_with_message( "Cannot open patchdock file: " + patchdock_fname_ );
101 
102  std::string line;
103  bool entries_found( false );
104  while ( getline( data, line ) ) {
105  using namespace std;
106 
108  t.alpha = t.beta = t.gamma = 0;
109  t.translation.zero() ;
110 
111  istringstream line_stream( line );
112  string first_field;
113  line_stream >> first_field;
114 
115  if( first_field == "#" ) { entries_found = true; continue; }
116  if( !entries_found ) continue;
117  core::Size const wheres_pipe( line.find_first_of( "|" ) );
118  if( wheres_pipe == string::npos ) break;; // no longer reading entries
119  core::Size const transformation_begin( line.find_last_of( "||" ) + 2 );
120  std::istringstream transData( line.substr( transformation_begin, 10000) );
121  core::Real x,y,z;
122  transData >> t.alpha >> t.beta >> t.gamma >> x >> y >> z;
123  if( transData.fail() ) {
124  TR<<"Error parsing transformation data in line\n"<<line<<std::endl;
125  runtime_assert( !transData.fail() );
126  }
127  t.translation.assign( x, y, z );
128  saved_transformations_.push_back( t );
129  }
130  return( saved_transformations_[ patchdock_entry_num_ ] );
131 }
132 
133 //@detailed transform a chain within the pose according to t. The transformation computed here is
134 //based on patchdock's transOutput.pl and pdb_trans
135 void
137 {
138  core::Size const chain_begin( pose.conformation().chain_begin( chain ) );
139  core::Size const chain_end( pose.conformation().chain_end( chain ) );
140 
142  { //compute rotation matrix (taken from RBSMover), but here expecting radian rather than degrees
143  core::Real const sa ( std::sin( t.alpha ));
144  core::Real const ca ( std::cos( t.alpha ));
145  core::Real const sb ( std::sin( t.beta ));
146  core::Real const cb ( std::cos( t.beta ));
147  core::Real const sg ( std::sin( t.gamma ));
148  core::Real const cg ( std::cos( t.gamma ));
149 // Adapted from code sent by Dina Schneidman of the Wolfson lab (Tel-Aviv U)
150  rotation.xx( cg * cb ); rotation.xy( -sb*sa*cg - sg * ca ); rotation.xz( -sb*ca*cg + sg * sa );
151  rotation.yx( sg * cb ); rotation.yy( -sb*sa*sg + ca*cg ); rotation.yz( -sb*ca*sg - sa*cg );
152  rotation.zx( sb ); rotation.zy( cb*sa ); rotation.zz( cb*ca );
153  }//compute rotation
154 
155 //rotate each atom around the geometric centre of the chain
156  for( core::Size residue=chain_begin; residue<=chain_end; ++residue ) {
157  core::Size const atom_begin( 1 );
158  core::Size const atom_end( pose.residue( residue ).natoms() );
159 
160  numeric::xyzVector< core::Real > localX, localRX;
161  for( core::Size atom=atom_begin; atom<=atom_end; ++atom ) {
162  id::AtomID const id( atom, residue );
163 
164  localX = pose.xyz( id );
165  localRX = rotation * localX;
166  pose.set_xyz( id, localRX );
167  }
168  }
169 
170 //translate
171  for( core::Size residue=chain_begin; residue<=chain_end; ++residue ) {
172  core::Size const atom_begin( 1 );
173  core::Size const atom_end( pose.residue( residue ).natoms() );
174 
175  for( core::Size atom=atom_begin; atom<=atom_end; ++atom ) {
176  id::AtomID const id( atom, residue );
177 
178  numeric::xyzVector< core::Real > const new_pos( pose.xyz( id ) + t.translation );
179  pose.set_xyz( id, new_pos );
180  }
181  }
182  // detect disulfides
183  using basic::options::option;
184  using namespace basic::options::OptionKeys;
185  if ( option[ in::detect_disulf ].user() ?
186  option[ in::detect_disulf ]() : // detect_disulf true
187  pose.is_fullatom() // detect_disulf default but fa pose
188  )
189  {
191  }
192 }
193 
194 void
195 PatchdockReader::read_poses( core::pose::Pose & input_pose, std::string & input_tag )
196 {
197  core::pose::Pose dummy_pose;
198  std::string dummy_tag( input_tag );
199 
200  read_poses( input_pose, dummy_pose, input_tag, dummy_tag );
201 }
202 
203 void
204 PatchdockReader::read_patchdock( std::string & input_tag, std::string & native_tag )
205 {
206  using namespace basic::options;
207  using namespace basic::options::OptionKeys;
208 
209  patchdock_entry_num_ = 0;
210  patchdock_fname_ = "";
211  bool const patchdock( option[ parser::patchdock ].user() );
212  if( patchdock ) {
213  patchdock_fname_ = option[ parser::patchdock ]();
214  if( patchdock_fname_ == "" ) { // use default patchdock fname ( 1jjj_2xxx.pdb.gz -> 1jjj_2xxx.patchdock )
215  core::Size const filename_end( input_tag.find_first_of( "." ) );
216 
217  patchdock_fname_ = input_tag.substr( 0, filename_end ) + ".patchdock";
218  }
219  TR<<"Reading from patchdock file name: "<<patchdock_fname_<<std::endl;
220  bool const patchdock_random_entry( option[ parser::patchdock_random_entry ].user() );
221  core::Size const number_of_entries = number_of_patchdock_entries();
222  if( number_of_entries == 0 )
223  utility_exit_with_message_status( "No patchdock entries found. Aborting", 0 );
224  if( patchdock_random_entry ) {
225  utility::vector1< core::Size > entry_num_extrema = option[ parser::patchdock_random_entry ]();
226 
227  runtime_assert( entry_num_extrema.size() == 2 );
228  runtime_assert( entry_num_extrema[ 1 ] <= entry_num_extrema[ 2 ] );
229  runtime_assert( entry_num_extrema[ 1 ] > 0 );
230 
231  TR<<number_of_entries<<" entries in patchdock file "<<patchdock_fname_<<std::endl;
232  entry_num_extrema[ 2 ] = std::min( entry_num_extrema[ 2 ], number_of_entries );
233  TR<<"sampling a number between "<<entry_num_extrema[ 1 ]<<" and "<<entry_num_extrema[ 2 ]<<std::endl;
234 
235  patchdock_entry_num_ = ( core::Size ) floor( RG.uniform() * ( entry_num_extrema[ 2 ] - entry_num_extrema[ 1 ] ) ) + entry_num_extrema[ 1 ];
236  runtime_assert( patchdock_entry_num_ <= entry_num_extrema[ 2 ] );
237  runtime_assert( patchdock_entry_num_ >= entry_num_extrema[ 1 ] );
238  std::stringstream ss;
239  ss << "." << patchdock_entry_num_;
240  option[ out::user_tag ].value( ss.str() ); // to set the output tag
241  }
242  else{
243  core::Size const entrynum_begin( input_tag.find_first_of( "." ) );
244  core::Size const entrynum_end( input_tag.find_last_of( "." ) );
245  std::stringstream ss( input_tag.substr( entrynum_begin+1, entrynum_end - entrynum_begin ) );
246  ss >> patchdock_entry_num_;
247  if( patchdock_entry_num_ > number_of_entries ){
248  TR<<"number of patchdock entries exceeded. You've asked for entry "<< patchdock_entry_num_<<" but only "<<number_of_entries<<" entries were found"<<std::endl;
249  utility_exit_with_message_status("aborting.", 0 );
250  }
251  if( input_tag == native_tag ){
252  input_tag.replace( entrynum_begin, entrynum_end - entrynum_begin + 1, "." );
253  native_tag.replace( entrynum_begin, entrynum_end - entrynum_begin + 1, "." );
254  }
255  }
256  }
257 }
258 
259 //@details transform an input pdb according to patchdock parameters
260 //if patchdock option is not set, return as is.
261 /// If the native and input tags match those saved in the object, then the
262 /// pose will not be read again from disk. Only the patchdock entry will be read.
263 void
264 PatchdockReader::read_poses( core::pose::Pose & input_pose, core::pose::Pose & native_pose, std::string & input_tag, std::string & native_tag )
265 {
266  using namespace basic::options;
267  using namespace basic::options::OptionKeys;
268 
269  if( saved_input_tag_ == input_tag && saved_native_tag_ == native_tag )
270  {//we've already read this pose, do not go to disk again
271  input_pose = *saved_input_pose_;
272  native_pose = *saved_native_pose_;
273  TR<<"Skipped reading pose from disk"<<std::endl;
274  }
275  else{
276  clear_internals();
277  saved_input_tag_ = input_tag;
278  saved_native_tag_ = native_tag;
279  TR<<"Reading pose from disk"<<std::endl;
280  if ( option[ in::file::centroid_input ].user() ) {
281  core::import_pose::centroid_pose_from_pdb( input_pose, input_tag );
282  core::import_pose::centroid_pose_from_pdb( native_pose, native_tag );
283  } else {
286 
287  core::import_pose::pose_from_pdb( input_pose, *rsd_set, input_tag );
288  core::import_pose::pose_from_pdb( native_pose, *rsd_set, native_tag );
289  }//else
290  if( option[ in::file::fold_tree ].user() ){
291  std::string const fold_tree_fname( option[ in::file::fold_tree ]() );
292  utility::io::izstream data( fold_tree_fname );
293  if ( !data ) {
294  TR << "Cannot open file: " << fold_tree_fname << std::endl;
295  runtime_assert( data );
296  }
297  std::string line;
298  bool ft_found( false );
299  while( getline( data, line ) ){
300  if( line.substr(0,10) == "FOLD_TREE " ){
301  std::istringstream line_stream( line );
303  line_stream >> f;
304  input_pose.fold_tree( f );
305  native_pose.fold_tree( f );
306  ft_found = true;
307  TR<<"Using user-defined fold-tree:\n"<<input_pose.fold_tree()<<std::endl;
308  break;
309  }//IF FOLD_TREE
310  }//getline
311  runtime_assert( ft_found );
312  }//option foldtree
313 
314  saved_input_pose_ = new core::pose::Pose( input_pose );
315  saved_native_pose_ = new core::pose::Pose( native_pose );
316  }//else
317 
318  read_patchdock( input_tag, native_tag );
319 
320  if( !patchdock_entry_num_ ) return; // no need for transformations
321  TR<<"Reading patchdock entry "<<patchdock_entry_num_<<" from file: "<<patchdock_fname_<<std::endl;
322  Transformation t( read_patchdock_entry() );
323 
324  transform_pose( input_pose, 2/*chain*/, t );
325  transform_pose( native_pose, 2, t );
326  TR.flush();
327 }
328 
329 }//protein_interface_design
330 }//protocols
331