Rosetta
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
MolecularSurfaceCalculator.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/scoring/sc/ShapeComplementarityCalculator.cc
11 /// @brief Implementation of molecular surface calculation for shape complementarity.
12 /// @details Lawrence & Coleman shape complementarity calculator (based on CCP4's sc)
13 /// @author Luki Goldschmidt <luki@mbi.ucla.edu>, refactored by Alex Ford (fordas@uw.edu)
14 
15 /// This code was ported from the original Fortran code found in CCP4:
16 /// Sc (Version 2.0): A program for determining Shape Complementarity
17 /// Copyright Michael Lawrence, Biomolecular Research Institute
18 /// 343 Royal Parade Parkville Victoria Australia
19 ///
20 #ifndef INCLUDED_core_scoring_sc_MolecularSurfaceCalculator_cc
21 #define INCLUDED_core_scoring_sc_MolecularSurfaceCalculator_cc
22 
23 // Project Headers
25 
26 #include <core/types.hh>
27 #include <core/pose/Pose.hh>
29 #include <core/kinematics/Jump.hh>
33 #include <numeric/xyzVector.hh>
34 #include <numeric/NumericTraits.hh>
35 
36 // Utility headers
37 #include <utility/vector1.hh>
38 #include <utility/exit.hh>
39 #include <utility/io/izstream.hh>
40 #include <basic/Tracer.hh>
41 #include <basic/database/open.hh>
42 
43 // C headers
44 #include <stdio.h>
45 
46 // C++ headers
47 #include <iostream>
48 #include <ostream>
49 #include <fstream>
50 #include <vector>
51 #include <map>
52 #include <string>
53 
54 static THREAD_LOCAL basic::Tracer TR( "core.scoring.sc.MolecularSurfaceCalculator" );
55 
56 using namespace core;
57 
58 namespace core {
59 namespace scoring {
60 namespace sc {
61 
62 std::vector<ATOM_RADIUS> MolecularSurfaceCalculator::radii_; // static const
63 
64 ////////////////////////////////////////////////////////////////////////////
65 // Public class functions
66 ////////////////////////////////////////////////////////////////////////////
67 
68 /// @brief
69 /// MolecularSurfaceCalculator constructor, initializes default settings
70 
72 {
73  memset(&settings, 0, sizeof(settings));
74 
75  // Defaults from sc source
76  settings.rp = 1.7;
77  settings.density = 15.0;
78  settings.band = 1.5;
79  settings.sep = 8.0;
80  settings.weight = 0.5;
81  settings.binwidth_dist = 0.02;
82  settings.binwidth_norm = 0.02;
83 
84  Reset();
85 }
86 
87 /// @brief
88 /// Initializes calculation and GPU (if used)
89 /// Init() is also called implicitly by the static CalcSc() function.
90 
92 {
93  if ( radii_.empty() ) {
94  ReadScRadii();
95  }
96  if ( radii_.empty() ) {
97  return 0;
98  }
99 
100  return 1;
101 }
102 
104 {
105  Reset();
106 }
107 
108 /// @brief
109 /// Reset calculator for another calculation.
110 /// Must be used when the MolecularSurfaceCalculator instance is re-used.
111 /// @details
112 /// Atom, probe and surface dot vectors are reset here. We don't clear them
113 /// after the calculation is finished in case the caller would like to use those
114 /// data elsewhere.
115 
117 {
118  // Free data
119  for ( std::vector<Atom>::iterator a = run_.atoms.begin(); a < run_.atoms.end(); ++a ) {
120  a->neighbors.clear();
121  a->buried.clear();
122  }
123 
124  // Clear structures
125  run_.atoms.clear();
126  run_.probes.clear();
127  run_.dots[0].clear();
128  run_.dots[1].clear();
129 
130  memset(&run_.results, 0, sizeof(run_.results));
131  memset(&run_.prevp, 0, sizeof(run_.prevp));
132  run_.prevburied = 0;
133 }
134 
135 /// @brief Generate molecular surfaces for the given pose.
136 ///// @details
137 /// This function initializes the calculator, adds all residues in the given pose, and generates molecular surfaces.
138 ///
139 /// The pose is partitioned into separate molecules across the given jump. If the given jump is 0, the entire pose is
140 /// loaded as molecule 1.
141 /// To control what residues make up either surface, use the AddResidue() or even AddAtom() function instead.
142 /// Returns true on success. Results are retrieved with GetResults().
143 ///
144 /// Example:
145 /// core::scoring::sc::MolecularSurfaceCalculator calc;
146 /// if(calc.Calc( pose ))
147 /// ... = calc.GetResults();
149 {
150  if ( !Init() ) {
151  return 0;
152  }
153 
154  if ( jump_id > pose.num_jump() ) {
155  TR.Error << "Jump ID out of bounds (pose has " << pose.num_jump() << " jumps)" << std::endl;
156  return 0;
157  }
158 
159  // Partition pose by jump_id
160  ObjexxFCL::FArray1D_bool is_upstream ( pose.total_residue(), true );
161 
162  if ( jump_id > 0 ) {
163  pose.fold_tree().partition_by_jump( jump_id, is_upstream );
164  }
165 
166  for ( Size i = 1; i <= pose.n_residue(); ++i ) {
167  core::conformation::Residue const & residue = pose.residue(i);
168  if ( residue.type().name() == "VRT" ) {
169  continue;
170  }
171  if ( residue.type().is_metal() ) continue;
172  if ( !AddResidue(is_upstream(i) ? 0 : 1, residue) ) {
173  return 0;
174  }
175  }
176 
177  return Calc();
178 }
179 
180 /// @brief Generate molecular surfaces for loaded atoms.
181 ///// @details
182 /// This function generates molecular surfaces for atoms added via AddAtom and AddResidue.
183 ///
184 /// Init() must be called before this function.
185 /// Returns true on success.
187 {
188  try
189 {
190  basic::gpu::Timer timer(TR.Debug);
191 
192  run_.results.valid = 0;
193 
194  if ( run_.atoms.empty() ) {
195  throw ShapeComplementarityCalculatorException("No atoms defined");
196  }
197 
198  // Determine assign the attention numbers for each atom
200 
202  return 1;
203  }
205 {
206  TR.Error << "Failed: " << e.error << std::endl;
207 }
208 
209  return 0;
210 }
211 
212 
213 /// @brief Generate untrimmed surfaces for the defined molecules.
214 ///// @details
215 /// This function should be called within a try/catch block for ShapeComplementarityCalculatorException.
216 /// Raises exception on error.
218 {
219  if ( run_.atoms.empty() ) {
220  throw ShapeComplementarityCalculatorException("No atoms defined");
221  }
222 
223  // Now compute the surface for the atoms in the interface and its neighbours
224  TR.Debug << "Generating molecular surface, " << settings.density << " dots/A^2" << std::endl;
225  CalcDotsForAllAtoms(run_.atoms);
226 
227  if ( TR.Debug.visible() ) {
228  TR.Debug << " Buried atoms (1): " << run_.results.surface[0].nBuriedAtoms << std::endl;
229  TR.Debug << " Buried atoms (2): " << run_.results.surface[1].nBuriedAtoms << std::endl;
230  TR.Debug << " Blocked atoms (1): " << run_.results.surface[0].nBuriedAtoms << std::endl;
231  TR.Debug << " Blocked atoms (2): " << run_.results.surface[1].nBuriedAtoms << std::endl;
232  TR.Debug << " Convex dots: " << run_.results.dots.convex << std::endl;
233  TR.Debug << " Toroidal dots: " << run_.results.dots.toroidal << std::endl;
234  TR.Debug << " Concave dots: " << run_.results.dots.concave << std::endl;
235  TR.Debug << "Total surface dots (1): " << run_.dots[0].size() << std::endl;
236  TR.Debug << "Total surface dots (2): " << run_.dots[1].size() << std::endl;
237  TR.Debug << " Total surface dots: " << (run_.dots[0].size()+run_.dots[1].size()) << std::endl;
238  }
239 }
240 
241 /// @brief Read atom radius definitions from file
242 /// @defailed
243 /// This function is implicitly called, but can be overloaded or
244 /// called explicitly for custom handling of the atom radii library.
245 /// Returns true on success
246 
248 {
249 #ifdef MULTI_THREADED
250  utility::thread::WriteLockGuard lock( sc_radii_mutex_ );
251 #endif
252 
253  char const *fn = "scoring/score_functions/sc/sc_radii.lib";
254  ATOM_RADIUS radius;
255  utility::io::izstream in;
256 
257  if ( !basic::database::open(in, fn) ) {
258  TR.Error << "Failed to read " << fn << std::endl;
259  return 0;
260  }
261 
262  radii_.clear();
263 
264  while ( in.good() ) {
265  memset(&radius, 0, sizeof(radius));
266  in >> radius.residue >> radius.atom >> radius.radius;
267  if ( *radius.residue && *radius.atom && radius.radius > 0 ) {
268  TR.Trace << "Atom Radius: " << radius.residue << ":" << radius.atom << " = " << radius.radius << std::endl;
269  radii_.push_back(radius);
270  }
271  }
272 
273  TR.Trace << "Atom radii read: " << radii_.size() << std::endl;
274 
275  return !radii_.empty();
276 }
277 
278 /// @brief Add a rosetta residue to a specific molecule
279 /// @details
280 /// Call this function when explicitly defining which residues belong to
281 /// which the molecular surface. If partitioning by jump_id is sufficient
282 /// for your application, you may use the Calc() or CalcSc() functions
283 /// instead.
284 /// Returns number of atoms added for the specified residue.
285 ///
286 /// Example:
287 /// core::scoring::sc::MolecularSurfaceCalculator calc;
288 /// core::Real sc;
289 /// calc.Init();
290 /// calc.Reset(); // Only needed when re-using the calculator
291 /// for(core::Size i = 1; i <= pose.n_residue(); i++)
292 /// calc.AddResidue((i < 100), pose.residue(i));
293 /// if(calc.Calc())
294 /// sc = calc.GetResults().sc;
295 
297  int molecule,
298  core::conformation::Residue const & residue)
299 {
300  std::vector<Atom> scatoms;
301 
302  if ( !Init() ) {
303  return 0;
304  }
305 
306  // Pass 1: Assign atom radii and check if we can add all atoms for this residue
307  // Only use heavy atoms for SC calculation
308  for ( Size i = 1; i <= residue.nheavyatoms(); ++i ) {
309  // Skip virtual atoms
310  if ( residue.is_virtual(i) ) {
311  continue;
312  }
313 
314  // Skip metal atoms (for now -- add support later):
315  if ( residue.type().is_metal() ) continue;
316 
317  Atom scatom;
318  numeric::xyzVector<Real> xyz = residue.xyz(i);
319  scatom.x(xyz.x());
320  scatom.y(xyz.y());
321  scatom.z(xyz.z());
322  scatom.nresidue = residue.seqpos();
323  scatom.radius = 0;
324  strncpy(scatom.residue, residue.name3().c_str(), sizeof(scatom.residue)-1);
325  strncpy(scatom.atom, residue.atom_name(i).c_str()+1, sizeof(scatom.atom)-1);
326 
327  if ( !AssignAtomRadius(scatom) ) {
328  TR.Error << "Failed to add residue " << residue.name3() << " at position " << residue.seqpos() << " to surface - cannot find radius for " << residue.atom_name(i) << std::endl;
329  return 0;
330  }
331  scatoms.push_back(scatom);
332  }
333 
334  // Pass 2: Add all atoms for the residue
335  int n =0;
336  for ( std::vector<Atom>::iterator it = scatoms.begin(); it != scatoms.end(); ++it ) {
337 #if defined(WIN32) && !defined(WIN_PYROSETTA) // windows WINAPI has an AddAtom function
338  if ( AddAtomWIN32(molecule, *it) ) ++n;
339 #else
340  if(AddAtom(molecule, *it)) ++n;
341 #endif
342  }
343 
344  return n;
345 }
346 
347 /// @brief Add an atom to a molecule for computation.
348 /// @details
349 /// Add an core::scoring::sc::Atom to the molecule.
350 /// Normally this is called by AddResidue(). Explicit addition
351 /// of atoms via this function is rarely needed.
352 /// This function also looks-up the atom radius and density.
353 /// Returns true on success.
354 #if defined(WIN32) && !defined(WIN_PYROSETTA) // windows WINAPI has an AddAtom function
355 int MolecularSurfaceCalculator::AddAtomWIN32(int molecule, Atom &atom)
356 #else
358 #endif
359 {
360  if ( atom.radius <= 0 ) {
361  AssignAtomRadius(atom);
362  }
363 
364  if ( atom.radius > 0 ) {
365  molecule = (molecule == 1);
366  atom.density = settings.density;
367  atom.molecule = molecule;
368  atom.natom = ++run_.results.nAtoms;
369  atom.access = 0;
370 
371  run_.atoms.push_back(atom);
372  ++run_.results.surface[molecule].nAtoms;
373  return 1;
374  } else {
375  TR.Error << "Failed to assign atom radius for residue "
376  << atom.residue << ":" << atom.atom << "!" << std::endl;
377  }
378  return 0;
379 }
380 
381 ////////////////////////////////////////////////////////////////////////////
382 // Protected class functions
383 ////////////////////////////////////////////////////////////////////////////
384 
385 // Look up the atom radius for an atom
387 {
388  std::vector<ATOM_RADIUS>::const_iterator radius;
389 
390  // Assign radius with wildcard matching
391  for ( radius = radii_.begin(); radius != radii_.end(); ++radius ) {
392  if ( WildcardMatch(atom.residue, radius->residue, sizeof(atom.residue)) &&
393  WildcardMatch(atom.atom, radius->atom, sizeof(atom.atom)) ) {
394  atom.radius = radius->radius;
395  if ( TR.Trace.visible() ) {
396  char buf[256];
397 #ifdef WIN32
398  _snprintf(buf, sizeof(buf),
399 #else
400  snprintf(buf, sizeof(buf),
401 #endif
402  "Assigned atom radius to %s:%s at (%8.4f, %8.4f, %8.4f) = %.3f",
403  atom.residue,
404  atom.atom,
405  atom.x(),
406  atom.y(),
407  atom.z(),
408  atom.radius
409  );
410  TR.Trace << buf << std::endl;
411  }
412  return 1;
413  }
414  }
415 
416  return 0;
417 }
418 
419 // Inline residue and atom name matching function
421  char const *query,
422  char const *pattern,
423  int l)
424 {
425  while ( --l > 0 ) {
426  bool match =
427  (*query == *pattern) ||
428  (*query && *pattern == '*') ||
429  (*query == ' ' && !*pattern);
430  if ( !match ) {
431  return 0;
432  }
433 
434  // Allow anything following a * in pattern
435  if ( *pattern == '*' && !pattern[1] ) {
436  return 1;
437  }
438 
439  if ( *query ) {
440  ++query;
441  }
442  if ( *pattern ) {
443  ++pattern;
444  }
445  }
446  return 1;
447 }
448 
449 // Assign attention numbers for each atom. By default attention numbers are assigned
450 // to compute surface dots using all defined atoms.
452 {
453  std::vector<Atom>::iterator pAtom;
454 
455  for ( pAtom = atoms.begin(); pAtom < atoms.end(); ++pAtom ) {
456  pAtom->atten = ATTEN_BURIED_FLAGGED;
457  ++run_.results.surface[pAtom->molecule].nBuriedAtoms;
458  }
459 
460  return 1;
461 }
462 
463 ////////////////////////////////////////////////////////////////////////////
464 // Molecular surface calculation
465 ////////////////////////////////////////////////////////////////////////////
466 // M. L. Connolly J. Appl. Crystallogr., 16, p548 - p558 (1983)
467 // Compute the surface for the atoms in the interface and its neighbours
468 ////////////////////////////////////////////////////////////////////////////
469 
471 {
472  // Calc maximum radius for atoms list
473  run_.radmax = 0.0;
474  for ( std::vector<Atom>::const_iterator pAtom1 = run_.atoms.begin(); pAtom1 < run_.atoms.end(); ++pAtom1 ) {
475  if ( pAtom1->radius > run_.radmax ) {
476  run_.radmax = pAtom1->radius;
477  }
478  }
479 
480  // Add dots for each atom in the list
481  for ( std::vector<Atom>::iterator pAtom1 = run_.atoms.begin(); pAtom1 < run_.atoms.end(); ++pAtom1 ) {
482  Atom &atom1 = *pAtom1;
483 
484  if ( atom1.atten <= 0 ) {
485  continue;
486  }
487 
488  // Find neighbor
489  if ( !FindNeighbordsAndBuriedAtoms(atom1) ) {
490  continue;
491  }
492 
493  if ( !atom1.access ) {
494  continue;
495  }
496 
497  if ( atom1.atten <= ATTEN_BLOCKER ) {
498  continue;
499  }
500 
501  if ( atom1.atten == ATTEN_6 && atom1.buried.empty() ) {
502  continue;
503  }
504 
505  // Generate convex surface
506  GenerateConvexSurface(atom1);
507  }
508 
509  // Concave surface generation
510  if ( settings.rp > 0 ) {
512  }
513 
514  return 1;
515 }
516 
517 /// @brief A small struct to report which of two atoms is closer to a given atom:
518 struct
519  CloserToAtom {
520  bool operator() ( Atom * a1, Atom * a2 ) {
521  MolecularSurfaceCalculator::ScValue d1 = ref_atom_->distance( * a1 );
522  MolecularSurfaceCalculator::ScValue d2 = ref_atom_->distance( * a2 );
523  return d1 < d2;
524  }
525  CloserToAtom( Atom * reference_atom ) {
526  ref_atom_ = reference_atom;
527  }
528 private:
530 };
531 
532 // Private atom distance sort callback used below
533 // Atom *_atom_distance_ref = NULL;
534 //int MolecularSurfaceCalculator::_atom_distance_cb(void *a1, void *a2)
535 //{
536 // ScValue d1 = _atom_distance_ref->distance(*((Atom*)a1));
537 // ScValue d2 = _atom_distance_ref->distance(*((Atom*)a2));
538 // return d1 < d2 ? -1: (d2 > d1 ? 1 : 0);
539 //}
540 
541 // Calculate surface dots around a single atom (main loop in original code)
543 {
544  if ( !FindNeighborsForAtom(atom1) ) {
545  return 0;
546  }
547 
548  // sort neighbors by distance from atom1
549  //_atom_distance_ref = &atom1;
550 
551 
552  CloserToAtom closer_to_atom1( &atom1 );
553  std::sort(atom1.neighbors.begin(), atom1.neighbors.end(), closer_to_atom1 );
554  //_atom_distance_ref = NULL;
555 
556  SecondLoop(atom1);
557 
558  return atom1.neighbors.size();
559 }
560 
561 // Make a list of neighboring atoms from atom1
562 // (loop to label 100 in original code)
564 {
565  std::vector<Atom>::iterator iAtom2;
566  std::vector<Atom*> &neighbors = atom1.neighbors;
567  ScValue d2;
568  ScValue bridge;
569  ScValue bb2 = pow(4 * run_.radmax + 4 * settings.rp, 2);
570  int nbb = 0;
571 
572  for ( iAtom2 = run_.atoms.begin(); iAtom2 < run_.atoms.end(); ++iAtom2 ) {
573  Atom &atom2 = *iAtom2;
574  if ( atom1 == atom2 || atom2.atten <= 0 ) {
575  continue;
576  }
577 
578  if ( atom1.molecule == atom2.molecule ) {
579 
580  d2 = atom1.distance_squared(atom2);
581 
582  if ( d2 <= 0.0001 ) {
583  throw ShapeComplementarityCalculatorException("Coincident atoms: %d:%s:%s @ (%.3f, %.3f, %.3f) == %d:%s:%s @ (%.3f, %.3f, %.3f)",
584  atom1.natom, atom1.residue, atom1.atom, atom1.x(), atom1.y(), atom1.z(),
585  atom2.natom, atom2.residue, atom2.atom, atom2.x(), atom2.y(), atom2.z());
586  }
587 
588  bridge = atom1.radius + atom2.radius + 2 * settings.rp;
589  if ( d2 >= bridge * bridge ) {
590  continue;
591  }
592 
593  neighbors.push_back(&atom2);
594 
595  } else {
596 
597  if ( atom2.atten < ATTEN_BURIED_FLAGGED ) {
598  continue;
599  }
600 
601  d2 = atom1.distance_squared(atom2);
602  if ( d2 < bb2 ) {
603  ++nbb;
604  }
605 
606  bridge = atom1.radius + atom2.radius + 2 * settings.rp;
607  if ( d2 >= bridge * bridge ) {
608  continue;
609  }
610 
611  atom1.buried.push_back(&atom2);
612  }
613  }
614 
615  if ( atom1.atten == ATTEN_6 && !nbb ) {
616  return 0;
617  }
618 
619  if ( neighbors.empty() ) {
620  // no neighbors
621  atom1.access = 1;
622  // no convex surface generation
623  return 0;
624  }
625 
626  return neighbors.size();
627 }
628 
629 // second loop (per original code)
631 {
632  Vec3 uij, tij;
633  ScValue erj, eri, rij, /*density,*/ dij, asymm, _far_, contain;
634  int between;
635  std::vector<Atom*> &neighbors = atom1.neighbors;
636 
637  eri = atom1.radius + settings.rp;
638 
639  for ( std::vector<Atom*>::iterator iAtom2 = neighbors.begin(); iAtom2 < neighbors.end(); ++iAtom2 ) {
640  Atom &atom2 = **iAtom2;
641 
642  if ( atom2 <= atom1 ) {
643  continue;
644  }
645 
646  erj = atom2.radius + settings.rp;
647  //density = (atom1.density + atom2.density) / 2; // set but never used ~Labonte
648  dij = atom1.distance(atom2);
649 
650  uij = (atom2 - atom1) / dij;
651  asymm = (eri * eri - erj * erj) / dij;
652  between = (ABS(asymm) < dij);
653 
654  tij = ((atom1 + atom2) * 0.5f) + (uij * (asymm * 0.5f));
655 
656  _far_ = (eri + erj) * (eri + erj) - dij * dij;
657  if ( _far_ <= 0.0 ) {
658  continue;
659  }
660 
661  _far_ = sqrt(_far_);
662 
663  contain = dij * dij - ((atom1.radius - atom2.radius) * (atom1.radius - atom2.radius));
664  if ( contain <= 0.0 ) {
665  continue;
666  }
667 
668  contain = sqrt(contain);
669  rij = 0.5 * _far_ * contain / dij;
670 
671  if ( neighbors.size() <= 1 ) {
672  atom1.access = 1;
673  atom2.access = 1;
674  break;
675  }
676 
677  ThirdLoop(atom1, atom2, uij, tij, rij);
678 
679  if ( atom1.atten > ATTEN_BLOCKER || (atom2.atten > ATTEN_BLOCKER && settings.rp > 0.0) ) {
680  GenerateToroidalSurface(atom1, atom2, uij, tij, rij, between);
681  }
682  }
683 
684  return 1;
685 }
686 
687 // third loop (per original code)
689  Atom& atom1,
690  Atom& atom2,
691  Vec3 const &uij,
692  Vec3 const &tij,
693  ScValue rij)
694 {
695  std::vector<Atom*> &neighbors = atom1.neighbors;
696  ScValue eri, erj, erk, djk, dik;
697  ScValue asymm, dt, dtijk2, hijk, isign, wijk, swijk, rkp2;
698  int is0;
699  Vec3 uik, dijk, pijk, utb, iujk, tv, tik, bijk, uijk;
700 
701  eri = atom1.radius + settings.rp;
702  erj = atom2.radius + settings.rp;
703 
704  for ( std::vector<Atom*>::iterator iAtom3 = neighbors.begin();
705  iAtom3 < neighbors.end(); ++iAtom3 ) {
706  Atom &atom3 = **iAtom3;
707  if ( atom3 <= atom2 ) {
708  continue;
709  }
710 
711  erk = atom3.radius + settings.rp;
712  djk = atom2.distance(atom3);
713  if ( djk >= erj+erk ) {
714  continue;
715  }
716 
717  dik = atom1.distance(atom3);
718  if ( dik >= eri+erk ) {
719  continue;
720  }
721 
722  if ( atom1.atten <= ATTEN_BLOCKER && atom2.atten <= ATTEN_BLOCKER && atom3.atten <= ATTEN_BLOCKER ) {
723  continue;
724  }
725 
726  uik = (atom3 - atom1) / dik;
727  dt = uij.dot(uik);
728  wijk = acosf(dt);
729  swijk = sinf(wijk);
730 
731  if ( dt >= 1.0 || dt <= -1.0 || wijk <= 0.0 || swijk <= 0.0 ) {
732  // collinear and other
733  dtijk2 = tij.distance(atom3);
734  rkp2 = erk * erk - rij * rij;
735  if ( dtijk2 < rkp2 ) {
736  // 600
737  return 0;
738  }
739  continue;
740  }
741 
742  uijk = uij.cross(uik) / swijk;
743  utb = uijk.cross(uij);
744  asymm = (eri*eri - erk*erk) / dik;
745  tik = (atom1 + atom3)*0.5f + uik*asymm*0.5f;
746 
747  // Was: tv = uik * (tik - tij);
748  tv = (tik - tij);
749  tv.x(uik.x() * tv.x());
750  tv.y(uik.y() * tv.y());
751  tv.z(uik.z() * tv.z());
752 
753  dt = tv.x() + tv.y() + tv.z();
754  bijk = tij + utb * dt / swijk;
755  hijk = eri*eri - bijk.distance_squared(atom1);
756  if ( hijk <= 0.0 ) {
757  // no height, skip
758  continue;
759  }
760 
761  hijk = sqrt(hijk);
762  for ( is0 = 1; is0 <= 2; ++is0 ) {
763  isign = 3 - 2 * is0;
764  pijk = bijk + uijk * hijk * isign;
765 
766  // check for collision
767  if ( CheckAtomCollision2(pijk, atom2, atom3, neighbors) ) {
768  continue;
769  }
770 
771  // new probe position
772  PROBE probe;
773  if ( isign > 0 ) {
774  probe.pAtoms[0] = &atom1;
775  probe.pAtoms[1] = &atom2;
776  probe.pAtoms[2] = &atom3;
777  } else {
778  probe.pAtoms[0] = &atom2;
779  probe.pAtoms[1] = &atom1;
780  probe.pAtoms[2] = &atom3;
781  }
782  probe.height = hijk;
783  probe.point = pijk;
784  probe.alt = uijk * isign;
785  run_.probes.push_back(probe);
786 
787  atom1.access = 1;
788  atom2.access = 1;
789  atom3.access = 1;
790  }
791  }
792 
793  return 1;
794 }
795 
796 // Check two atoms against a list of neighbors for collision
798  Vec3 const &pijk,
799  Atom const &atom1,
800  Atom const &atom2,
801  std::vector<Atom*> const &atoms)
802 {
803  for ( std::vector<Atom*>::const_iterator ineighbor = atoms.begin();
804  ineighbor < atoms.end(); ++ineighbor ) {
805  Atom const &neighbor = **ineighbor;
806  if ( &atom1 == &neighbor || &atom2 == &neighbor ) {
807  continue;
808  }
809  if ( pijk.distance_squared(neighbor) <= pow(neighbor.radius + settings.rp, 2) ) {
810  // collision detected
811  return 1;
812  }
813  }
814  return 0;
815 }
816 
817 // Generate convex surface for a specific atom
819 {
820  std::vector<Atom*> const &neighbors = atom1.neighbors;
821  Atom const * neighbor;
822  Vec3 north(0, 0, 1);
823  Vec3 south(0, 0, -1);
824  Vec3 eqvec(1, 0, 0);
825  Vec3 vtemp, vql, uij, tij, pij, cen, pcen;
826  ScValue dt, erj, dij, eri, _far_, contain;
827  ScValue area, asymm, cs, ps, rad, ri, rij, rj;
828 
829  ri = atom1.radius;
830  eri = (atom1.radius + settings.rp);
831 
832  if ( !neighbors.empty() ) {
833  // use first neighbor
834  neighbor = neighbors[0];
835 
836  north = atom1 - *neighbor;
837  north.normalize();
838 
839  vtemp.x(north.y()*north.y() + north.z()*north.z());
840  vtemp.y(north.x()*north.x() + north.z()*north.z());
841  vtemp.z(north.x()*north.x() + north.y()*north.y());
842  vtemp.normalize();
843 
844  dt = vtemp.dot(north);
845  if ( ABS(dt) > 0.99 ) {
846  vtemp = Vec3(1, 0, 0);
847  }
848 
849  eqvec = north.cross(vtemp);
850  eqvec.normalize();
851  vql = eqvec.cross(north);
852 
853  rj = neighbor->radius;
854  erj = neighbor->radius + settings.rp;
855  dij = atom1.distance(*neighbor);
856  uij = (*neighbor - atom1) / dij;
857 
858  asymm = (eri*eri - erj*erj) / dij;
859  tij = ((atom1 + *neighbor) * 0.5f) + (uij * (asymm * 0.5f));
860  _far_ = pow(eri + erj, 2) - dij*dij;
861  if ( _far_ <= 0.0 ) {
862  throw ShapeComplementarityCalculatorException("Imaginary _far_ for atom %d, neighbor atom %d", atom1.natom, neighbor->natom);
863  }
864  _far_ = sqrt(_far_);
865 
866  contain = pow(dij, 2) - pow(ri - rj, 2);
867  if ( contain <= 0.0 ) {
868  throw ShapeComplementarityCalculatorException("Imaginary contain for atom %d, neighbor atom %d", atom1.natom, neighbor->natom);
869  }
870  contain = sqrt(contain);
871  rij = 0.5 * _far_ * contain / dij;
872  pij = tij + (vql * rij);
873  south = (pij - atom1) / eri;
874 
875  if ( north.cross(south).dot(eqvec) <= 0.0 ) {
876  throw ShapeComplementarityCalculatorException("Non-positive frame for atom %d, neighbor atom %d", atom1.natom, neighbor->natom);
877  }
878  }
879 
880  // Generate subdivided arc
881  std::vector<Vec3> lats;
882  Vec3 o(0);
883  cs = SubArc(o, ri, eqvec, atom1.density, north, south, lats);
884 
885  if ( lats.empty() ) {
886  return 0;
887  }
888 
889  // Project onto north vector
890  std::vector<Vec3> points;
891  for ( std::vector<Vec3>::iterator ilat = lats.begin(); ilat < lats.end(); ++ilat ) {
892  dt = ilat->dot(north);
893  cen = atom1 + (north*dt);
894  rad = ri*ri - dt*dt;
895  if ( rad <= 0.0 ) {
896  continue;
897  }
898  rad = sqrt(rad);
899 
900  points.clear();
901  ps = SubCir(cen, rad, north, atom1.density, points);
902  if ( points.empty() ) {
903  continue;
904  }
905  area = ps * cs;
906 
907  for ( std::vector<Vec3>::iterator point = points.begin();
908  point < points.end(); ++point ) {
909 
910  pcen = atom1 + ((*point - atom1) * (eri/ri));
911 
912  // Check for collision
913  if ( CheckPointCollision(pcen, neighbors) ) {
914  continue;
915  }
916 
917  // No collision, put point
918  ++run_.results.dots.convex;
919  AddDot(atom1.molecule, 1, *point, area, pcen, atom1);
920  }
921  }
922  return 1;
923 }
924 
925 // Check a point for collision against a list of atoms
927  Vec3 const &pcen,
928  std::vector<Atom*> const &atoms)
929 {
930  for ( std::vector<Atom*>::const_iterator ineighbor = atoms.begin()+1;
931  ineighbor < atoms.end(); ++ineighbor ) {
932  if ( pcen.distance(**ineighbor) <= ((*ineighbor)->radius + settings.rp) ) {
933  // collision detected
934  return 1;
935  }
936  }
937  return 0;
938 }
939 
940 // Generate toroidal surface between two atoms
942  Atom &atom1,
943  Atom &atom2,
944  Vec3 const uij,
945  Vec3 const tij,
946  ScValue rij,
947  int between)
948 {
949  std::vector<Atom*> &neighbors = atom1.neighbors;
950  ScValue density, /*ri,*/ /*rj,*/ rb, rci, rcj, rs, e, edens, eri, erj, erl, dtq, pcusp, /*anglei,*/ /*anglej,*/ dt, ts, ps, area;
951  Vec3 pi, pj, axis, dij, pqi, pqj, qij, qjk, qj;
952 
953  std::vector<Vec3> subs;
954 
955  // following Fortran original
956  // will be optimized by compiler
957  density = (atom1.density + atom2.density) / 2;
958  //ri = atom1.radius; // set but never used ~Labonte
959  //rj = atom2.radius; // set but never used ~Labonte
960  eri = (atom1.radius + settings.rp);
961  erj = (atom2.radius + settings.rp);
962  rci = rij * atom1.radius / eri;
963  rcj = rij * atom2.radius / erj;
964  rb = rij - settings.rp;
965 
966  if ( rb <= 0.0 ) {
967  rb = 0.0;
968  }
969 
970  rs = (rci + 2 * rb + rcj) / 4;
971  e = rs / rij;
972  edens = e * e * density;
973 
974  ts = SubCir(tij, rij, uij, edens, subs);
975  if ( subs.empty() ) {
976  return 0;
977  }
978 
979  for ( std::vector<Vec3>::iterator isub = subs.begin(); isub < subs.end(); ++isub ) {
980  Vec3 &sub = *isub;
981 
982  // check for collision
983  int tooclose = 0;
984  ScValue d2 = 0;
985  for ( std::vector<Atom*>::iterator ineighbor = neighbors.begin();
986  !tooclose && ineighbor < neighbors.end() && !tooclose;
987  ++ineighbor ) {
988  Atom const &neighbor = **ineighbor; // for readability
989  if ( atom2 == neighbor ) {
990  continue;
991  }
992  erl = neighbor.radius + settings.rp;
993  d2 = sub.distance_squared(neighbor);
994  tooclose = d2 < (erl * erl);
995  }
996  if ( tooclose ) {
997  continue;
998  }
999 
1000  // no collision, toroidal arc generation
1001  Vec3 &pij = sub;
1002  atom1.access = 1;
1003  atom2.access = 1;
1004 
1005  if ( atom1.atten == ATTEN_6 && atom2.atten == ATTEN_6&& atom1.buried.empty() ) {
1006  continue;
1007  }
1008 
1009  pi = (atom1 - pij) / eri;
1010  pj = (atom2 - pij) / erj;
1011  axis = pi.cross(pj);
1012  axis.normalize();
1013 
1014  dtq = pow(settings.rp, 2) - pow(rij, 2);
1015  pcusp = dtq > 0 && between;
1016  if ( pcusp ) {
1017  // point cusp -- two shortened arcs
1018  dtq = sqrt(dtq);
1019  qij = tij - uij * dtq;
1020  qjk = tij + uij * dtq;
1021  pqi = (qij - pij) / (ScValue)settings.rp;
1022  pqj = Vec3(0.0);
1023 
1024  } else {
1025  // no cusp
1026  pqi = pi + pj;
1027  pqi.normalize();
1028  pqj = pqi;
1029  }
1030 
1031  dt = pqi.dot(pi);
1032  if ( dt >= 1.0 || dt <= -1.0 ) {
1033  return 0;
1034  }
1035  //anglei = acosf(dt); // set but never used ~Labonte
1036 
1037  dt = pqj.dot(pj);
1038  if ( dt >= 1.0 || dt <= -1.0 ) {
1039  return 0;
1040  }
1041  //anglej = acosf(dt); // set but never used ~Labonte
1042 
1043  // convert two arcs to points
1044  if ( atom1.atten >= ATTEN_2 ) {
1045  std::vector<Vec3> points;
1046  ps = SubArc(pij, settings.rp, axis, density, pi, pqi, points);
1047  for ( std::vector<Vec3>::iterator point = points.begin(); point < points.end(); ++point ) {
1048  area = ps * ts * DistancePointToLine(tij, uij, *point) / rij;
1049  ++run_.results.dots.toroidal;
1050  AddDot(atom1.molecule, 2, *point, area, pij, atom1);
1051  }
1052  }
1053 
1054  if ( atom2.atten >= ATTEN_2 ) {
1055  std::vector<Vec3> points;
1056  ps = SubArc(pij, settings.rp, axis, density, pqj, pj, points);
1057  for ( std::vector<Vec3>::iterator point = points.begin(); point < points.end(); ++point ) {
1058  area = ps * ts * DistancePointToLine(tij, uij, *point) / rij;
1059  ++run_.results.dots.toroidal;
1060  AddDot(atom1.molecule, 2, *point, area, pij, atom2);
1061  }
1062  }
1063  }
1064  return 1;
1065 }
1066 
1067 // Generate concave surface for all probes
1069 {
1070  std::vector<PROBE const *> lowprobs, nears;
1071 
1072  // collect low probes
1073  for ( std::vector<PROBE>::iterator probe = run_.probes.begin();
1074  probe < run_.probes.end(); ++probe ) {
1075  if ( probe->height < settings.rp ) {
1076  lowprobs.push_back(&(*probe));
1077  }
1078  }
1079 
1080  for ( std::vector<PROBE>::iterator probe = run_.probes.begin();
1081  probe < run_.probes.end(); ++probe ) {
1082 
1083  if ( probe->pAtoms[0]->atten == ATTEN_6 &&
1084  probe->pAtoms[1]->atten == ATTEN_6 &&
1085  probe->pAtoms[2]->atten == ATTEN_6 ) {
1086  continue;
1087  }
1088 
1089  Vec3 &pijk = probe->point, &uijk = probe->alt;
1090  ScValue hijk = probe->height;
1091  ScValue density = (
1092  probe->pAtoms[0]->density +
1093  probe->pAtoms[1]->density +
1094  probe->pAtoms[2]->density ) / 3;
1095 
1096  // gather nearby low probes
1097  nears.clear();
1098  for ( std::vector<PROBE const *>::const_iterator lprobe = lowprobs.begin();
1099  lprobe < lowprobs.end(); ++lprobe ) {
1100  if ( &(*probe) == *lprobe ) {
1101  continue;
1102  }
1103 
1104  ScValue d2 = pijk.distance_squared((*lprobe)->point);
1105  if ( d2 > 4 * pow(settings.rp, 2) ) {
1106  continue;
1107  }
1108 
1109  nears.push_back(*lprobe);
1110  }
1111 
1112  // set up vectors from probe center to three atoms
1113  Vec3 vp[3], vectors[3];
1114  for ( int i = 0; i < 3; ++i ) {
1115  vp[i] = *(probe->pAtoms[i]) - pijk;
1116  vp[i].normalize();
1117  }
1118 
1119  // set up vectors to three cutting planes
1120  vectors[0] = vp[0].cross(vp[1]);
1121  vectors[1] = vp[1].cross(vp[2]);
1122  vectors[2] = vp[2].cross(vp[0]);
1123  vectors[0].normalize();
1124  vectors[1].normalize();
1125  vectors[2].normalize();
1126 
1127  // find latitude of highest vertex of triangle
1128  ScValue dm = -1.0;
1129  int mm = 0;
1130  for ( int i = 0; i < 3; ++i ) {
1131  ScValue dt = uijk.dot(vp[i]);
1132  if ( dt > dm ) {
1133  dm = dt;
1134  mm = i;
1135  }
1136  }
1137 
1138  // create arc for selecting latitudes
1139  Vec3 south = -uijk;
1140  Vec3 axis = vp[mm].cross(south);
1141  axis.normalize();
1142 
1143  std::vector<Vec3> lats;
1144  Vec3 o(0);
1145  ScValue cs;
1146 
1147  cs = SubArc(o, settings.rp, axis, density, vp[mm], south, lats);
1148  if ( lats.empty() ) {
1149  continue;
1150  }
1151 
1152  std::vector<Vec3> points;
1153  for ( std::vector<Vec3>::iterator ilat = lats.begin();
1154  ilat < lats.end(); ++ilat ) {
1155  ScValue dt, area, rad, ps;
1156  Vec3 cen;
1157 
1158  dt = ilat->dot(south);
1159  cen = south * dt;
1160  rad = pow(settings.rp, 2) - pow(dt, 2);
1161  if ( rad <= 0.0 ) {
1162  continue;
1163  }
1164  rad = sqrtf(rad);
1165 
1166  points.clear();
1167  ps = SubCir(cen, rad, south, density, points);
1168  if ( points.empty() ) {
1169  continue;
1170  }
1171 
1172  area = ps * cs;
1173 
1174  for ( std::vector<Vec3>::iterator point = points.begin();
1175  point < points.end(); ++point ) {
1176  // check against 3 planes
1177  int bail = 0;
1178  for ( int i = 0; i < 3; ++i ) {
1179  ScValue dt = point->dot(vectors[i]);
1180  if ( dt >= 0.0 ) {
1181  bail = 1;
1182  break;
1183  }
1184  }
1185  if ( bail ) {
1186  continue;
1187  }
1188 
1189  *point += pijk;
1190 
1191  if ( (hijk < settings.rp && !nears.empty()) &&
1192  CheckProbeCollision(*point, nears, pow(settings.rp, 2)) ) {
1193  continue;
1194  }
1195 
1196  // determine which atom the surface point is closest to
1197  int mc = 0;
1198  ScValue dmin = 2 * settings.rp;
1199  for ( int i = 0; i < 3; ++i ) {
1200  ScValue d = point->distance(*(probe->pAtoms[i])) -
1201  probe->pAtoms[i]->radius;
1202  if ( d < dmin ) {
1203  dmin = d;
1204  mc = i;
1205  }
1206  }
1207 
1208  // No collision, put point
1209  ++run_.results.dots.concave;
1210  AddDot(probe->pAtoms[mc]->molecule, 3, *point, area, pijk, *probe->pAtoms[mc]);
1211  }
1212  }
1213  }
1214  return 1;
1215 }
1216 
1217 // Check a point against a set of probes for collision within radius^2
1219  Vec3 const &point,
1220  std::vector<PROBE const *> const nears,
1221  ScValue const r2)
1222 {
1223  for ( std::vector<const PROBE*>::const_iterator _near_ = nears.begin();
1224  _near_ < nears.end(); ++_near_ ) {
1225  if ( point.distance_squared((*_near_)->point) < r2 ) {
1226  // Collision
1227  return 1;
1228  }
1229  }
1230  return 0;
1231 }
1232 
1233 // Add a molecular dot
1235  int const molecule,
1236  int const type,
1237  Vec3 const coor,
1238  ScValue const area,
1239  Vec3 const pcen,
1240  Atom const &atom)
1241 {
1242  DOT dot = { coor, Vec3(), area, 0, type, &atom };
1243  ScValue pradius = settings.rp, erl;
1244 
1245  // calculate outward pointing unit normal vector
1246  if ( pradius <= 0 ) {
1247  dot.outnml = coor - atom;
1248  } else {
1249  dot.outnml = (pcen - coor) / pradius;
1250  }
1251 
1252  // determine whether buried
1253 
1254  // first check whether probe changed
1255  if ( pcen.distance_squared(run_.prevp) <= 0.0 ) {
1256  dot.buried = run_.prevburied;
1257 
1258  } else {
1259 
1260  // check for collision with neighbors in other molecules
1261  dot.buried = 0;
1262  for ( std::vector<Atom*>::const_iterator iNeighbor = atom.buried.begin();
1263  iNeighbor < atom.buried.end();
1264  ++iNeighbor ) {
1265  erl = (*iNeighbor)->radius + pradius;
1266  ScValue d = pcen.distance_squared(**iNeighbor);
1267  if ( d <= erl*erl ) {
1268  dot.buried = 1;
1269  break;
1270  }
1271 
1272  }
1273 
1274  run_.prevp = pcen;
1275  run_.prevburied = dot.buried;
1276  }
1277 
1278  run_.dots[molecule].push_back(dot);
1279 }
1280 
1281 
1282 // Calculate distance from point to line
1284  Vec3 const &cen,
1285  Vec3 const &axis,
1286  Vec3 const &pnt)
1287 {
1288  Vec3 vec = pnt - cen;
1289  ScValue dt = vec.dot(axis);
1290  ScValue d2 = vec.magnitude_squared() - pow(dt, 2);
1291  return d2 < 0.0 ? 0.0 : sqrt(d2);
1292 }
1293 
1294 // Generate sub arc of molecular dots centered around a defined point
1296  Vec3 const &cen,
1297  ScValue const rad,
1298  Vec3 const &axis,
1299  ScValue const density,
1300  Vec3 const &x,
1301  Vec3 const &v,
1302  std::vector<Vec3> &points)
1303 {
1304  Vec3 y;
1305  ScValue angle;
1306  ScValue dt1, dt2;
1307 
1308  y = axis.cross(x);
1309  dt1 = v.dot(x);
1310  dt2 = v.dot(y);
1311  angle = atan2(dt2, dt1);
1312 
1313  if ( angle < 0.0 ) {
1314  angle = angle + 2*PI;
1315  }
1316 
1317  return SubDiv(cen, rad, x, y, angle, density, points);
1318 }
1319 
1320 // Subdivide defined arc and generate molecular dots
1322  Vec3 const &cen,
1323  ScValue const rad,
1324  Vec3 const &x,
1325  Vec3 const &y,
1326  ScValue const angle,
1327  ScValue const density,
1328  std::vector<Vec3> &points)
1329 {
1330  ScValue delta, a, c, s, ps;
1331  int i;
1332 
1333  delta = 1.0 / (sqrt(density) * rad);
1334  a = - delta / 2;
1335 
1336  for ( i = 0; i < MAX_SUBDIV; ++i ) {
1337  a = a + delta;
1338  if ( a > angle ) {
1339  break;
1340  }
1341 
1342  c = rad * cosf(a);
1343  s = rad * sinf(a);
1344  points.push_back(Vec3(cen + x*c + y*s));
1345  }
1346 
1347  if ( a + delta < angle ) {
1348  throw ShapeComplementarityCalculatorException("Too many subdivisions");
1349  }
1350 
1351  if ( !points.empty() ) {
1352  ps = rad * angle / points.size();
1353  } else {
1354  ps = 0.0;
1355  }
1356 
1357  return ps;
1358 }
1359 
1360 // Generate an arbitrary unit vector perpendicular to axis
1362  Vec3 const &cen,
1363  ScValue const rad,
1364  Vec3 const &axis,
1365  ScValue const density,
1366  std::vector<Vec3> &points)
1367 {
1368  Vec3 v1, v2, x, y;
1369  ScValue dt;
1370 
1371  v1.x(pow(axis.y(), 2) + pow(axis.z(), 2));
1372  v1.y(pow(axis.x(), 2) + pow(axis.z(), 2));
1373  v1.z(pow(axis.x(), 2) + pow(axis.y(), 2));
1374  v1.normalize();
1375  dt = v1.dot(axis);
1376 
1377  if ( ABS(dt) > 0.99 ) {
1378  v1.x(1.0);
1379  v1.y(0.0);
1380  v1.z(0.0);
1381  }
1382 
1383  v2 = axis.cross(v1);
1384  v2.normalize();
1385  x = axis.cross(v2);
1386  x.normalize();
1387  y = axis.cross(x);
1388 
1389  return SubDiv(cen, rad, x, y, 2.0 * PI, density, points);
1390 }
1391 
1392 ///////////////////////////////////////////////////////////////////////////
1393 // Private helpers
1394 ////////////////////////////////////////////////////////////////////////////
1395 
1396 Atom::Atom() : numeric::xyzVector < MolecularSurfaceCalculator::ScValue > (0.0)
1397 {
1398  natom = 0;
1399  nresidue = 0;
1400  molecule = 0;
1401  radius = 0;
1402  density = 0;
1403  atten = 0;
1404  access = 0;
1405 
1406  memset(atom, 0, sizeof(atom));
1407  memset(residue, 0, sizeof(residue));
1408 }
1409 
1411 
1412 // The End
1413 ////////////////////////////////////////////////////////////////////////////
1414 
1415 } // namespace sc
1416 } // namespace scoring
1417 } // namespace core
1418 
1419 #endif // INCLUDED_core_scoring_sc_MolecularSurfaceCalculator_cc
1420 
1421 // END //
Fold tree class.
int ThirdLoop(Atom &pAtom1, Atom &pAtom, Vec3 const &uij, Vec3 const &tij, ScValue const rij)
kinematics::FoldTree const & fold_tree() const
Returns the pose FoldTree.
Definition: Pose.cc:305
Size nheavyatoms() const
Returns the number of heavyatoms in this residue.
Definition: Residue.hh:295
virtual int Init()
Initializes calculation and GPU (if used) Init() is also called implicitly by the static CalcSc() fun...
bool is_virtual(Size const &atomno) const
Check if atom is virtual.
Definition: Residue.cc:1642
numeric::xyzVector< float > outnml
std::vector< numeric::xyzVector< core::Real > > r2
Definition: TMalign.cc:71
Vec xyz(Pose const &p, Size const &ia, Size const &ir)
Definition: FunGroupTK.cc:95
c
DEPRECATED convert between the real-valued chi dihedrals and the rotamer well indices.
Vec a(Pose const &p, numeric::Size const &i, string const &s)
std::string const & atom_name(int const atm) const
Returns the name of this residue's atom with index number
Definition: Residue.hh:1927
A molecular system including residues, kinematics, and energies.
Definition: Pose.hh:153
ScValue SubArc(Vec3 const &cen, ScValue const rad, Vec3 const &axis, ScValue const density, Vec3 const &x, Vec3 const &v, std::vector< Vec3 > &points)
ScValue SubDiv(Vec3 const &cen, ScValue const rad, Vec3 const &x, Vec3 const &y, ScValue angle, ScValue density, std::vector< Vec3 > &points)
Size seqpos() const
Returns the sequence position of this residue.
Definition: Residue.hh:1629
numeric::xyzVector< float > alt
virtual int AssignAttentionNumbers(std::vector< Atom > &atom)
struct core::scoring::sc::MolecularSurfaceCalculator::@3 settings
int AddAtom(int molecule, Atom &atom)
Add an atom to a molecule for computation.
void GenerateMolecularSurfaces()
Generate untrimmed surfaces for the defined molecules.
void partition_by_jump(int const jump_number, FoldTree &f1, FoldTree &f2) const
partition into two foldtrees by cutting at jump= jump_number
Definition: FoldTree.cc:1787
int CheckAtomCollision2(Vec3 const &pijk, Atom const &atom1, Atom const &atom2, std::vector< Atom * > const &atoms)
int WildcardMatch(char const *query, char const *pattern, int const l)
A small struct to report which of two atoms is closer to a given atom:
Size n_residue() const
Returns the number of residues in the pose conformation example(s): pose.n_residue() See also: Pose P...
Definition: Pose.cc:760
std::string const & name3() const
Returns this residue's 3-letter representation.
Definition: Residue.hh:1950
platform::Size Size
Definition: types.hh:30
Instance Residue class, used for placed residues and rotamers.
Definition: Residue.hh:90
Size total_residue() const
Returns the number of residues in the pose conformation.
Definition: Pose.cc:754
numeric::xyzVector< float > point
Kinematics Jump class.
Vector const & xyz(Size const atm_index) const
Returns the position of this residue's atom with index number
Definition: Residue.cc:362
struct core::scoring::sc::MolecularSurfaceCalculator::@4 run_
core::Size AddResidue(int molecule, core::conformation::Residue const &residue)
Add a rosetta residue to a specific molecule.
rosetta project type declarations
static THREAD_LOCAL basic::Tracer TR("core.scoring.sc.MolecularSurfaceCalculator")
ScValue SubCir(Vec3 const &cen, ScValue const rad, Vec3 const &north, ScValue const density, std::vector< Vec3 > &points)
ResidueType const & type() const
Returns this residue's ResidueType.
Definition: Residue.hh:1139
int CheckPointCollision(Vec3 const &pcen, std::vector< Atom * > const &atoms)
Size num_jump() const
Returns the number of jumps in the pose FoldTree.
Definition: Pose.cc:800
std::string const & name() const
get our (unique) residue name
virtual void Reset()
Reset calculator for another calculation. Must be used when the MolecularSurfaceCalculator instance i...
void AddDot(int const molecule, int const type, Vec3 const coor, ScValue const area, Vec3 const pcen, Atom const &atom)
virtual int Calc()
Generate molecular surfaces for loaded atoms. //.
ScValue DistancePointToLine(Vec3 const &cen, Vec3 const &axis, Vec3 const &pnt)
utility::vector1< Hit > match
Definition: Hit.fwd.hh:57
int CheckProbeCollision(Vec3 const &point, std::vector< const PROBE * > const nears, ScValue const r2)
int GenerateToroidalSurface(Atom &atom1, Atom &atom2, Vec3 const uij, Vec3 const tij, ScValue rij, int between)
Method declarations and simple accessor definitions for the Residue class.
Residue const & residue(Size const seqpos) const
Returns the Residue at position (read access) Note: this method will trigger a refold if eit...
Definition: Pose.cc:900
numeric::xyzVector< core::Real > point
bool is_metal() const
Return true if this residue type is a metal ion, false otherwise.
static THREAD_LOCAL basic::Tracer TR("core.scoring.AtomVDW")
int ReadScRadii()
Read atom radius definitions from file This function is implicitly called, but can be overloaded or ...
MolecularSurfaceCalculator()
MolecularSurfaceCalculator constructor, initializes default settings.
Forward header for the Molecular Surface Calculator.
Pose class.