13 #include <ObjexxFCL/FArray2D.hh>
17 #include <utility/file/FileName.hh>
18 #include <utility/file/PathName.hh>
19 #include <utility/exit.hh>
20 #include <utility/file/file_sys_util.hh>
22 #include <basic/prof.hh>
34 #include <basic/Tracer.hh>
35 #include <basic/options/option.hh>
39 #include <basic/options/keys/mc.OptionKeys.gen.hh>
40 #include <basic/options/keys/cluster.OptionKeys.gen.hh>
42 #include <utility/vector1.hh>
53 namespace canonical_sampling {
54 namespace mc_convergence_checks {
56 static basic::Tracer
TR(
"HierarchicalLevel");
59 using namespace basic;
90 for( std::list< PoolData >::iterator itr =
pool_cache_.begin();
94 addresses_at_level.push_back( addr );
95 num_addresses_at_level++;
101 max_cache_size_( 100 ),
103 max_levels_( maxlevels ),
105 num_clusters_in_level_(0),
106 next_free_address_index_(0)
108 using namespace basic::options;
109 using namespace basic::options::OptionKeys;
112 universal_address[ 1 ] = 1;
118 if(
TR.visible() ) {
TR.Debug <<
"new hierarchical-level created, level=" <<
level_ <<
" radius=" <<
radius_ << std::endl;}
137 using namespace basic::options;
138 using namespace basic::options::OptionKeys;
141 universal_address[ 1 ] = 1;
147 if(
TR.visible() ) {
TR.Debug <<
"new hierarchical-level created, level=" <<
level_ <<
" radius=" <<
radius_ << std::endl; }
164 using namespace basic::options;
165 using namespace basic::options::OptionKeys;
168 if(
TR.visible() ) {
TR.Debug <<
"new hierarchical-level created level=" <<
level_ <<
" radius=" <<
radius_ << std::endl; }
202 runtime_assert(
level_ == level );
238 std::list<PoolData>::iterator
240 PROF_START( basic::HIERARCHICAL_FIND );
244 std::list<PoolData>::iterator itr =
pool_cache_.begin();
252 PROF_STOP( basic::HIERARCHICAL_FIND );
257 PROF_START( basic::HIERARCHICAL_FIND );
264 bool found_addr =
next_level_->level_find( addr, level, itr );
266 }
else if(
level_ == level ) {
268 TR.Debug <<
"searching for address: ";
269 for(
core::Size ii = 1; ii <= addr.size(); ii++ ) {
270 TR.Debug << addr[ ii ] <<
" ";
272 TR.Debug <<
" at level: " << level << std::endl;
274 runtime_assert(
level_ == level );
278 bool load_if_missing =
false;
285 TR.Debug <<
"found address at level: " << level <<
" : ";
286 for(
core::Size ii = 1; ii <= tmp.size(); ii++ ) {
287 TR.Debug << tmp[ ii] <<
" ";
289 TR.Debug <<
" size of pool: " << (*itr).pool_->size() << std::endl;
300 TR.Debug <<
"found address at level: " << level <<
" : ";
301 for(
core::Size ii = 1; ii <= tmp.size(); ii++ ) {
302 TR.Debug << tmp[ ii] <<
" ";
304 TR.Debug <<
" size of pool: " << (*itr).pool_->size() << std::endl;
309 TR.Error <<
"you got to a point in level_find that you shouldn't have gotten to" << std::endl;
310 PROF_STOP( basic::HIERARCHICAL_FIND );
318 runtime_assert( address1.size() == address2.size() );
320 for(
core::Size ii = 1; ii < address1.size(); ii++ ) {
321 if( address1[ ii ] == address2[ ii ] ) {
322 num_matching_levels++;
333 if( address1.size() != address2.size() )
return false;
335 for(
core::Size ii = 1; ii <= address1.size(); ii++ ) {
336 if( address1[ ii ] != address2[ ii ] && address1[ ii ] != 0 && address2[ ii ] != 0 ) {
353 if( new_level == 0 ) {
354 new_level = tmp_address.size() + 1;
356 for(
core::Size ii = new_level; ii <= tmp_address.size(); ii++ ) {
357 tmp_address[ ii ] = 0;
360 add_new( coord, tag, address );
361 if( write_to_file ) {
366 ss->fill_struct(pose, tag);
368 for(
core::Size ii = ( new_level - 1 ); ii <= tmp_address.size(); ii++ ) {
372 if(
TR.visible() ) {
TR.Debug <<
"this file " << silent_outfile <<
" does not exist. attempting to create" << std::endl; }
373 utility::file::create_directory_recursive( file.path() );
374 utility::file::create_blank_file( file.name() );
376 os.open( (file.name()).c_str() );
377 ss->print_header( os );
381 os.open( (file.name()).c_str(), std::ios::app );
382 ss->print_header( os );
386 if(
TR.visible() ) {
TR.Debug <<
"writing " << ss->decoy_tag() <<
" to " << silent_outfile << std::endl; }
388 os.open( (silent_outfile).c_str(), std::ios::app );
391 if( ii < tmp_address.size() ) {
392 tmp_address[ ii + 1 ] = address[ ii + 1 ];
406 if( new_level == 0 ) {
407 new_level = tmp_address.size() + 1;
409 for(
core::Size ii = new_level; ii <= tmp_address.size(); ii++ ) {
410 tmp_address[ ii ] = 0;
413 add_new( coord, tag, address );
414 if( write_to_file ) {
416 for(
core::Size ii = ( new_level - 1 ); ii <= address.size(); ii++ ) {
422 utility::file::create_directory_recursive( file.path() );
423 utility::file::create_blank_file( file.name() );
425 os.open( (file.name()).c_str() );
430 os.open( (file.name()).c_str(), std::ios::app );
436 os.open( (silent_outfile).c_str(), std::ios::app );
439 if( ii < tmp_address.size() ) {
440 tmp_address[ ii + 1 ] = address[ ii + 1 ];
457 core::Size last_level_address =
evaluate( coord, best_decoy, best_rmsd, best_address );
458 return last_level_address;
469 core::Size last_level_address =
evaluate( coord, best_decoy, best_rmsd, best_address );
470 return last_level_address;
476 for( first_zero_pos = 1; first_zero_pos <= address.size(); first_zero_pos++ ) {
477 if( address[ first_zero_pos ] == 0 )
break;
486 for(
core::Size ii = 2; ii <= addr.size(); ii++ ) {
510 for(
core::Size ii = 1; ii <= max_levels_seen.size(); ii++ ) {
511 for(
core::Size jj = 1; jj <= max_levels_seen[ ii ]; jj++ ) {
512 path_address[ ii ] = jj;
515 os.open( filename.c_str(), std::ios::app );
516 ss->print_header( os );
524 PROF_START( basic::SORT_POOL );
525 if(
TR.visible() )
TR.Debug <<
"now going to sort pool" << std::endl;
529 tags.reserve( pool_ptr->size() );
530 if(
TR.visible() )
TR.Debug <<
"there are " << pool_ptr->size() <<
" structures in the starting pool-rmsd" << std::endl;
531 initial_order.reserve( pool_ptr->size() );
533 for(
core::Size ii = 1; ii <= pool_ptr->size(); ii++ ) {
536 tags.push_back( addr );
537 initial_order.push_back( addr );
542 for(
core::Size ii = 1; ii <= pool_ptr->size(); ii++ ) {
544 runtime_assert( index <= pool_ptr->
size());
545 pool_ptr->get( index, coords );
547 if(
TR.visible() )
TR.Debug <<
"adding structures with tag: " << newtag <<
" and " << coords.u2() <<
" residues index: " << index <<
" out of " << pool_ptr->size() << std::endl;
548 sorted_pool->add( coords, coords.u2(), newtag );
550 pool_ptr = sorted_pool;
551 PROF_STOP( basic::SORT_POOL );
556 PROF_START( basic::HIERARCHICAL_FIND_ADDRESS );
558 for( ii = 1; ii <= addresses.size(); ii++ ) {
564 PROF_STOP( basic::HIERARCHICAL_FIND_ADDRESS );
570 PROF_START( basic::HIERARCHICAL_SORT_ADDRESSES );
571 for(
core::Size ii = 1; ii <= addresses.size(); ii++ ) {
573 Address min_index_addr = addresses[ ii ];
574 for(
core::Size jj = ii + 1; jj <= addresses.size(); jj++ ) {
575 if(
less_than( addresses[ jj ], min_index_addr ) ) {
577 min_index_addr = addresses[ jj ];
580 if( ii != min_index ) {
581 tmp = addresses[ ii ];
582 addresses[ ii ] = min_index_addr;
586 PROF_STOP( basic::HIERARCHICAL_SORT_ADDRESSES );
593 while( pos < length ) {
595 result_addr.push_back( atoi(addr.substr( pos+1, newpos - pos - 1).c_str() ) );
602 std::ostringstream q;
603 for(
core::Size ii = 1; ii < addr.size(); ii++ ) {
604 q << addr[ ii ] <<
".";
606 q << addr[ addr.size() ];
607 newtag =
"new." + q.str();
612 if(addr1.size() < addr2.size() ) {
615 for(
core::Size ii = 1; ii <= addr1.size(); ii++ ) {
616 if( addr1[ ii ] != addr2[ ii ] ) {
617 if( addr1[ ii ] < addr2[ ii ] ) {
665 for(
core::Size ii =1; ii <= addr.size(); ii++ ) {
678 return evaluate( coords, best_decoy, best_rmsd, best_indices,
true,
true );
687 bool reset_all_levels,
688 bool load_if_missing_from_cache
690 using namespace basic;
691 PROF_START( basic::HIERARCHICAL_EVALUATE );
695 if( reset_all_levels ) {
696 reset( best_indices, best_rmsd );
697 best_indices[ 1 ] = 1;
702 return next_level_->evaluate( coords, best_decoy, best_rmsd, best_indices, reset_all_levels, load_if_missing_from_cache );
705 std::list<PoolData>::iterator addr_itr =
find( best_indices );
708 bool element_exists_in_cache =
true;
710 if(
TR.visible() )
TR.Debug <<
"address at time of evaluation for level " <<
level_ <<
" is: ";
print_address( best_indices );
713 if(
TR.visible() )
TR.Debug <<
"address doesn't exist in cache, but exists on file... loading..." << std::endl;
714 element_exists_in_cache =
false;
715 if( load_if_missing_from_cache ) {
721 TR <<
"loading " <<
lib_full_path( best_indices ) <<
" from file" << std::endl;
723 matching_pool =
load_pool( best_indices );
726 if(
TR.visible() )
TR.Debug <<
"element doesn't exist in cache and we're not allowed to load from file, exiting eval" << std::endl;
737 matching_pool = (*addr_itr);
739 matching_pool_ptr = matching_pool.pool_;
740 if( element_exists_in_cache &&
pool_cache_.size() > 1 ) {
741 if(
TR.visible() ) {
TR.Debug <<
"EVAL: element exists in cache, shuffling to front" << std::endl;}
750 level_address = ((*
pool_cache_.begin()).
pool_)->evaluate( coords, best_decoy, best_level_rmsd );
751 round( best_level_rmsd );
753 bool outside_known_structures =
false;
757 if(
TR.visible() )
TR.Debug <<
"going down to next level" << std::endl;
758 if( best_level_rmsd >
radius_ ) {
761 if(
TR.visible() ) {
TR.Debug <<
"best level rmsd: " << best_level_rmsd <<
" greater than radius: " <<
radius_ << std::endl; }
762 outside_known_structures =
true;
763 best_indices[
level_ + 1 ] = 0;
764 best_rmsd[
level_ ] = best_level_rmsd;
765 if(
TR.visible() )
TR.Debug <<
"assigned values 0 and " << best_level_rmsd <<
" to best_indices and best_rmsd " << std::endl;
767 best_indices[
level_ + 1 ] = level_address;
768 best_rmsd[
level_ ] = best_level_rmsd;
769 if(
TR.visible() )
TR.Debug <<
"assigned values " << level_address <<
" and " << best_level_rmsd <<
" to best_indices and best_rmsd " << std::endl;
771 if( !outside_known_structures ) {
772 if(
TR.visible() ) {
TR.Debug <<
"EVAL: now going one level down to evaluate recursively " << std::endl; }
773 last_level_address =
next_level_->evaluate( coords, best_decoy, best_rmsd, best_indices, reset_all_levels, load_if_missing_from_cache );
776 if(
TR.visible() )
TR.Debug <<
"reached last level: assigning a value of " <<
level_ <<
" and rms: " << best_level_rmsd << std::endl;
777 best_rmsd[
level_ ] = best_level_rmsd;
778 return level_address;
780 PROF_STOP( basic::HIERARCHICAL_EVALUATE );
781 return last_level_address;
786 PROF_START( basic::HIERARCHICAL_ROUND );
788 if(
TR.visible() )
TR.Debug <<
"input to round is: " << best_rmsd <<
" ";
792 if( remainder >= 0.5 ) {
794 remainder = ceil(remainder);
799 remainder = floor(remainder);
805 best_rmsd = (remainder + floor(
t))/100;
807 if( (
int)(floor( best_rmsd * 10.0 )) % 10 == 0 ) {
808 best_rmsd = (floor(best_rmsd * 10)) / 10;
810 if(
TR.visible() )
TR.Debug <<
" output of round: " << best_rmsd << std::endl;
811 PROF_STOP( basic::HIERARCHICAL_ROUND );
816 TR.Debug <<
"testing ROUND:\n";
820 TR.Debug <<
t <<
" " << rounded << std::endl;
822 TR.Debug <<
"end testing ROUND\n";
849 PROF_START( basic::HIERARCHICAL_POOL_SIZE );
852 std::list< PoolData >::iterator itr;
854 if(
TR.visible() )
TR.Debug <<
"pool size from pool_size function is: " << (*itr).pool_->size() << std::endl;
855 return (*itr).pool_->size();
860 PROF_STOP( basic::HIERARCHICAL_POOL_SIZE );
866 runtime_assert(
level_ == 1 );
873 PROF_START( basic::HIERARCHICAL_ADD_ELEM_TO_CACHE );
876 newpooldat.pool_->add( coords, coords.u2(),
tag );
881 PROF_STOP( basic::HIERARCHICAL_ADD_ELEM_TO_CACHE );
888 return add_new( coord, tag, address,
false );
896 bool resolve_remaining_levels
898 using namespace basic;
899 PROF_START( basic::HIERARCHICAL_ADD );
903 TR.Error <<
" CANNOT ADD IF ADDRESS DOESN'T EXIST IN CACHE. exiting without adding!" << std::endl;
908 bool added_level =
false;
910 if( ( address_at_level > 0 &&
find( address ) ==
pool_cache_.end() ) ||
911 address_at_level == 0 ) {
914 new_level_addr[ ii ] = 0;
920 if( address[
level_ + 1 ] == 0 ) {
921 std::list<PoolData>::iterator itr;
924 address[
level_ + 1 ] = (*itr).pool_->size() + 1;
926 runtime_assert( (*itr).pool_->size() > 0 );
927 address[
level_ + 1 ] = (*itr).pool_->size();
930 address[
level_ + 1 ] = 1;
933 bool added_levels_to_child =
next_level_->add_new( coord, tag, address, resolve_remaining_levels );
934 if( added_levels_to_child && !added_level ) {
935 ( *
find( address ) ).
pool_->add( coord, coord.u2(),
tag );
938 if( address_at_level > 0 &&
find( address ) !=
pool_cache_.end() && !added_level ) {
939 ( *
find( address ) ).
pool_->add( coord, coord.u2(),
tag );
942 PROF_STOP( basic::HIERARCHICAL_ADD );
959 for( std::list< PoolData >::iterator it =
pool_cache_.begin();
967 if(
TR.visible() )
TR.Debug <<
"level: " <<
level_ <<
" ";
969 Address addr = (*itr).address_;
971 for(
core::Size ii = 1; ii <= addr.size(); ii++ ) {
972 TR.Debug << addr[ ii ] <<
" ";
977 if(
TR.visible() )
TR.Debug << std::endl;
986 if(
TR.visible() ) {
TR.Debug <<
"level: " <<
level_ <<
" size of level: " <<
size() << std::endl; }
987 for( std::list< PoolData >::iterator itr =
pool_cache_.begin();
992 TR.Debug <<
" expecting: " << poolop->size() << std::endl;
993 for(
core::Size ii = 1; ii <= poolop->size(); ii++ ) {
994 TR.Debug << poolop->get_tag( ii ) << std::endl;
996 TR.Debug <<
"end pool at this level" << std::endl;
1006 if(
TR.visible() )
TR.Debug <<
"size per level: " <<
level_ <<
" " << this->size() <<
" ";
1007 for( std::list< PoolData >::iterator itr =
pool_cache_.begin();
1009 if(
TR.visible() ) {
1010 TR.Debug <<
"address: ";
1011 for(
core::Size ii = 1; ii <= (*itr).address_.size(); ii++ ) {
1012 TR.Debug << (*itr).address_[ ii ] <<
" ";
1014 TR.Debug <<
", size: " << (*itr).pool_->size() <<
" | ";
1015 TR.Debug << std::endl;
1029 has_address = has_address &&
next_level_->address_exists_in_cache( address );
1047 PROF_START( basic::LOAD_HIERARCHY );
1062 while( pool_ptr->size() == 0 && ntries > 0 ) {
1073 runtime_assert( pool_ptr->size() > 0 );
1084 PROF_STOP( basic::LOAD_HIERARCHY );
1085 return PoolData( pool_ptr, address );
1090 using namespace basic::options;
1091 using namespace basic::options::OptionKeys;
1119 std::list< PoolData >::iterator itr =
pool_cache_.begin();
1120 while( count < index ) {
1123 return (*itr).address_;
1130 for(
core::Size ii = 1; ii <= address.size(); ii++ ) {
1131 TR.Debug << address[ ii ] <<
" ";
1133 TR.Debug << std::endl;
1139 PROF_START( basic::LIB_FULL_PATH );
1140 using namespace core;
1141 using namespace basic::options;
1142 using namespace basic::options::OptionKeys;
1143 using namespace std;
1145 runtime_assert(address[ 1 ] > 0 );
1152 int nofsubdir = option[cluster::K_n_sub];
1159 std::ostringstream fnstream;
1163 if( address[ 1 ] == 0 ){
1164 last_num_not_zero = 1;
1166 for( last_num_not_zero = 1; last_num_not_zero < address.size(); last_num_not_zero++ ) {
1167 if( address[ last_num_not_zero + 1 ] == 0 ) {
1172 runtime_assert( last_num_not_zero > 0 );
1174 fnstream <<
"c_" << setfill (
'0') << setw (5) << address[last_num_not_zero] <<
".out";
1177 for (
Size i=last_num_not_zero; i >= 1; i--)
1179 ostringstream pathstream1;
1180 ostringstream pathstream2;
1183 if (i>1) pathstream1 << libdir_prefix << setfill (
'0') << setw (5) << address[i-1] << libdir_suffix << s ;
1185 pathstream2 << subdir_prefix << setfill (
'0') << setw (3) <<
int((address[i]-1)/nofsubdir) << s;
1186 fn = pathstream1.str()+pathstream2.str()+fn;
1189 if(
TR.visible() ) {
1190 TR.Debug <<
"LIB_FULL_PATH: from address: ";
1191 for(
core::Size ii = 1; ii <= address.size(); ii++ ) {
1192 TR.Debug << address[ ii ] <<
" ";
1194 TR.Debug <<
" got file-name: " << defaultpath+fn;
1196 PROF_STOP( basic::LIB_FULL_PATH );
1197 return defaultpath+fn;