18 #ifndef INCLUDED_core_conformation_find_neighbors_hh
19 #define INCLUDED_core_conformation_find_neighbors_hh
31 #include <numeric/numeric.functions.hh>
32 #include <numeric/xyzTriple.hh>
33 #include <numeric/xyzVector.hh>
35 #include <numeric/geometry/hashing/xyzStripeHashWithMeta.hh>
40 #include <ObjexxFCL/FArray3D.hh>
46 #include <boost/unordered_map.hpp>
56 #include <utility/vector1.hh>
57 #include <basic/options/keys/score.OptionKeys.gen.hh>
58 #include <basic/prof.hh>
62 namespace conformation {
74 boost::hash_combine( seed, key.x() );
75 boost::hash_combine( seed, key.y() );
76 boost::hash_combine( seed, key.z() );
84 template <
class Vertex,
class Edge>
98 if ( strategy ==
STRIPEHASH || ( strategy ==
AUTOMATIC && basic::options::option[ basic::options::OptionKeys::score::find_neighbors_stripehash ]() )) {
102 }
else if ( strategy ==
NAIVE || point_graph->num_vertices() < N_POINTS_BREAK_EVEN ) {
111 template <
class Vertex,
class Edge>
119 core::Size const n_points( point_graph->num_vertices() );
120 if ( n_points == 0 )
return;
121 core::Real neighbor_cutoff_sq = neighbor_cutoff * neighbor_cutoff;
124 if ( n_points <= 1 )
return;
127 for (
core::Size ii = 1; ii <= n_points; ++ii ) {
128 PointPosition const & ii_pos( point_graph->get_vertex(ii).data().xyz() );
129 for (
core::Size jj = ii + 1; jj <= n_points; ++jj ) {
130 core::Real const d_sq( ii_pos.distance_squared( point_graph->get_vertex(jj).data().xyz() ) );
131 if ( d_sq <= neighbor_cutoff_sq ) {
133 point_graph->add_edge( ii, jj, Edge( d_sq ) );
139 template <
class Vertex,
class Edge>
153 template <
class Vertex,
class Edge>
159 core::Size const n_points( point_graph->num_vertices() );
160 if ( n_points <= 1 )
return;
161 std::cout << n_points << std::endl;
163 for(
core::Size ii = 1; ii <= n_points; ++ii ) pts[ii] = point_graph->get_vertex(ii).data().xyz();
165 numeric::geometry::hashing::xyzStripeHashWithMeta<Real> hash(neighbor_cutoff,pts,dummy);
167 for(
core::Size ii = 1; ii <= n_points; ++ii ) {
168 hash.visit(pts[ii],ii,visitor);
189 template <
class Vertex,
class Edge>
205 typedef numeric::xyzTriple< core::Size > CubeDim;
208 typedef std::vector< core::Size > PointIDs;
210 typedef std::map< CubeKey, PointIDs > Cubes;
217 core::Size const n_points( point_graph->num_vertices() );
219 core::Real neighbor_cutoff_sq( neighbor_cutoff*neighbor_cutoff);
222 Points points( n_points );
223 for (
core::Size ii = 1; ii <= n_points; ++ii ) { points[ ii ] = point_graph->get_vertex( ii ).data().xyz(); }
226 if ( n_points <= 1 )
return;
232 for (
core::Size ii = 2; ii <= n_points; ++ii ) {
233 bbl.min( points[ ii ] );
234 bbu.max( points[ ii ] );
238 core::Real const epsilon( epsilon_multiplier * std::numeric_limits< core::Real >::epsilon() );
245 core::Real const side( side_factor * neighbor_cutoff );
248 CubeDim
const cube_dim(
249 core::Size( std::ceil( ( bbu.x() - bbl.x() ) * side_inv ) ),
250 core::Size( std::ceil( ( bbu.y() - bbl.y() ) * side_inv ) ),
251 core::Size( std::ceil( ( bbu.z() - bbl.z() ) * side_inv ) )
260 core::Size const n_cube( cube_dim.x() * cube_dim.y() * cube_dim.z() );
266 find_neighbors_naive<Vertex, Edge>( point_graph, neighbor_cutoff );
283 for (
core::Size i = 1; i <= n_points; ++i ) {
289 core::Size( ( pp.x() - bbl.x() ) * side_inv ),
290 core::Size( ( pp.y() - bbl.y() ) * side_inv ),
295 assert( cube_key.x() < cube_dim.x() );
296 assert( cube_key.y() < cube_dim.y() );
297 assert( cube_key.z() < cube_dim.z() );
300 cubes[ cube_key ].push_back( i );
305 for (
core::Size i = 1; i <= n_points; ++i ) {
317 core::Real const cx( pp.x() - ( bbl.x() + ( icx * side ) ) );
318 core::Real const cy( pp.y() - ( bbl.y() + ( icy * side ) ) );
319 core::Real const cz( pp.z() - ( bbl.z() + ( icz * side ) ) );
322 for (
core::Size ix = max( icx,
core::Size( 1 ) ) - 1, ixe = min( icx + 1, cube_dim.x() - 1 ); ix <= ixe; ++ix ) {
323 for (
core::Size iy = max( icy,
core::Size( 1 ) ) - 1, iye = min( icy + 1, cube_dim.y() - 1 ); iy <= iye; ++iy ) {
324 for (
core::Size iz = max( icz,
core::Size( 1 ) ) - 1, ize = min( icz + 1, cube_dim.z() - 1 ); iz <= ize; ++iz ) {
325 Cubes::iterator
const ic( cubes.find(
CubeKey( ix,iy, iz ) ) );
326 if ( ic != cubes.end() ) {
328 ( ix != icx ?
square( cx - ( ix > icx ? side : D_ZERO ) ) : D_ZERO ) +
329 ( iy != icy ?
square( cy - ( iy > icy ? side : D_ZERO ) ) : D_ZERO ) +
330 ( iz != icz ?
square( cz - ( iz > icz ? side : D_ZERO ) ) : D_ZERO )
331 <= neighbor_cutoff_sq )
333 for ( PointIDs::iterator ia = ic->second.begin(), iae = ic->second.end(); ia != iae; ++ia ) {
336 core::Real const d_sq( pp.distance_squared( points[ j ] ) );
337 if ( d_sq <= neighbor_cutoff_sq )
339 point_graph->add_edge( i, j, Edge( d_sq ) );
366 template <
class Vertex,
class Edge>
379 typedef numeric::xyzTriple< core::Size > CubeDim;
380 typedef numeric::xyzTriple< core::Size >
CubeKey;
382 typedef std::vector< core::Size > PointIDs;
383 typedef ObjexxFCL::FArray3D< PointIDs > Cubes;
386 core::Size const n_points( point_graph->num_vertices() );
388 core::Real neighbor_cutoff_sq( neighbor_cutoff*neighbor_cutoff);
391 Points points( n_points );
392 for (
core::Size ii = 1; ii <= n_points; ++ii ) { points[ ii ] = point_graph->get_vertex( ii ).data().xyz(); }
395 if ( n_points <= 1 )
return;
401 for (
core::Size ii = 2; ii <= n_points; ++ii ) {
402 bbl.min( points[ ii ] );
403 bbu.max( points[ ii ] );
407 core::Real const epsilon( epsilon_multiplier * std::numeric_limits< core::Real >::epsilon() );
414 core::Real const side( side_factor * neighbor_cutoff );
417 CubeDim
const cube_dim(
418 core::Size( std::ceil( ( bbu.x() - bbl.x() ) * side_inv ) ),
419 core::Size( std::ceil( ( bbu.y() - bbl.y() ) * side_inv ) ),
420 core::Size( std::ceil( ( bbu.z() - bbl.z() ) * side_inv ) )
441 Cubes cubes( cube_dim.x(), cube_dim.y(), cube_dim.z() );
443 for (
core::Size i = 1; i <= n_points; ++i ) {
447 CubeKey
const cube_key(
448 core::Size( ( pp.x() - bbl.x() ) * side_inv ) + 1,
449 core::Size( ( pp.y() - bbl.y() ) * side_inv ) + 1,
450 core::Size( ( pp.z() - bbl.z() ) * side_inv ) + 1
454 assert( cube_key.x() <= cube_dim.x() );
455 assert( cube_key.y() <= cube_dim.y() );
456 assert( cube_key.z() <= cube_dim.z() );
460 core::Size i_index = cubes.index( cube_key.x(), cube_key.y(), cube_key.z() );
461 if ( cubes[ i_index ].
size() == 0 ) {
471 cubes[ i_index ].reserve( 10 );
473 cubes[ i_index ].push_back( i );
479 for (
core::Size i = 1; i <= n_points; ++i ) {
489 for (
core::Size ix = max( icx,
core::Size( 2 ) ) - 1, ixe = min( icx + 1, cube_dim.x() ); ix <= ixe; ++ix ) {
490 for (
core::Size iy = max( icy,
core::Size( 2 ) ) - 1, iye = min( icy + 1, cube_dim.y() ); iy <= iye; ++iy ) {
491 for (
core::Size iz = max( icz,
core::Size( 2 ) ) - 1, ize = min( icz + 1, cube_dim.z() ); iz <= ize; ++iz ) {
494 core::Size cube_index = cubes.index( ix, iy, iz );
498 if ( cubes[ cube_index ].
size() != 0 ) {
499 for ( PointIDs::iterator ia = cubes[ cube_index ].begin(), iae = cubes[ cube_index ].
end(); ia != iae; ++ia ) {
503 core::Real const d_sq( pp.distance_squared( points[ j ] ) );
504 if ( d_sq <= neighbor_cutoff_sq )
506 point_graph->add_edge( i, j, Edge( d_sq ) );
528 template <
class Vertex,
class Edge>
544 find_neighbors_3dgrid_restricted<Vertex,Edge>( point_graph, neighbor_cutoff, residue_selection );
545 }
else if ( strategy ==
NAIVE || point_graph->num_vertices() < N_POINTS_BREAK_EVEN ) {
546 find_neighbors_naive_restricted<Vertex,Edge>( point_graph, neighbor_cutoff, residue_selection );
548 find_neighbors_octree_restricted<Vertex,Edge>( point_graph, neighbor_cutoff, residue_selection, strategy );
553 template <
class Vertex,
class Edge>
562 core::Size const n_points( point_graph->num_vertices() );
563 if ( n_points == 0 )
return;
564 core::Real neighbor_cutoff_sq = neighbor_cutoff * neighbor_cutoff;
567 if ( n_points <= 1 )
return;
570 for (
core::Size ii = 1; ii <= n_points; ++ii ) {
571 if ( !residue_selection[ ii ] )
continue;
572 PointPosition const & ii_pos( point_graph->get_vertex(ii).data().xyz() );
573 for (
core::Size jj = 1; jj <= n_points; ++jj ) {
574 if ( residue_selection[ jj ] && jj <= ii )
continue;
575 core::Real const d_sq( ii_pos.distance_squared( point_graph->get_vertex(jj).data().xyz() ) );
576 if ( d_sq <= neighbor_cutoff_sq ) {
578 point_graph->add_edge( ii, jj, Edge( d_sq ) );
585 template <
class Vertex,
class Edge>
602 typedef numeric::xyzTriple< core::Size > CubeDim;
605 typedef std::vector< core::Size > PointIDs;
607 typedef std::map< CubeKey, PointIDs > Cubes;
614 core::Size const n_points( point_graph->num_vertices() );
616 core::Real neighbor_cutoff_sq( neighbor_cutoff*neighbor_cutoff);
619 Points points( n_points );
620 for (
core::Size ii = 1; ii <= n_points; ++ii ) { points[ ii ] = point_graph->get_vertex( ii ).data().xyz(); }
623 if ( n_points <= 1 )
return;
629 for (
core::Size ii = 2; ii <= n_points; ++ii ) {
630 bbl.min( points[ ii ] );
631 bbu.max( points[ ii ] );
635 core::Real const epsilon( epsilon_multiplier * std::numeric_limits< core::Real >::epsilon() );
642 core::Real const side( side_factor * neighbor_cutoff );
645 CubeDim
const cube_dim(
646 core::Size( std::ceil( ( bbu.x() - bbl.x() ) * side_inv ) ),
647 core::Size( std::ceil( ( bbu.y() - bbl.y() ) * side_inv ) ),
648 core::Size( std::ceil( ( bbu.z() - bbl.z() ) * side_inv ) )
657 core::Size const n_cube( cube_dim.x() * cube_dim.y() * cube_dim.z() );
663 find_neighbors_naive_restricted<Vertex, Edge>( point_graph, neighbor_cutoff,residue_selection );
680 for (
core::Size i = 1; i <= n_points; ++i ) {
686 core::Size( ( pp.x() - bbl.x() ) * side_inv ),
687 core::Size( ( pp.y() - bbl.y() ) * side_inv ),
692 assert( cube_key.x() < cube_dim.x() );
693 assert( cube_key.y() < cube_dim.y() );
694 assert( cube_key.z() < cube_dim.z() );
697 cubes[ cube_key ].push_back( i );
702 for (
core::Size i = 1; i <= n_points; ++i ) {
703 if ( !residue_selection[ i ] )
continue;
715 core::Real const cx( pp.x() - ( bbl.x() + ( icx * side ) ) );
716 core::Real const cy( pp.y() - ( bbl.y() + ( icy * side ) ) );
717 core::Real const cz( pp.z() - ( bbl.z() + ( icz * side ) ) );
720 for (
core::Size ix = max( icx,
core::Size( 1 ) ) - 1, ixe = min( icx + 1, cube_dim.x() - 1 ); ix <= ixe; ++ix ) {
721 for (
core::Size iy = max( icy,
core::Size( 1 ) ) - 1, iye = min( icy + 1, cube_dim.y() - 1 ); iy <= iye; ++iy ) {
722 for (
core::Size iz = max( icz,
core::Size( 1 ) ) - 1, ize = min( icz + 1, cube_dim.z() - 1 ); iz <= ize; ++iz ) {
723 Cubes::iterator
const ic( cubes.find(
CubeKey( ix,iy, iz ) ) );
724 if ( ic != cubes.end() ) {
726 ( ix != icx ?
square( cx - ( ix > icx ? side : D_ZERO ) ) : D_ZERO ) +
727 ( iy != icy ?
square( cy - ( iy > icy ? side : D_ZERO ) ) : D_ZERO ) +
728 ( iz != icz ?
square( cz - ( iz > icz ? side : D_ZERO ) ) : D_ZERO )
729 <= neighbor_cutoff_sq )
731 for ( PointIDs::iterator ia = ic->second.begin(), iae = ic->second.end(); ia != iae; ++ia ) {
733 if ( i < j || !residue_selection[ j ] ) {
734 core::Real const d_sq( pp.distance_squared( points[ j ] ) );
735 if ( d_sq <= neighbor_cutoff_sq )
737 point_graph->add_edge( i, j, Edge( d_sq ) );
760 template <
class Vertex,
class Edge>
774 typedef numeric::xyzTriple< core::Size > CubeDim;
775 typedef numeric::xyzTriple< core::Size >
CubeKey;
777 typedef std::vector< core::Size > PointIDs;
778 typedef ObjexxFCL::FArray3D< PointIDs > Cubes;
781 core::Size const n_points( point_graph->num_vertices() );
783 core::Real neighbor_cutoff_sq( neighbor_cutoff*neighbor_cutoff);
786 Points points( n_points );
787 for (
core::Size ii = 1; ii <= n_points; ++ii ) { points[ ii ] = point_graph->get_vertex( ii ).data().xyz(); }
790 if ( n_points <= 1 )
return;
796 for (
core::Size ii = 2; ii <= n_points; ++ii ) {
797 bbl.min( points[ ii ] );
798 bbu.max( points[ ii ] );
802 core::Real const epsilon( epsilon_multiplier * std::numeric_limits< core::Real >::epsilon() );
809 core::Real const side( side_factor * neighbor_cutoff );
812 CubeDim
const cube_dim(
813 core::Size( std::ceil( ( bbu.x() - bbl.x() ) * side_inv ) ),
814 core::Size( std::ceil( ( bbu.y() - bbl.y() ) * side_inv ) ),
815 core::Size( std::ceil( ( bbu.z() - bbl.z() ) * side_inv ) )
836 Cubes cubes( cube_dim.x(), cube_dim.y(), cube_dim.z() );
838 for (
core::Size i = 1; i <= n_points; ++i ) {
842 CubeKey
const cube_key(
843 core::Size( ( pp.x() - bbl.x() ) * side_inv ) + 1,
844 core::Size( ( pp.y() - bbl.y() ) * side_inv ) + 1,
845 core::Size( ( pp.z() - bbl.z() ) * side_inv ) + 1
849 assert( cube_key.x() <= cube_dim.x() );
850 assert( cube_key.y() <= cube_dim.y() );
851 assert( cube_key.z() <= cube_dim.z() );
855 core::Size i_index = cubes.index( cube_key.x(), cube_key.y(), cube_key.z() );
856 if ( cubes[ i_index ].
size() == 0 ) {
866 cubes[ i_index ].reserve( 10 );
868 cubes[ i_index ].push_back( i );
874 for (
core::Size i = 1; i <= n_points; ++i ) {
876 if ( !residue_selection[ i ] )
continue;
885 for (
core::Size ix = max( icx,
core::Size( 2 ) ) - 1, ixe = min( icx + 1, cube_dim.x() ); ix <= ixe; ++ix ) {
886 for (
core::Size iy = max( icy,
core::Size( 2 ) ) - 1, iye = min( icy + 1, cube_dim.y() ); iy <= iye; ++iy ) {
887 for (
core::Size iz = max( icz,
core::Size( 2 ) ) - 1, ize = min( icz + 1, cube_dim.z() ); iz <= ize; ++iz ) {
890 core::Size cube_index = cubes.index( ix, iy, iz );
894 if ( cubes[ cube_index ].
size() != 0 ) {
895 for ( PointIDs::iterator ia = cubes[ cube_index ].begin(), iae = cubes[ cube_index ].
end(); ia != iae; ++ia ) {
898 if ( i < j || !residue_selection[ j ]) {
899 core::Real const d_sq( pp.distance_squared( points[ j ] ) );
900 if ( d_sq <= neighbor_cutoff_sq )
902 point_graph->add_edge( i, j, Edge( d_sq ) );
924 template <
class Vertex,
class Edge>
933 find_neighbors<Vertex,Edge>(point_graph,neighbor_cutoff,strategy);
941 if(d_squared < min_d_squared)
943 min_d_squared = d_squared;
944 min_node_index = query_it->upper_vertex();
947 return min_node_index;
950 template <
class Vertex,
class Edge>
961 core::Size const n_points( point_graph->num_vertices() );
962 if ( n_points == 0 )
return;
963 core::Real neighbor_cutoff_sq = neighbor_cutoff * neighbor_cutoff;
966 if ( n_points <= 1 )
return;
970 for (
Size ii = 1; ii <= non_surface_ranges.size(); ++ii ) {
971 for (
Size jj = non_surface_ranges[ ii ].first, jjend = non_surface_ranges[ ii ].second; jj <= jjend; ++jj ) {
972 PointPosition const & jj_pos( point_graph->get_vertex(jj).data().xyz() );
973 for (
Size kk = 1; kk <= n_points; ++kk ) {
974 if ( ! is_surface[ kk ] && kk <= jj )
continue;
975 Real const d_sq( jj_pos.distance_squared( point_graph->get_vertex( kk ).data().xyz() ) );
976 if ( d_sq <= neighbor_cutoff_sq ) {
977 Size lower = kk < jj ? kk : jj;
978 Size upper = kk < jj ? jj : kk;
979 point_graph->add_edge( lower, upper, Edge( d_sq ) );