25 #ifndef INCLUDED_core_scoring_sc_ShapeComplementarityCalculator_cc
26 #define INCLUDED_core_scoring_sc_ShapeComplementarityCalculator_cc
40 #include <numeric/xyzVector.hh>
41 #include <numeric/NumericTraits.hh>
44 #include <utility/vector1.hh>
45 #include <utility/exit.hh>
46 #include <utility/io/izstream.hh>
47 #include <basic/Tracer.hh>
48 #include <basic/database/open.hh>
61 #define UPPER_MULTIPLE(n,d) (((n)%(d)) ? (((n)/(d)+1)*(d)) : (n))
63 static basic::Tracer
TR(
"core.scoring.sc.ShapeComplementarityCalculator");
108 if(sc.
Calc(pose, jump_id))
129 if( jump_id > pose.
num_jump() || jump_id <= 0) {
130 TR.Error <<
"Jump ID out of bounds (pose has " << pose.
num_jump() <<
" jumps)" << std::endl;
152 basic::gpu::Timer timer(
TR.Debug);
154 run_.results.valid = 0;
156 if(
run_.atoms.empty())
158 if(!
run_.results.surface[0].nAtoms)
160 if(!
run_.results.surface[1].nAtoms)
168 if(!
run_.dots[0].size() || !
run_.dots[1].size())
174 TR.Debug <<
"Trimming peripheral band, " <<
settings.band <<
"A range" << std::endl;
176 std::vector<DOT const *> trimmed_dots[2];
177 for(
int i = 0; i < 2; ++i) {
179 if(!trimmed_dots[i].
size())
181 run_.results.surface[i].nTrimmedDots = trimmed_dots[i].size();
182 run_.results.surface[i].nAllDots =
run_.dots[i].size();
186 TR.Debug <<
"Computing surface separation and vectors" << std::endl;
191 run_.results.surface[2].d_mean = (
run_.results.surface[0].d_mean +
run_.results.surface[1].d_mean) / 2;
192 run_.results.surface[2].d_median = (
run_.results.surface[0].d_median +
run_.results.surface[1].d_median) / 2;
193 run_.results.surface[2].s_mean = (
run_.results.surface[0].s_mean +
run_.results.surface[1].s_mean) / 2;
194 run_.results.surface[2].s_median = (
run_.results.surface[0].s_median +
run_.results.surface[1].s_median) / 2;
196 run_.results.surface[2].nAtoms = (
run_.results.surface[0].nAtoms +
run_.results.surface[1].nAtoms);
197 run_.results.surface[2].nBuriedAtoms = (
run_.results.surface[0].nBuriedAtoms +
run_.results.surface[1].nBlockedAtoms);
198 run_.results.surface[2].nBlockedAtoms = (
run_.results.surface[0].nBuriedAtoms +
run_.results.surface[1].nBuriedAtoms);
199 run_.results.surface[2].nAllDots = (
run_.results.surface[0].nAllDots +
run_.results.surface[1].nAllDots);
200 run_.results.surface[2].nTrimmedDots = (
run_.results.surface[0].nTrimmedDots +
run_.results.surface[1].nTrimmedDots);
203 run_.results.surface[2].trimmedArea = (
run_.results.surface[0].trimmedArea +
run_.results.surface[1].trimmedArea);
205 run_.results.sc =
run_.results.surface[2].s_median;
206 run_.results.distance =
run_.results.surface[2].d_median;
207 run_.results.area =
run_.results.surface[2].trimmedArea;
208 run_.results.valid = 1;
213 TR.Error <<
"Failed: " << e.
error << std::endl;
226 std::vector<Atom>::iterator pAtom1, pAtom2;
228 for(pAtom1 =
run_.atoms.begin(); pAtom1 <
run_.atoms.end(); ++pAtom1) {
231 for(pAtom2 =
run_.atoms.begin(); pAtom2 <
run_.atoms.end(); ++pAtom2) {
232 if(pAtom1->molecule == pAtom2->molecule)
234 r = pAtom1->distance(*pAtom2);
242 TR.Debug <<
"Atom ATTEN_BLOCKER: " << pAtom1->natom << std::endl;
245 ++
run_.results.surface[pAtom1->molecule].nBlockedAtoms;
251 ++
run_.results.surface[pAtom1->molecule].nBuriedAtoms;
262 std::vector<DOT>
const &sdots,
263 std::vector<DOT const *> &trimmed_dots)
272 area = gpuTrimPeripheralBand(sdots, trimmed_dots);
279 for(std::vector<DOT>::const_iterator idot = sdots.begin(); idot < sdots.end(); ++idot) {
280 DOT const &dot = *idot;
284 trimmed_dots.push_back(&dot);
299 std::vector<DOT>
const &sdots)
304 for(std::vector<DOT>::const_iterator idot2 = sdots.begin(); idot2 < sdots.end(); ++idot2) {
305 DOT const &dot2 = *idot2;
310 if(dot.
coor.distance_squared(dot2.
coor) <= r2)
323 std::vector<DOT const*>
const &my_dots,
324 std::vector<DOT const*>
const &their_dots)
326 std::map<int,int> dbins;
327 std::map<int,int> sbins;
328 ScValue norm_sum = 0.0, distmin_sum = 0.0;
332 if(my_dots.empty() || their_dots.empty())
335 for(std::vector<DOT const*>::const_iterator idot = my_dots.begin();
336 idot < my_dots.end(); ++idot) {
341 total += (*idot)->area;
345 std::vector<DOT const*> neighbors;
346 std::vector<DOT const*>::const_iterator iNeighbor;
349 gpuFindClosestNeighbors(my_dots, their_dots, neighbors);
350 iNeighbor = neighbors.begin();
354 for(std::vector<DOT const*>::const_iterator idot = my_dots.begin();
355 idot < my_dots.end(); ++idot)
357 DOT const &dot1 = **idot;
360 DOT const *neighbor = NULL;
365 neighbor = *iNeighbor++;
380 distmin = neighbor->
coor.distance(dot1.
coor);
381 distmin_sum += distmin;
392 r = r * exp( - pow(distmin, 2) *
settings.weight );
394 r =
MIN(0.999,
MAX(r, -0.999));
409 ScValue abin, cumarea =0, cumperc = 0, perc,
c;
411 std::map<int,int>::const_iterator it;
413 TR.Trace << std::endl;
414 TR.Trace <<
"Distance between surfaces D(" << (molecule+1) <<
"->" << (molecule+1)%2+1 <<
"):" << std::endl;
415 TR.Trace <<
"From - To\tArea\tCum. Area\t%\tCum. %" << std::endl;
417 for(it = dbins.begin(); it != dbins.end(); ++it) {
418 abin = total * (it->second) / my_dots.size();
420 perc = abin * 100 / total;
422 if(cumperc <= 50 && c >= 50) {
423 rleft = (it->first) *
settings.binwidth_dist;
424 rmedian = rleft + (50 - cumperc) *
settings.binwidth_dist / ( c - cumperc );
429 if(
TR.Trace.visible()) {
432 snprintf(buf,
sizeof(buf),
433 "%.2f - %.2f\t%.1f\t%.1f\t%.1f\t%.1f",
439 TR.Trace << buf << std::endl;
444 run_.results.surface[molecule].d_mean = distmin_sum / my_dots.size();
445 run_.results.surface[molecule].d_median = rmedian;
447 TR.Trace << std::endl;
448 TR.Trace <<
"Surface complementarity S(" << (molecule+1) <<
"->" << (molecule+1)%2+1 <<
"):" << std::endl;
449 TR.Trace <<
"From - To\tNumber\t%\tCumm. %" << std::endl;
452 for(it = sbins.begin(); it != sbins.end(); ++it) {
453 perc = (
ScValue)(it->second) * 100 / my_dots.size();
455 if(cumperc <= 50 && c >= 50) {
457 rmedian = rleft + (50 - cumperc) *
settings.binwidth_norm / ( c - cumperc );
462 if(
TR.Trace.visible()) {
464 snprintf(buf,
sizeof(buf),
465 "%.2f - %.2f\t%d\t%.1f\t%.1f",
468 it->second, perc, cumperc);
469 TR.Trace << buf << std::endl;
474 run_.results.surface[molecule].s_mean= -norm_sum / my_dots.size();
475 run_.results.surface[molecule].s_median = -rmedian;
484 std::vector<DOT const*>
const &their_dots)
487 DOT const *neighbor = NULL;
492 for(std::vector<DOT const*>::const_iterator idot2 = their_dots.begin();
493 idot2 < their_dots.end(); ++idot2) {
494 DOT const &dot2 = **idot2;
497 d = dot2.
coor.distance_squared(dot1.
coor);
511 core::Real inline ShapeComplementarityCalculator::GetTimerMs(clock_t &
start)
513 clock_t now = clock();
518 void ShapeComplementarityCalculator::gpuInit()
521 if(
TR.Debug.visible())
527 settings.gpu_threads = gpu.device().threads;
528 gpu.RegisterProgram(
"gpu/sc.cl");
532 std::vector<DOT>
const &dots,
533 std::vector<DOT const*> &trimmed_dots)
535 using namespace basic::gpu;
547 float4 *hAccDotCoords, *phAccDotCoords;
548 float4 *hBurDotCoords, *phBurDotCoords;
555 if(!hAccDotCoords || !hBurDotCoords || !hDotColl)
556 throw ShapeComplementarityCalculatorException(
"Out of host memory!");
559 phAccDotCoords = hAccDotCoords;
560 phBurDotCoords = hBurDotCoords;
561 for(std::vector<DOT>::const_iterator idot = dots.begin();
562 idot < dots.end(); ++idot) {
563 #ifdef SC_PRECISION_REAL
565 phBurDotCoords->x = idot->coor.x();
566 phBurDotCoords->y = idot->coor.y();
567 phBurDotCoords->z = idot->coor.z();
570 phAccDotCoords->x = idot->coor.x();
571 phAccDotCoords->y = idot->coor.y();
572 phAccDotCoords->z = idot->coor.z();
578 *phBurDotCoords++ = *((float4*)&idot->coor.x());
580 *phAccDotCoords++ = *((float4*)&idot->coor.x());
583 nBur = phBurDotCoords - hBurDotCoords;
584 nAcc = phAccDotCoords - hAccDotCoords;
588 if(!gpu.ExecuteKernel(
"TrimPeripheralBand", nBur, threads, 32,
589 GPU_IN,
UPPER_MULTIPLE(nAcc, threads) *
sizeof(*hAccDotCoords), hAccDotCoords,
591 GPU_IN,
UPPER_MULTIPLE(nBur, threads) *
sizeof(*hBurDotCoords), hBurDotCoords,
592 GPU_OUT,
UPPER_MULTIPLE(nBur, threads) *
sizeof(*hDotColl), hDotColl,
595 throw ShapeComplementarityCalculatorException(
"Failed to launch GPU kernel TrimPeripheralBand!");
600 for(std::vector<DOT>::const_iterator idot = dots.begin();
601 idot < dots.end(); ++idot) {
602 DOT const &dot1 = *idot;
607 trimmed_dots.push_back(&dot1);
611 delete hAccDotCoords;
612 delete hBurDotCoords;
615 TR.Debug <<
"Peripheral trimming GPU processing time: " << gpu.lastKernelRuntime() <<
" ms kernel, " << GetTimerMs(timer) <<
" ms total" << std::endl;
620 int ShapeComplementarityCalculator::gpuFindClosestNeighbors(
621 std::vector<DOT const*>
const &my_dots,
622 std::vector<DOT const*>
const &their_dots,
623 std::vector<DOT const*> &neighbors)
625 using namespace basic::gpu;
627 int nMyDots, nTheirDots, nNeighbors;
635 float4 *hMyDotCoords, *phMyDotCoords;
636 float4 *hTheirDotCoords, *phTheirDotCoords;
639 DOT const **hTheirDots, **phTheirDots;
644 nMyDots = my_dots.size();
645 nTheirDots = their_dots.size();
646 nNeighbors = nMyDots;
649 hTheirDotCoords =
new float4 [
UPPER_MULTIPLE(nTheirDots, threads)];
654 phMyDotCoords = hMyDotCoords;
655 for(std::vector<DOT const*>::const_iterator idot = my_dots.begin(); idot < my_dots.end(); ++idot) {
656 phMyDotCoords->x = (*idot)->coor.x();
657 phMyDotCoords->y = (*idot)->coor.y();
658 phMyDotCoords->z = (*idot)->coor.z();
661 nMyDots = phMyDotCoords - hMyDotCoords;
664 phTheirDotCoords = hTheirDotCoords;
665 phTheirDots = hTheirDots;
666 for(std::vector<DOT const*>::const_iterator idot = their_dots.begin(); idot < their_dots.end(); ++idot) {
669 phTheirDotCoords->x = (*idot)->coor.x();
670 phTheirDotCoords->y = (*idot)->coor.y();
671 phTheirDotCoords->z = (*idot)->coor.z();
673 *phTheirDots++ = *idot;
675 nTheirDots = phTheirDotCoords - hTheirDotCoords;
678 if(!gpu.ExecuteKernel(
"FindClosestNeighbor", nMyDots, threads, 32,
679 GPU_IN,
UPPER_MULTIPLE(nMyDots, threads) *
sizeof(*hMyDotCoords), hMyDotCoords,
680 GPU_IN,
UPPER_MULTIPLE(nTheirDots, threads) *
sizeof(*hTheirDotCoords), hTheirDotCoords,
682 GPU_OUT,
UPPER_MULTIPLE(nNeighbors, threads) *
sizeof(*hNeighbors), hNeighbors,
684 throw ShapeComplementarityCalculatorException(
"Failed to launch GPU kernel FindClosestNeighbor!");
687 for(
int i = 0; i < nNeighbors; ++i)
688 neighbors.push_back( hTheirDots[hNeighbors[i]] );
691 delete hTheirDotCoords;
695 TR.Debug <<
"Find Neighbors GPU processing time: " << gpu.lastKernelRuntime() <<
" ms kernel, " << GetTimerMs(timer) <<
" ms total" << std::endl;
709 #endif // INCLUDED_core_scoring_sc_ShapeComplementarityCalculator_cc