24 #include <boost/unordered_map.hpp>
38 #include <basic/Tracer.hh>
39 #include <basic/options/option.hh>
40 #include <basic/options/keys/lh.OptionKeys.gen.hh>
42 #include <numeric/HomogeneousTransform.hh>
46 #include <utility/excn/Exceptions.hh>
47 #include <utility/exit.hh>
48 #include <utility/fixedsizearray1.hh>
49 #include <utility/pointer/owning_ptr.hh>
51 #include <numeric/angle.functions.hh>
52 #include <numeric/geometry/hashing/SixDHasher.hh>
62 #include <boost/lexical_cast.hpp>
66 #include <utility/vector1.hh>
68 #if defined(WIN32) || defined(__CYGWIN__)
74 using namespace protocols::moves;
75 using namespace core::scoring;
77 using namespace core::pose;
78 using namespace conformation;
79 using namespace kinematics;
80 using namespace protocols::frag_picker;
92 static basic::Tracer
TR(
"LoopHashMap");
100 using namespace core;
101 using namespace core::pose;
102 using namespace conformation;
103 using namespace kinematics;
104 using namespace numeric::geometry::hashing;
110 while (!pose.residue_type(nres).is_polymer()) nres--;
114 std::sort( cuts_in.begin(), cuts_in.end() );
117 for (
Size i=1; i<=cuts_in.size(); ++i) {
118 if (cuts_in[i]<=jr && cuts_in[i]>=ir) {
119 TR.Error <<
"ERROR -- residue range crosses cut IR: " << ir <<
" JR: " << jr <<
" CUT: " << cuts_in[i] << std::endl;
124 if (cuts_in[i]==ir-1) {
125 TR.Error <<
"ERROR -- startres immediately follows cut IR: " << ir <<
" CUT: " << cuts_in[i] << std::endl;
145 for (
Size i=1; i<=cuts_in.size(); ++i) {
146 if (cuts_in[i] >= nres)
break;
147 if (cutpoint > last_cut && cutpoint < cuts_in[i]) {
148 f.
add_edge( last_cut+1, ir, Edge::PEPTIDE );
149 f.add_edge( ir, cutpoint, Edge::PEPTIDE );
150 f.add_edge( cutpoint + 1, jr, Edge::PEPTIDE );
151 f.add_edge( jr, cuts_in[i] , Edge::PEPTIDE );
152 f.add_edge( ir, jr, 1 );
153 if (last_cut!=0) f.add_edge( 1, last_cut+1, jump_num++);
155 f.add_edge( last_cut+1, cuts_in[i], Edge::PEPTIDE );
156 if (last_cut!=0) f.add_edge( 1, last_cut+1, jump_num++);
158 last_cut = cuts_in[i];
160 if (last_cut+1 <= nres) {
161 if (cutpoint > last_cut && cutpoint < nres) {
162 f.add_edge( last_cut+1, ir, Edge::PEPTIDE );
163 f.add_edge( ir, cutpoint, Edge::PEPTIDE );
164 f.add_edge( cutpoint + 1, jr, Edge::PEPTIDE );
165 f.add_edge( jr, nres , Edge::PEPTIDE );
166 f.add_edge( ir, jr, 1 );
167 if (last_cut!=0) f.add_edge( 1, last_cut+1, jump_num++);
169 f.add_edge( last_cut+1, nres, Edge::PEPTIDE );
170 if (last_cut!=0) f.add_edge( 1, last_cut+1, jump_num++);
173 for (
core::Size i=nres+1; i<=pose.total_residue(); ++i)
174 f.add_edge( 1, i, jump_num++ );
177 if( ir == 1 ) theroot = pose.total_residue();
179 if( f.reorder(theroot) == false ){
180 TR.Error <<
"ERROR During reordering of fold tree - am ignoring this LOOP ! bailing: The root: " << theroot <<
" NRES " << pose.total_residue() <<
" IR: " << ir <<
" JR: " << jr << std::endl;
189 myjump = pose.jump( 1 );
195 numeric::HomogeneousTransform< Real > ht( rt.get_rotation() , rt.get_translation() );
198 rt_6[1] = rt.get_translation().x();
199 rt_6[2] = rt.get_translation().y();
200 rt_6[3] = rt.get_translation().z();
201 rt_6[4] = euler_angles.x()*180.0/numeric::constants::d::pi;
202 rt_6[5] = euler_angles.y()*180.0/numeric::constants::d::pi;
203 rt_6[6] = euler_angles.z()*180.0/numeric::constants::d::pi;
215 using namespace core;
216 using namespace core::pose;
217 using namespace conformation;
218 using namespace kinematics;
219 using namespace numeric::geometry::hashing;
230 std::sort( cuts_in.begin(), cuts_in.end() );
233 for (
Size i=1; i<=cuts_in.size(); ++i) {
234 if (cuts_in[i]<=jr && cuts_in[i]>=ir) {
235 TR.Error <<
"ERROR -- residue range crosses cut IR: " << ir <<
" JR: " << jr <<
" CUT: " << cuts_in[i] << std::endl;
240 if (cuts_in[i]==ir-1) {
241 TR.Error <<
"ERROR -- startres immediately follows cut IR: " << ir <<
" CUT: " << cuts_in[i] << std::endl;
261 for (
Size i=1; i<=cuts_in.size(); ++i) {
262 if (cuts_in[i] >= nres)
break;
263 if (cutpoint > last_cut && cutpoint < cuts_in[i]) {
264 f.
add_edge( last_cut+1, ir, Edge::PEPTIDE );
265 f.add_edge( ir, cutpoint, Edge::PEPTIDE );
266 f.add_edge( cutpoint + 1, jr, Edge::PEPTIDE );
267 f.add_edge( jr, cuts_in[i] , Edge::PEPTIDE );
268 f.add_edge( ir, jr, 1 );
269 if (last_cut!=0) f.add_edge( 1, last_cut+1, jump_num++);
271 f.add_edge( last_cut+1, cuts_in[i], Edge::PEPTIDE );
272 if (last_cut!=0) f.add_edge( 1, last_cut+1, jump_num++);
274 last_cut = cuts_in[i];
276 if (last_cut+1 <= nres) {
277 if (cutpoint > last_cut && cutpoint < nres) {
278 f.add_edge( last_cut+1, ir, Edge::PEPTIDE );
279 f.add_edge( ir, cutpoint, Edge::PEPTIDE );
280 f.add_edge( cutpoint + 1, jr, Edge::PEPTIDE );
281 f.add_edge( jr, nres , Edge::PEPTIDE );
282 f.add_edge( ir, jr, 1 );
283 if (last_cut!=0) f.add_edge( 1, last_cut+1, jump_num++);
285 f.add_edge( last_cut+1, nres, Edge::PEPTIDE );
286 if (last_cut!=0) f.add_edge( 1, last_cut+1, jump_num++);
290 f.add_edge( 1, i, jump_num++ );
294 if( newroot>0 ) theroot = newroot;
295 if( f.reorder(theroot) == false ){
296 TR.Error <<
"ERROR During reordering of fold tree - am ignoring this LOOP ! bailing: The root: " << theroot <<
" NRES " << pose.
total_residue() <<
" IR: " << ir <<
" JR: " << jr << std::endl;
305 myjump = pose.
jump( 1 );
315 numeric::HomogeneousTransform< Real > ht( rt.get_rotation() , rt.get_translation() );
319 rt_6[1] = rt.get_translation().x();
320 rt_6[2] = rt.get_translation().y();
321 rt_6[3] = rt.get_translation().z();
322 rt_6[4] = euler_angles.x()*180.0/numeric::constants::d::pi;
323 rt_6[5] = euler_angles.y()*180.0/numeric::constants::d::pi;
324 rt_6[6] = euler_angles.z()*180.0/numeric::constants::d::pi;
352 rt_6[4] = euler_angles.x()*180.0/numeric::constants::d::pi;
353 rt_6[5] = euler_angles.y()*180.0/numeric::constants::d::pi;
354 rt_6[6] = euler_angles.z()*180.0/numeric::constants::d::pi;
362 loop_size_ = loop_size;
366 void LoopHashMap::mem_foot_print(){
367 TR <<
"loopdb_: " << loopdb_.size() <<
" Size: " << loopdb_.size() *
sizeof(
LeapIndex ) << std::endl;
368 TR <<
"BackboneIndexMap: " << backbone_index_map_.size() <<
" Size: " << backbone_index_map_.size() * (
sizeof(boost::uint64_t) +
sizeof(
core::Size) ) << std::endl;
371 void LoopHashMap::sort() {
372 std::sort( loopdb_.begin(), loopdb_.end(),
by_index() );
378 loop_size_ = loop_size;
383 TR.Info <<
"Setting up hash_: Size: " << loop_size << std::endl;
398 euler_offsets[1] = 0;
399 euler_offsets[2] = 0;
400 euler_offsets[3] = 0;
406 using namespace basic::options;
407 using namespace basic::options::OptionKeys;
409 if( option[ lh::grid_space_multiplier].user() ) {
410 space_multiplier = option[ lh::grid_space_multiplier]();
412 if( option[ lh::grid_angle_multiplier].user() ) {
413 angle_multiplier = option[ lh::grid_angle_multiplier]();
416 bin_widths[1] = space_multiplier*loop_size;
417 bin_widths[2] = space_multiplier*loop_size;
418 bin_widths[3] = space_multiplier*loop_size;
419 bin_widths[4] = angle_multiplier*loop_size;
420 bin_widths[5] = angle_multiplier*loop_size;
421 bin_widths[6] = angle_multiplier*loop_size;
423 hash_ =
new numeric::geometry::hashing::SixDCoordinateBinner( bounding_box, euler_offsets, bin_widths );
425 hash_->tree_init(option[lh::max_radius]());
432 rt_6[1] = legacyleap_index.
vecx;
433 rt_6[2] = legacyleap_index.
vecy;
434 rt_6[3] = legacyleap_index.
vecz;
435 rt_6[4] = legacyleap_index.
rotx;
436 rt_6[5] = legacyleap_index.
roty;
437 rt_6[6] = legacyleap_index.
rotz;
439 leap_index.
index = 0;
440 leap_index.
offset = legacyleap_index.
ba;
441 add_leap( leap_index, rt_6 );
444 void LoopHashMap::add_leap(
const LeapIndex &leap_index, boost::uint64_t key ) {
446 loopdb_.push_back( leap_index );
448 backbone_index_map_.insert( std::make_pair( key, cpindex ));
453 loopdb_.push_back( leap_index );
455 rt_6[1] = transform[1];
456 rt_6[2] = transform[2];
457 rt_6[3] = transform[3];
458 rt_6[4] = transform[4];
459 rt_6[5] = transform[5];
460 rt_6[6] = transform[6];
461 while( rt_6[ 4 ] < 0.0 ) rt_6[ 4 ] += 360.0;
462 while( rt_6[ 4 ] >= 360.0 ) rt_6[ 4 ] -= 360.0;
463 while( rt_6[ 5 ] < 0.0 ) rt_6[ 5 ] += 360.0;
464 while( rt_6[ 5 ] >= 360.0 ) rt_6[ 5 ] -= 360.0;
465 while( rt_6[ 6 ] < 0.0 ) rt_6[ 6 ] += 180.0;
466 while( rt_6[ 6 ] > 180.0 ) rt_6[ 6 ] -= 180.0;
467 if( !( rt_6[ 4 ] >= 0.0 && rt_6[ 4 ] < 360.0 )) { std::cerr <<
"rt_6[4] out of bounds: " << rt_6[4] << std::endl; utility_exit_with_message(
"RANGE ERROR" ); }
468 if( !( rt_6[ 5 ] >= 0.0 && rt_6[ 5 ] < 360.0 )) { std::cerr <<
"rt_6[5] out of bounds: " << rt_6[5] << std::endl; utility_exit_with_message(
"RANGE ERROR" ); }
469 if( !( rt_6[ 6 ] >= 0.0 && rt_6[ 6 ] <= 180.0 )) { std::cerr <<
"rt_6[6] out of bounds: " << rt_6[6] << std::endl; utility_exit_with_message(
"RANGE ERROR" ); }
470 hash_index( rt_6, cpindex );
475 if( ! hash_->contains( transform ) ){
480 boost::uint64_t bin_index = hash_->bin_index( transform );
482 loopdb_[data].key = bin_index;
484 backbone_index_map_.insert( std::make_pair( bin_index, data ) );
488 void LoopHashMap::bbdb_range( std::pair< BackboneIndexMap::iterator, BackboneIndexMap::iterator > &
range ){
489 range.first = backbone_index_map_.begin();
490 range.second = backbone_index_map_.end();
498 if( ! hash_->contains( transform ) ){
503 transform[4] = numeric::nonnegative_principal_angle_degrees(transform[4] );
504 transform[5] = numeric::nonnegative_principal_angle_degrees(transform[5] );
505 boost::uint64_t bin_index = hash_->bin_index( transform );
510 BackboneIndexMap::iterator>
range = backbone_index_map_.equal_range( bin_index );
513 for( BackboneIndexMap::iterator it = range.first;
517 result.push_back( it->second );
524 center[4] = numeric::nonnegative_principal_angle_degrees(center[4] );
525 center[5] = numeric::nonnegative_principal_angle_degrees(center[5] );
526 std::vector< boost::uint64_t > bin_index_vec = hash_->radial_bin_index( radius, center );
528 for(
core::Size i = 0; i < bin_index_vec.size(); ++i ) {
531 BackboneIndexMap::iterator>
range = backbone_index_map_.equal_range( bin_index_vec[i] );
532 for( BackboneIndexMap::iterator it = range.first;
536 result.push_back( it->second );
543 center[4] = numeric::nonnegative_principal_angle_degrees(center[4] );
544 center[5] = numeric::nonnegative_principal_angle_degrees(center[5] );
545 std::vector< boost::uint64_t > bin_index_vec = hash_->radial_bin_index( radius, center );
547 for(
core::Size i = 0; i < bin_index_vec.size(); ++i ) {
548 count += backbone_index_map_.count( bin_index_vec[i] );
556 std::vector < core::Size > &result
559 if( index > backbone_index_map_.bucket_count()){
564 BackboneIndexMap::local_iterator begin = backbone_index_map_.begin( index );
565 BackboneIndexMap::local_iterator
end = backbone_index_map_.end( index );
567 for( BackboneIndexMap::local_iterator it = begin; it !=
end; ++it) {
568 result.push_back( it->second );
575 LeapIndex leap_index = get_peptide( bb_index );
576 return leap_index.
key;
580 LoopHashMap::radial_lookup_withkey( boost::uint64_t key,
core::Size radius, std::vector < core::Size > &result )
584 radial_lookup( radius, center, result );
588 LoopHashMap::lookup_withkey( boost::uint64_t key, std::vector < core::Size > &result )
591 BackboneIndexMap::iterator>
range = backbone_index_map_.equal_range( key );
593 for( BackboneIndexMap::iterator it = range.first; it != range.second; ++it) {
594 result.push_back( it->second );
602 FILE *file = fopen( filename.c_str(),
"r" );
606 while( !feof( file ) ){
607 const unsigned int bufsize = 128;
609 size_t readshorts = fread(&bufferdata[0],
sizeof(
LegacyLeapIndex),bufsize,file);
610 for(
unsigned i = 0; i< readshorts; i ++ ){
611 add_legacyleap( bufferdata[i] );
615 loopdb_.reserve( loopdb_.size() );
617 TR.Info <<
"Rehashed dataset:" << backbone_index_map_.size() <<
" " << loopdb_.size() << std::endl;
618 TR.Info <<
"Rehashed dataset: OUTOFBOUNDS: " << loopdb_.size() - backbone_index_map_.size() << std::endl;
622 std::ofstream file( filename.c_str() );
624 for(
core::Size i = 0; i < loopdb_.size(); i++ ){
625 file << loopdb_[i].index <<
" " << loopdb_[i].offset <<
" " << loopdb_[i].key << std::endl;
631 LoopHashMap::read_db(
633 std::map< core::Size, bool > & homolog_index
635 std::ifstream file( filename.c_str() );
639 while( getline( file, line ) ) {
640 std::vector<std::string> output;
642 while(sline >> t){ output.push_back(t); }
645 if( leap_index.
index < loopdb_range.first )
continue;
646 if( leap_index.
index >= loopdb_range.second && loopdb_range.second != 0 )
continue;
649 leap_index.
index -= loopdb_range.first;
651 if( homolog_index.find( leap_index.
index ) != homolog_index.end() )
continue;
653 leap_index.
key = boost::lexical_cast< boost::uint64_t > ( output[2] );
654 add_leap( leap_index, leap_index.
key );
656 TR.Info <<
"Loophashmap range " << loopdb_[0].index <<
" " << loopdb_[loopdb_.size() - 1].index << std::endl;