20 #ifndef INCLUDED_core_scoring_sc_MolecularSurfaceCalculator_cc
21 #define INCLUDED_core_scoring_sc_MolecularSurfaceCalculator_cc
33 #include <numeric/xyzVector.hh>
34 #include <numeric/NumericTraits.hh>
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>
54 static THREAD_LOCAL basic::Tracer
TR(
"core.scoring.sc.MolecularSurfaceCalculator" );
119 for ( std::vector<Atom>::iterator
a =
run_.atoms.begin();
a <
run_.atoms.end(); ++
a ) {
120 a->neighbors.clear();
127 run_.dots[0].clear();
128 run_.dots[1].clear();
130 memset(&
run_.results, 0,
sizeof(
run_.results));
131 memset(&
run_.prevp, 0,
sizeof(
run_.prevp));
155 TR.Error <<
"Jump ID out of bounds (pose has " << pose.
num_jump() <<
" jumps)" << std::endl;
160 ObjexxFCL::FArray1D_bool is_upstream ( pose.
total_residue(), true );
168 if ( residue.
type().
name() ==
"VRT" ) {
172 if ( !
AddResidue(is_upstream(i) ? 0 : 1, residue) ) {
190 basic::gpu::Timer timer(
TR.Debug);
192 run_.results.valid = 0;
194 if (
run_.atoms.empty() ) {
206 TR.Error <<
"Failed: " << e.
error << std::endl;
219 if (
run_.atoms.empty() ) {
224 TR.Debug <<
"Generating molecular surface, " <<
settings.density <<
" dots/A^2" << std::endl;
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;
249 #ifdef MULTI_THREADED
250 utility::thread::WriteLockGuard lock( sc_radii_mutex_ );
253 char const *fn =
"scoring/score_functions/sc/sc_radii.lib";
255 utility::io::izstream in;
257 if ( !basic::database::open(in, fn) ) {
258 TR.Error <<
"Failed to read " << fn << std::endl;
264 while ( in.good() ) {
265 memset(&radius, 0,
sizeof(radius));
268 TR.Trace <<
"Atom Radius: " << radius.
residue <<
":" << radius.
atom <<
" = " << radius.
radius << std::endl;
273 TR.Trace <<
"Atom radii read: " <<
radii_.size() << std::endl;
300 std::vector<Atom> scatoms;
318 numeric::xyzVector<Real>
xyz = residue.
xyz(i);
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;
331 scatoms.push_back(scatom);
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;
340 if(
AddAtom(molecule, *it)) ++n;
354 #if defined(WIN32) && !defined(WIN_PYROSETTA) // windows WINAPI has an AddAtom function
355 int MolecularSurfaceCalculator::AddAtomWIN32(
int molecule,
Atom &atom)
361 AssignAtomRadius(atom);
365 molecule = (molecule == 1);
366 atom.
density = settings.density;
368 atom.
natom = ++run_.results.nAtoms;
371 run_.atoms.push_back(atom);
372 ++run_.results.surface[molecule].nAtoms;
375 TR.Error <<
"Failed to assign atom radius for residue "
376 << atom.
residue <<
":" << atom.
atom <<
"!" << std::endl;
388 std::vector<ATOM_RADIUS>::const_iterator radius;
391 for ( radius =
radii_.begin(); radius !=
radii_.end(); ++radius ) {
394 atom.
radius = radius->radius;
395 if (
TR.Trace.visible() ) {
398 _snprintf(buf,
sizeof(buf),
400 snprintf(buf,
sizeof(buf),
402 "Assigned atom radius to %s:%s at (%8.4f, %8.4f, %8.4f) = %.3f",
410 TR.Trace << buf << std::endl;
427 (*query == *pattern) ||
428 (*query && *pattern ==
'*') ||
429 (*query ==
' ' && !*pattern);
435 if ( *pattern ==
'*' && !pattern[1] ) {
453 std::vector<Atom>::iterator pAtom;
455 for ( pAtom = atoms.begin(); pAtom < atoms.end(); ++pAtom ) {
457 ++
run_.results.surface[pAtom->molecule].nBuriedAtoms;
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;
481 for ( std::vector<Atom>::iterator pAtom1 =
run_.atoms.begin(); pAtom1 <
run_.atoms.end(); ++pAtom1 ) {
482 Atom &atom1 = *pAtom1;
484 if ( atom1.
atten <= 0 ) {
526 ref_atom_ = reference_atom;
565 std::vector<Atom>::iterator iAtom2;
566 std::vector<Atom*> &neighbors = atom1.
neighbors;
572 for ( iAtom2 =
run_.atoms.begin(); iAtom2 <
run_.atoms.end(); ++iAtom2 ) {
573 Atom &atom2 = *iAtom2;
574 if ( atom1 == atom2 || atom2.
atten <= 0 ) {
580 d2 = atom1.distance_squared(atom2);
582 if ( d2 <= 0.0001 ) {
589 if ( d2 >= bridge * bridge ) {
593 neighbors.push_back(&atom2);
601 d2 = atom1.distance_squared(atom2);
607 if ( d2 >= bridge * bridge ) {
611 atom1.
buried.push_back(&atom2);
619 if ( neighbors.empty() ) {
626 return neighbors.size();
633 ScValue erj, eri, rij, dij, asymm, _far_, contain;
635 std::vector<Atom*> &neighbors = atom1.
neighbors;
639 for ( std::vector<Atom*>::iterator iAtom2 = neighbors.begin(); iAtom2 < neighbors.end(); ++iAtom2 ) {
640 Atom &atom2 = **iAtom2;
642 if ( atom2 <= atom1 ) {
648 dij = atom1.distance(atom2);
650 uij = (atom2 - atom1) / dij;
651 asymm = (eri * eri - erj * erj) / dij;
652 between = (
ABS(asymm) < dij);
654 tij = ((atom1 + atom2) * 0.5f) + (uij * (asymm * 0.5f));
656 _far_ = (eri + erj) * (eri + erj) - dij * dij;
657 if ( _far_ <= 0.0 ) {
664 if ( contain <= 0.0 ) {
668 contain = sqrt(contain);
669 rij = 0.5 * _far_ * contain / dij;
671 if ( neighbors.size() <= 1 ) {
695 std::vector<Atom*> &neighbors = atom1.
neighbors;
696 ScValue eri, erj, erk, djk, dik;
697 ScValue asymm, dt, dtijk2, hijk, isign, wijk, swijk, rkp2;
699 Vec3 uik, dijk, pijk, utb, iujk, tv, tik, bijk, uijk;
704 for ( std::vector<Atom*>::iterator iAtom3 = neighbors.begin();
705 iAtom3 < neighbors.end(); ++iAtom3 ) {
706 Atom &atom3 = **iAtom3;
707 if ( atom3 <= atom2 ) {
712 djk = atom2.distance(atom3);
713 if ( djk >= erj+erk ) {
717 dik = atom1.distance(atom3);
718 if ( dik >= eri+erk ) {
726 uik = (atom3 - atom1) / dik;
731 if ( dt >= 1.0 || dt <= -1.0 || wijk <= 0.0 || swijk <= 0.0 ) {
733 dtijk2 = tij.distance(atom3);
734 rkp2 = erk * erk - rij * rij;
735 if ( dtijk2 < rkp2 ) {
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;
749 tv.x(uik.x() * tv.x());
750 tv.y(uik.y() * tv.y());
751 tv.z(uik.z() * tv.z());
753 dt = tv.x() + tv.y() + tv.z();
754 bijk = tij + utb * dt / swijk;
755 hijk = eri*eri - bijk.distance_squared(atom1);
762 for ( is0 = 1; is0 <= 2; ++is0 ) {
764 pijk = bijk + uijk * hijk * isign;
784 probe.
alt = uijk * isign;
785 run_.probes.push_back(probe);
801 std::vector<Atom*>
const &atoms)
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 ) {
809 if ( pijk.distance_squared(neighbor) <= pow(neighbor.
radius +
settings.rp, 2) ) {
820 std::vector<Atom*>
const &neighbors = atom1.
neighbors;
821 Atom const * neighbor;
823 Vec3 south(0, 0, -1);
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;
832 if ( !neighbors.empty() ) {
834 neighbor = neighbors[0];
836 north = atom1 - *neighbor;
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());
844 dt = vtemp.dot(north);
845 if (
ABS(dt) > 0.99 ) {
846 vtemp =
Vec3(1, 0, 0);
849 eqvec = north.cross(vtemp);
851 vql = eqvec.cross(north);
853 rj = neighbor->radius;
854 erj = neighbor->radius +
settings.rp;
855 dij = atom1.distance(*neighbor);
856 uij = (*neighbor - atom1) / dij;
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 ) {
866 contain = pow(dij, 2) - pow(ri - rj, 2);
867 if ( contain <= 0.0 ) {
870 contain = sqrt(contain);
871 rij = 0.5 * _far_ * contain / dij;
872 pij = tij + (vql * rij);
873 south = (pij - atom1) / eri;
875 if ( north.cross(south).dot(eqvec) <= 0.0 ) {
881 std::vector<Vec3> lats;
883 cs =
SubArc(o, ri, eqvec, atom1.
density, north, south, lats);
885 if ( lats.empty() ) {
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);
902 if ( points.empty() ) {
907 for ( std::vector<Vec3>::iterator
point = points.begin();
910 pcen = atom1 + ((*
point - atom1) * (eri/ri));
918 ++
run_.results.dots.convex;
928 std::vector<Atom*>
const &atoms)
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) ) {
949 std::vector<Atom*> &neighbors = atom1.
neighbors;
950 ScValue density, rb, rci, rcj, rs, e, edens, eri, erj, erl, dtq, pcusp, dt, ts, ps, area;
951 Vec3 pi, pj, axis, dij, pqi, pqj, qij, qjk, qj;
953 std::vector<Vec3> subs;
962 rci = rij * atom1.
radius / eri;
963 rcj = rij * atom2.
radius / erj;
970 rs = (rci + 2 * rb + rcj) / 4;
974 ts =
SubCir(tij, rij, uij, edens, subs);
975 if ( subs.empty() ) {
979 for ( std::vector<Vec3>::iterator isub = subs.begin(); isub < subs.end(); ++isub ) {
985 for ( std::vector<Atom*>::iterator ineighbor = neighbors.begin();
986 !tooclose && ineighbor < neighbors.end() && !tooclose;
988 Atom const &neighbor = **ineighbor;
989 if ( atom2 == neighbor ) {
993 d2 = sub.distance_squared(neighbor);
994 tooclose = d2 < (erl * erl);
1009 pi = (atom1 - pij) / eri;
1010 pj = (atom2 - pij) / erj;
1011 axis = pi.cross(pj);
1014 dtq = pow(
settings.rp, 2) - pow(rij, 2);
1015 pcusp = dtq > 0 && between;
1019 qij = tij - uij * dtq;
1020 qjk = tij + uij * dtq;
1032 if ( dt >= 1.0 || dt <= -1.0 ) {
1038 if ( dt >= 1.0 || dt <= -1.0 ) {
1045 std::vector<Vec3> points;
1047 for ( std::vector<Vec3>::iterator
point = points.begin();
point < points.end(); ++
point ) {
1049 ++
run_.results.dots.toroidal;
1055 std::vector<Vec3> points;
1057 for ( std::vector<Vec3>::iterator
point = points.begin();
point < points.end(); ++
point ) {
1059 ++
run_.results.dots.toroidal;
1070 std::vector<PROBE const *> lowprobs, nears;
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));
1080 for ( std::vector<PROBE>::iterator probe =
run_.probes.begin();
1081 probe <
run_.probes.end(); ++probe ) {
1083 if ( probe->pAtoms[0]->atten ==
ATTEN_6 &&
1084 probe->pAtoms[1]->atten ==
ATTEN_6 &&
1085 probe->pAtoms[2]->atten ==
ATTEN_6 ) {
1089 Vec3 &pijk = probe->point, &uijk = probe->alt;
1092 probe->pAtoms[0]->density +
1093 probe->pAtoms[1]->density +
1094 probe->pAtoms[2]->density ) / 3;
1098 for ( std::vector<PROBE const *>::const_iterator lprobe = lowprobs.begin();
1099 lprobe < lowprobs.end(); ++lprobe ) {
1100 if ( &(*probe) == *lprobe ) {
1104 ScValue d2 = pijk.distance_squared((*lprobe)->point);
1105 if ( d2 > 4 * pow(
settings.rp, 2) ) {
1109 nears.push_back(*lprobe);
1113 Vec3 vp[3], vectors[3];
1114 for (
int i = 0; i < 3; ++i ) {
1115 vp[i] = *(probe->pAtoms[i]) - pijk;
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();
1130 for (
int i = 0; i < 3; ++i ) {
1140 Vec3 axis = vp[mm].cross(south);
1143 std::vector<Vec3> lats;
1148 if ( lats.empty() ) {
1152 std::vector<Vec3> points;
1153 for ( std::vector<Vec3>::iterator ilat = lats.begin();
1154 ilat < lats.end(); ++ilat ) {
1158 dt = ilat->dot(south);
1160 rad = pow(
settings.rp, 2) - pow(dt, 2);
1167 ps =
SubCir(cen, rad, south, density, points);
1168 if ( points.empty() ) {
1174 for ( std::vector<Vec3>::iterator
point = points.begin();
1178 for (
int i = 0; i < 3; ++i ) {
1191 if ( (hijk <
settings.rp && !nears.empty()) &&
1199 for (
int i = 0; i < 3; ++i ) {
1201 probe->pAtoms[i]->radius;
1209 ++
run_.results.dots.concave;
1210 AddDot(probe->pAtoms[mc]->molecule, 3, *
point, area, pijk, *probe->pAtoms[mc]);
1220 std::vector<PROBE const *>
const nears,
1223 for ( std::vector<const PROBE*>::const_iterator _near_ = nears.begin();
1224 _near_ < nears.end(); ++_near_ ) {
1225 if ( point.distance_squared((*_near_)->point) <
r2 ) {
1242 DOT dot = { coor,
Vec3(), area, 0, type, &atom };
1246 if ( pradius <= 0 ) {
1247 dot.
outnml = coor - atom;
1249 dot.
outnml = (pcen - coor) / pradius;
1255 if ( pcen.distance_squared(
run_.prevp) <= 0.0 ) {
1262 for ( std::vector<Atom*>::const_iterator iNeighbor = atom.
buried.begin();
1263 iNeighbor < atom.
buried.end();
1265 erl = (*iNeighbor)->radius + pradius;
1266 ScValue d = pcen.distance_squared(**iNeighbor);
1267 if ( d <= erl*erl ) {
1278 run_.dots[molecule].push_back(dot);
1288 Vec3 vec = pnt - cen;
1290 ScValue d2 = vec.magnitude_squared() - pow(dt, 2);
1291 return d2 < 0.0 ? 0.0 : sqrt(d2);
1302 std::vector<Vec3> &points)
1311 angle = atan2(dt2, dt1);
1313 if ( angle < 0.0 ) {
1314 angle = angle + 2*
PI;
1317 return SubDiv(cen, rad, x, y, angle, density, points);
1328 std::vector<Vec3> &points)
1333 delta = 1.0 / (sqrt(density) * rad);
1344 points.push_back(
Vec3(cen + x*c + y*s));
1347 if ( a + delta < angle ) {
1351 if ( !points.empty() ) {
1352 ps = rad * angle / points.size();
1366 std::vector<Vec3> &points)
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));
1377 if (
ABS(dt) > 0.99 ) {
1383 v2 = axis.cross(v1);
1389 return SubDiv(cen, rad, x, y, 2.0 *
PI, density, points);
1406 memset(atom, 0,
sizeof(atom));
1419 #endif // INCLUDED_core_scoring_sc_MolecularSurfaceCalculator_cc
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.
virtual int Init()
Initializes calculation and GPU (if used) Init() is also called implicitly by the static CalcSc() fun...
numeric::xyzVector< float > outnml
std::vector< numeric::xyzVector< core::Real > > r2
Vec xyz(Pose const &p, Size const &ia, Size const &ir)
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::vector< Atom * > buried
A molecular system including residues, kinematics, and energies.
int GenerateConcaveSurface()
ScValue SubArc(Vec3 const &cen, ScValue const rad, Vec3 const &axis, ScValue const density, Vec3 const &x, Vec3 const &v, std::vector< Vec3 > &points)
int AssignAtomRadius(Atom &atom)
ScValue SubDiv(Vec3 const &cen, ScValue const rad, Vec3 const &x, Vec3 const &y, ScValue angle, ScValue density, std::vector< Vec3 > &points)
int SecondLoop(Atom &pAtom1)
numeric::xyzVector< float > alt
virtual int AssignAttentionNumbers(std::vector< Atom > &atom)
virtual ~MolecularSurfaceCalculator()
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
numeric::xyzVector< float > Vec3
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...
static std::vector< ATOM_RADIUS > radii_
Size total_residue() const
Returns the number of residues in the pose conformation.
numeric::xyzVector< float > point
struct core::scoring::sc::MolecularSurfaceCalculator::@4 run_
CloserToAtom(Atom *reference_atom)
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)
int CheckPointCollision(Vec3 const &pcen, std::vector< Atom * > const &atoms)
int FindNeighbordsAndBuriedAtoms(Atom &atom)
Size num_jump() const
Returns the number of jumps in the pose FoldTree.
int FindNeighborsForAtom(Atom &atom1)
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
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)
int CalcDotsForAllAtoms(std::vector< Atom > &atoms)
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...
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 ...
int GenerateConvexSurface(Atom const &atom1)
MolecularSurfaceCalculator()
MolecularSurfaceCalculator constructor, initializes default settings.
Forward header for the Molecular Surface Calculator.
std::vector< Atom * > neighbors