Rosetta 3.5
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
visualize.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/kinematics/visualize.cc
11 /// @brief 3-D visualizations of FoldTree and AtomTree in kinemage format
12 /// @author Ian W. Davis
13 
14 // Unit headers
16 
17 // Package headers
19 #include <core/kinematics/Edge.hh>
22 
23 // Rosetta headers
24 #include <core/types.hh>
26 #include <core/id/AtomID.hh>
27 #include <core/pose/Pose.hh>
28 #include <basic/Tracer.hh>
29 
30 // ObjexxFCL headers
31 
32 // C++ Headers
33 #include <iostream>
34 #include <fstream>
35 
37 #include <utility/vector0.hh>
38 #include <utility/vector1.hh>
39 
40 
41 namespace protocols {
42 namespace viewer {
43 
44 
45 //////////////////////////////////////////////////////////////////////////////
46 // helper functions private to this file
47 
48 
50  std::ostream & out,
51  int residue_num,
52  int atom_num,
54  std::string extras = "" //< P for points, color, width/radius, etc.
55 )
56 {
57  // atom_num is often 0 in fold tree, means no specific atom.
58  // might as well use the first one:
59  if (atom_num == 0) atom_num = 1;
60  core::conformation::Residue const & res = conf.residue(residue_num);
61  core::chemical::ResidueType const & res_type = conf.residue_type(residue_num);
62  core::conformation::Atom const & atom = res.atom(atom_num);
63  core::chemical::AtomType const & atom_type = res.atom_type(atom_num);
64  // This info appears when you click on the point
65  out << "{" << res_type.name3() << " " << res.seqpos()
66  << " " << res.atom_name(atom_num) << " (" << atom_type.name() << ")"
67  << "}";
68  // Color, width, etc. followed by coordinates
69  out << extras;
70  out << " " << atom.xyz().x() << " " << atom.xyz().y() << " " << atom.xyz().z() << "\n";
71 }
73  std::ostream & out,
74  int residue_num,
75  std::string atom_name,
77  std::string extras = "" //< P for points, color, width/radius, etc.
78 )
79 {
80  // atom_num is often 0 in fold tree, means no specific atom.
81  // might as well use the first one:
82  core::conformation::Residue const & res = conf.residue(residue_num);
83 
84  int atom_num;
85  if (atom_name == "") {
86  atom_num = 1;
87  } else {
88  atom_num = res.atom_index( atom_name );
89  }
90  print_node( out, residue_num, atom_num, conf, extras );
91 }
92 
93 
95  std::ostream & out,
96  core::conformation::Residue const & rsd1,
97  core::conformation::Residue const & rsd2,
99 )
100 {
101  print_node(out, rsd1.seqpos(), rsd1.connect_atom(rsd2), conf, "P");
102  print_node(out, rsd2.seqpos(), rsd2.connect_atom(rsd1), conf);
103 }
104 
105 
107  std::ostream & out,
108  core::conformation::Residue const & rsd,
110 )
111 {
112  // intra-residue connections
113  // do residues in different (~random) colors to help distinguish them
114  int const num_colors = 6;
115  std::string colors[num_colors] = {"pinktint", "peachtint", "yellowtint", "greentint", "bluetint", "lilactint"};
116  std::string color = colors[ rsd.seqpos() % num_colors ];
117  out << "@vectorlist {} color= " << color << " width= 1 master= {intra-res}\n";
118  for(core::Size atom_i = 1; atom_i <= rsd.natoms(); ++atom_i) {
119  core::conformation::Residue::AtomIndices const & nbrs = rsd.nbrs(atom_i);
120  for(core::conformation::Residue::AtomIndices::const_iterator j = nbrs.begin(), end_j = nbrs.end(); j != end_j; ++j) {
121  core::Size atom_j = *j;
122  if(atom_j <= atom_i) continue; // so we draw each bond just once, not twice
123  print_node(out, rsd.seqpos(), atom_i, conf, "P");
124  print_node(out, rsd.seqpos(), atom_j, conf);
125  }
126  }
127  // inter-residue connections
128  // there *has* to be a better way of getting next/prev residue...
129  out << "@vectorlist {} color= gray width= 1 master= {inter-res}\n";
130  core::chemical::ResidueType const & res_type = rsd.type();
131  if (rsd.seqpos() > 1 && rsd.is_bonded( conf.residue(rsd.seqpos()-1) )) {
132  print_interres_bond(out, rsd, conf.residue(rsd.seqpos()-1), conf);
133  }
134  if ((core::Size)rsd.seqpos() < conf.size() && rsd.is_bonded( conf.residue(rsd.seqpos()+1) )) {
135  print_interres_bond(out, rsd, conf.residue(rsd.seqpos()+1), conf);
136  }
137  for(core::Size i = 1; i <= res_type.n_residue_connections(); ++i) {
138  print_interres_bond(out, rsd, conf.residue( rsd.residue_connection_partner(i) ), conf);
139  }
140 }
141 
142 
143 /// @brief A better way to visualize the structure is use Prekin
144 /// or KiNG's File | Import | Molecules command.
146  std::ostream & out,
148 )
149 {
150  out << "@subgroup {by residue} dominant\n";
151  for(core::Size i = 1; i <= conf.size(); ++i) {
152  dump_residue_kinemage(out, conf.residue(i), conf);
153  }
154 }
155 
156 
158  std::ostream & out,
159  core::kinematics::FoldTree const & fold_tree,
161 )
162 {
163  out << "@arrowlist {true} color= gold width=3 radius= 0.6 off\n";
164  core::kinematics::FoldTree::const_iterator i = fold_tree.begin(), i_end = fold_tree.end();
165  for( ; i != i_end; ++i) {
166  //std::cout << i->start() << "," << i->start_atom() << " --> " << i->stop() << "," << i->stop_atom() << std::endl;
167  print_node(out, i->start(), i->start_atom(), conf, "P");
168  if ( i->is_jump() ) print_node(out, i->stop(), i->stop_atom(), conf, "width6");
169  else print_node(out, i->stop(), i->stop_atom(), conf);
170  }
171 
172  out << "@arrowlist {res-by-res} color= lime radius= 0.6\n";
173  i = fold_tree.begin(), i_end = fold_tree.end();
174  for( ; i != i_end; ++i) {
175  if ( i->is_jump() ) {
176  print_node(out, i->start(), i->start_atom(), conf, "P");
177  print_node(out, i->stop(), i->stop_atom(), conf, "width4");
178  } else {
179  print_node(out, i->start(), 0, conf, "P");
180  // start res num may be greater or less than stop res num:
181  int dir = (i->start() < i->stop() ? 1 : -1);
182  for(int j = i->start()+dir, j_end = i->stop()+dir; j != j_end; j+=dir ) {
183  print_node(out, j, 0, conf);
184  }
185  }
186  }
187 }
188 
189 
191  std::ostream & out,
192  core::kinematics::tree::Atom const & katom,
194 )
195 {
196  // Easier to just do point-line all the time than to try and see if
197  // previous line was drawn to our parent (it rarely will be).
198 
199  if (katom.parent().get() != NULL) {
200  core::id::AtomID const & p_atom_id = katom.parent()->atom_id();
201  int p_residue_num = p_atom_id.rsd();
202  int p_atom_num = p_atom_id.atomno();
203  print_node(out, p_residue_num, p_atom_num, conf, "P");
204  }
205 
206  core::id::AtomID const & atom_id = katom.atom_id();
207  int residue_num = atom_id.rsd();
208  int atom_num = atom_id.atomno();
209  if (katom.is_jump()) print_node(out, residue_num, atom_num, conf, "width4");
210  else print_node(out, residue_num, atom_num, conf);
211 
212  // Recursively visit child atoms
214  for( ; i != i_end; ++i) visit_atomtree_node(out, **i, conf);
215 }
216 
217 
219  std::ostream & out,
220  core::kinematics::AtomTree const & atom_tree,
222 )
223 {
224  out << "@arrowlist {true} color= orange\n";
225  core::kinematics::tree::Atom const & root = *( atom_tree.root() );
226  visit_atomtree_node(out, root, conf);
227 }
228 
229 
230 //////////////////////////////////////////////////////////////////////////////
231 // public functions
232 
233 void
235  std::string const filename,
236  core::pose::Pose const & pose
237 )
238 {
239  std::ofstream out (filename.c_str());
240  if (!out.good()) {
241  basic::Error() << "Can't open kinemage file " << filename << std::endl;
242  return;
243  }
244  out << "@text\n";
245  out << "View this file with KiNG or Mage from http://kinemage.biochem.duke.edu\n";
246  out << "@kinemage 1\n";
247  out << "@onewidth\n";
248  out << "@group {structure}\n";
250  out << "@group {fold tree} animate\n";
251  dump_foldtree_kinemage(out, pose.fold_tree(), pose.conformation());
252  out << "@group {atom tree} animate\n";
253  dump_atomtree_kinemage(out, pose.atom_tree(), pose.conformation());
254  out.close();
255 }
256 
257 
258 } // namespace viewer
259 } // namespace protocols
260