Rosetta 3.5
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
selection.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 core/pose/selection.cc
11 /// @brief pose residue selections
12 /// @author Sarel Fleishman (sarelf@u.washington.edu)
13 /// @author Jacob Corn (jecorn@u.washington.edu)
14 /// @author Rocco Moretti (rmoretti@u.washington.edu)
15 /// @author Eva-Maria Strauch (evas01@uw.edu)
16 
17 // Unit Headers
18 #include <core/pose/selection.hh>
19 // Project Headers
20 
21 #include <core/types.hh>
24 #include <core/pose/Pose.hh>
25 #include <core/pose/PDBPoseMap.hh>
26 #include <core/pose/PDBInfo.hh>
28 #include <boost/foreach.hpp>
29 #define foreach BOOST_FOREACH
30 
31 // Utility Headers
32 #include <basic/Tracer.hh>
33 #include <utility/string_util.hh>
34 #include <utility/vector1.hh>
35 #include <utility/tag/Tag.hh>
36 
37 #include <utility/vector0.hh>
38 
39 
40 static basic::Tracer TR( "core.pose.selection" );
41 
42 namespace core {
43 namespace pose {
44 
45 using namespace core::scoring;
46 using namespace core;
47 using namespace std;
48 using utility::vector1;
49 
50 /// @brief a convenience function to test whether the user has specified pdb numbering rather than rosetta numbering.
52 get_resnum( utility::tag::TagPtr const tag_ptr, core::pose::Pose const & pose, std::string const & prefix/*=""*/ ) {
53  core::Size resnum( 0 );
54  bool const pdb_num_used( tag_ptr->hasOption( prefix + "pdb_num" ) );
55  if( pose.pdb_info().get() == NULL ){//no pdbinfo for this pose (e.g., silent file), resort to using just the residue number
56  if( pdb_num_used ){
57  TR<<"Bad tag: "<< *tag_ptr<<std::endl;
58  utility_exit_with_message( "pdb_num used but no pdb_info found. Use res_num instead" );
59  return( 0 );
60  }
61  }
62  else{
63  core::pose::PDBPoseMap const pose_map( pose.pdb_info()->pdb2pose() );
64  if( pdb_num_used ) {
65  std::string pdbnum( tag_ptr->getOption<std::string>( prefix + "pdb_num" ) );
66  char const chain( pdbnum[ pdbnum.length() - 1 ] );
67  std::stringstream ss( pdbnum.substr( 0, pdbnum.length() - 1 ) );
68  core::Size number;
69  ss >> number;
70  resnum = pose_map.find( chain, number );
71  }
72  }
73  if( !pdb_num_used )
74  resnum = tag_ptr->getOption<core::Size>( prefix + "res_num" );
75 
76  runtime_assert( resnum );
77  return( resnum );
78 }
79 
80 /// @brief Extracts a residue number from a string.
81 /// @detail Recognizes two forms of numbering:
82 /// - Rosetta residue numbers (numbered sequentially from 1 to the last residue
83 /// in the pose). These have the form [0-9]+
84 /// - PDB numbers. These have the form [0-9]+[A-Z], where the trailing letter
85 /// is the chain ID.
86 /// @return the rosetta residue number for the string, or 0 upon an error
89  std::string const& resnum,
90  core::pose::Pose const& pose)
91 {
92 
93  string::const_iterator input_end = resnum.end();
94  //Set number to the sequence of digits at the start of input [0-9]*
95  string::const_iterator number_start = resnum.begin();
96  string::const_iterator number_end = resnum.begin();
97  while( number_end != input_end && *number_end >= '0' && *number_end <= '9' ) {
98  ++number_end;
99  }
100  //Set chain to the following characters
101  string::const_iterator chain_start = number_end;
102  string::const_iterator chain_end = number_end;
103  while( chain_end != input_end
104  && (('A' <= *chain_end && *chain_end <= 'Z') ||
105  ('a' <= *chain_end && *chain_end <= 'z') ||
106  '_' == *chain_end ) )
107  {
108  ++chain_end;
109  }
110 
111  string number(number_start,number_end);
112  string chain(chain_start,chain_end);
113 
114  //Require that the whole string match, and that the chain be a single char
115  if( chain_end != input_end || chain.size() > 1 || number.size() < 1) {
116  TR.Error << "Could not parse '" << resnum << "' into a residue number." << std::endl;
117  return Size(0);
118  }
119 
120  Size n;
121  std::istringstream ss( number );
122  ss >> n;
123  if( chain.size() == 1 ) { // PDB Number
124  TR.Trace << "Interpretting " << n << chain << " as a pdb number." << std::endl;
125  pose::PDBInfoCOP info = pose.pdb_info();
126  runtime_assert(info);
127  return info->pdb2pose( chain[0], n );
128  }
129  else { // Rosetta Number
130  TR.Trace << "Interpreting " << n << " as a Rosetta residue number." << std::endl;
131  return n;
132  }
133 }
134 
135 /// @brief Extracts residue numbers from a 'selection'.
136 /// @detail Recognizes two forms of numbering:
137 /// - Rosetta residue numbers (numbered sequentially from 1 to the last residue
138 /// in the pose). These have the form [0-9]+
139 /// - PDB numbers. These have the form [0-9]+[A-Z], where the trailing letter
140 /// is the chain ID.
141 /// - name3=ALA selects all alanines
142 /// @return the rosetta residue numbers for the string, or 0 upon an error
145  std::string const& sele,
146  core::pose::Pose const& pose
147 ){
149  if(sele.size()==9&&sele.substr(0,6)=="name3="){
150  string name3 = sele.substr(6,3);
151  for(Size ir=1; ir <= pose.n_residue(); ++ir) {
152  if(pose.residue(ir).name3()==name3){
153  res.push_back(ir);
154  }
155  }
156  } else {
157  res.push_back(parse_resnum(sele,pose));
158  }
159  return res;
160 }
161 
162 
163 /// @brief Extracts a list of residue numbers from a tag.
164 /// @details The tag should contain a comma-separated list of numbers, in either
165 /// pdb or rosetta format (@see parse_resnum for details)
168  utility::tag::TagPtr const tag_ptr,
169  string const& tag,
170  pose::Pose const& pose
171 ){
172  vector1< Size > resnums;
173  if( ! tag_ptr->hasOption( tag ) ) {
174  TR<<"Error: No "<<tag<<" option was found in tag "<<tag_ptr<<std::endl;
175  utility_exit();
176  return resnums;
177  }
178  set<Size> const resnums_set( get_resnum_list( tag_ptr->getOption< std::string >( tag ), pose ) );
179  resnums.clear();
180  resnums.insert( resnums.begin(), resnums_set.begin(), resnums_set.end() );
181  sort( resnums.begin(), resnums.end() );
182  unique( resnums.begin(), resnums.end() );
183 
184  return resnums;
185 }
186 
187 set<Size>
189  std::string const str,
190  core::pose::Pose const & pose
191 ){
192  using namespace std;
193  using namespace utility;
194  set< Size > resid;
195 
196  resid.clear();
197  vector1< string> const str_residues( utility::string_split( str , ',' ) );
198  foreach( string const res, str_residues ){
199  if( res == "" ) continue;
200  if( res.find('-') != string::npos) {
201  // Handle residue range
202  vector1< string> const str_limits( utility::string_split( res , '-' ) );
203  if ( str_limits.size() == 2) {
204  core::Size const start ( parse_resnum( str_limits[1], pose ) );
205  core::Size const end ( parse_resnum( str_limits[2], pose ) );
206  if ( start && end && start > end ) {
207  utility_exit_with_message("Invalid residue range: " + res);
208  }
209  for(core::Size i = start; i <= end; ++i )
210  resid.insert( i );
211  continue;
212  }
213  }
214  utility::vector1<core::Size> const nums( parse_selection_block( res, pose ) );
215  for(utility::vector1<core::Size>::const_iterator i = nums.begin(); i != nums.end(); ++i){
216  Size num = *i;
217  runtime_assert( num );
218  resid.insert( num );
219  }
220  }//foreach
221  return resid;
222 }
223 
224 
225 // fpd same as 'get_resnum_list', but preserve ordering from input list
228  std::string const str,
229  core::pose::Pose const & pose
230 ){
231  using namespace std;
232  using namespace utility;
234 
235  resid.clear();
236  vector1< string> const str_residues( utility::string_split( str , ',' ) );
237  foreach( string const res, str_residues ){
238  if( res == "" ) continue;
239  if( res.find('-') != string::npos) {
240  // Handle residue range
241  vector1< string> const str_limits( utility::string_split( res , '-' ) );
242  if ( str_limits.size() == 2) {
243  core::Size const start ( parse_resnum( str_limits[1], pose ) );
244  core::Size const end ( parse_resnum( str_limits[2], pose ) );
245  if ( start && end && start > end ) {
246  utility_exit_with_message("Invalid residue range: " + res);
247  }
248  for(core::Size i = start; i <= end; ++i )
249  resid.push_back( i );
250  continue;
251  }
252  }
253  utility::vector1<core::Size> const nums( parse_selection_block( res, pose ) );
254  for(utility::vector1<core::Size>::const_iterator i = nums.begin(); i != nums.end(); ++i){
255  Size num = *i;
256  runtime_assert( num );
257  resid.push_back( num );
258  }
259  }//foreach
260  return resid;
261 }
262 
263 } //pose
264 } //core