Rosetta 3.5
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
HierarchicalLevel.cc
Go to the documentation of this file.
4 #include <core/pose/Pose.hh>
5 #include <core/types.hh>
6 // AUTO-REMOVED #include <core/io/silent/ProteinSilentStruct.hh>
10 
11 // AUTO-REMOVED #include <numeric/random/random.hh>
12 
13 #include <ObjexxFCL/FArray2D.hh>
16 
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>
21 // AUTO-REMOVED #include <utility/io/izstream.hh>
22 #include <basic/prof.hh>
23 
24 #include <set>
25 #include <list>
26 #include <sstream>
27 #include <fstream>
28 #include <iostream>
29 // AUTO-REMOVED #include <sys/stat.h>
30 // AUTO-REMOVED #include <stdio.h>
31 // AUTO-REMOVED #include <errno.h>
32 // AUTO-REMOVED #include <math.h>
33 
34 #include <basic/Tracer.hh>
35 #include <basic/options/option.hh>
36 // AUTO-REMOVED #include <basic/options/option_macros.hh>
37 // AUTO-REMOVED #include <basic/options/keys/in.OptionKeys.gen.hh>
38 // AUTO-REMOVED #include <basic/options/keys/out.OptionKeys.gen.hh>
39 #include <basic/options/keys/mc.OptionKeys.gen.hh>
40 #include <basic/options/keys/cluster.OptionKeys.gen.hh>
41 
42 #include <utility/vector1.hh>
43 
44 //Auto Headers
45 #include <core/kinematics/Jump.hh>
46 
47 //this is actually only for debugging
48 #ifdef USEMPI
49 #include <mpi.h>
50 #endif
51 
52 namespace protocols{
53 namespace canonical_sampling {
54 namespace mc_convergence_checks {
55 
56  static basic::Tracer TR("HierarchicalLevel");
57  core::Real const MAX_RADIUS = 9999;
58 
59  using namespace basic;
60 
62  pool_(),
63  address_(),
64  nlevels_(0)
65  {}
66 
68  pool_(pool),
69  address_(address)
70  {
71  setup(nlevels);
72  }
73 
74  PoolData::PoolData( Pool_RMSD_OP pool, Address & address):
75  pool_(pool),
76  address_(address),
77  nlevels_(0)
78  {}
79 
80  void
82  nlevels_ = nlevels;
83  address_.resize(nlevels,0);
84  }
85 
86 
87  void
89  core::Size num_addresses_at_level = 0;
90  for( std::list< PoolData >::iterator itr = pool_cache_.begin();
91  itr != pool_cache_.end();
92  itr++ ) {
93  Address addr = (*itr).address_;
94  addresses_at_level.push_back( addr );
95  num_addresses_at_level++;
96  }
97  }
98 
100  pool_cache_(), //cache is filled as needed
101  max_cache_size_( 100 ),
102  level_(1),
103  max_levels_( maxlevels ),
104  radius_(),
105  num_clusters_in_level_(0),
106  next_free_address_index_(0)
107  {
108  using namespace basic::options;
109  using namespace basic::options::OptionKeys;
110 
111  utility::vector1< core::Size > universal_address( max_levels_ , 0 );
112  universal_address[ 1 ] = 1;
113  Pool_RMSD_OP poolrms = new Pool_RMSD();
114  pool_cache_.push_back( PoolData( poolrms, universal_address ) );
116  radius_ = option[ cluster::K_radius ]()[ level_ ];
117 
118  if( TR.visible() ) {TR.Debug << "new hierarchical-level created, level=" << level_ << " radius=" << radius_ << std::endl;}
119  if( ( level_ + 1 ) <= max_levels_ ) {
121  } else {
122  next_level_ = 0;
123  }
124  }
125 
126  //filename assumed to specify structures at top-most level
128  pool_cache_(), //cache is filled as needed
129  max_cache_size_( 100 ),
130  level_(1),
131  max_levels_( maxlevels ),
132  radius_(),
134  filename_(filename),
136  {
137  using namespace basic::options;
138  using namespace basic::options::OptionKeys;
139 
140  utility::vector1< core::Size > universal_address( max_levels_ , 0 );
141  universal_address[ 1 ] = 1;
142  Pool_RMSD_OP poolrms = new Pool_RMSD();
143  pool_cache_.push_back( PoolData( poolrms, universal_address ) );
145  radius_ = option[ cluster::K_radius ]()[ level_ ];
146 
147  if( TR.visible() ) { TR.Debug << "new hierarchical-level created, level=" << level_ << " radius=" << radius_ << std::endl; }
148  if( ( level_ + 1 ) <= max_levels_ ) {
150  } else {
151  next_level_ = 0;
152  }
153  }
154 
156  pool_cache_(), //cache is filled as needed
157  max_cache_size_( 100 ),
158  level_(level),
159  max_levels_(max_levels),
160  radius_(0),
163  {
164  using namespace basic::options;
165  using namespace basic::options::OptionKeys;
166 
167  radius_ = option[ cluster::K_radius ]()[ level_ ];
168  if( TR.visible() ) { TR.Debug << "new hierarchical-level created level=" << level_ << " radius=" << radius_ << std::endl; }
169  if( level_ < max_levels_ ) {
170  next_level_ = new HierarchicalLevel( level_ + 1, max_levels );
171  } else {
172  next_level_ = 0;
173  }
174  }
175 
176  std::string &
178  return filename_;
179  }
180 
183  return next_level_;
184  }
185 
186  void
188  radius_ = radius;
189  }
190 
191  core::Real
193  return radius_;
194  }
195 
196  core::Real
199  if( level_ != level && has_next_level() ) {
200  level_radius = next_level_->level_radius( level );
201  } else {
202  runtime_assert( level_ == level );
203  level_radius = radius_;
204  }
205  return level_radius;
206  }
207 
208  core::Size
210  return level_;
211  }
212 
213  core::Size
215  return max_levels_;
216  }
217 
218  void
220  max_cache_size_ = max_size;
221  if( has_next_level() ) {
222  next_level_->max_cache_size( max_size );
223  }
224  }
225 
226  core::Size
228  return max_cache_size_;
229  }
230 
231 
232  bool
234  return ( next_level_ != 0 );
235  }
236 
237  //if pool exists on file but not in memory, will not load pool from file
238  std::list<PoolData>::iterator
240  PROF_START( basic::HIERARCHICAL_FIND );
241  if( pool_cache_.size() == 0 ) {
242  return pool_cache_.end();
243  }
244  std::list<PoolData>::iterator itr = pool_cache_.begin();
245  while( itr != pool_cache_.end() ) {
246  if( equal_addresses( address, (*itr).address_ ) ) {
247  break;
248  }
249  itr++;
250  }
251  return itr;
252  PROF_STOP( basic::HIERARCHICAL_FIND );
253  }
254 
255  bool
256  HierarchicalLevel::level_find( Address & addr, core::Size const& level, std::list<PoolData>::iterator& itr ) { //find a particular address at a particular level
257  PROF_START( basic::HIERARCHICAL_FIND );
258  if( pool_cache_.size() == 0 && level == level_ ) {
259  itr = pool_cache_.end();
260  return false;
261  }
262 
263  if( level_ != level && has_next_level() ) {
264  bool found_addr = next_level_->level_find( addr, level, itr );
265  return found_addr;
266  } else if( level_ == level ) {
267  if( TR.visible() ) {
268  TR.Debug << "searching for address: ";
269  for( core::Size ii = 1; ii <= addr.size(); ii++ ) {
270  TR.Debug << addr[ ii ] << " ";
271  }
272  TR.Debug << " at level: " << level << std::endl;
273  }
274  runtime_assert( level_ == level );
275  runtime_assert( first_zero_pos( addr ) > level ); //not looking for an address that is unresolved
276  itr = find( addr );
277  //ek added 7/29/10
278  bool load_if_missing = false; //never load if missing!
279  if( load_if_missing && itr == pool_cache_.end() && pool_exists( addr ) ) { //pool exists on file, but not in memory
280  PoolData pd = load_pool( addr ); //load pool into cache and return itr to pool
281  pool_cache_.push_front( pd );
282  itr = pool_cache_.begin();
283  Address tmp = (*itr).address_;
284  if( TR.visible() ) {
285  TR.Debug << "found address at level: " << level << " : ";
286  for( core::Size ii = 1; ii <= tmp.size(); ii++ ) {
287  TR.Debug << tmp[ ii] << " ";
288  }
289  TR.Debug << " size of pool: " << (*itr).pool_->size() << std::endl;
290  }
291  return true;
292  //ek added 7/29/10
293  }
294  else if( itr == pool_cache_.end() ) { //if pool doesn't exists on file
295  return false;
296  }
297  else {
298  Address tmp = (*itr).address_;
299  if( TR.visible() ) {
300  TR.Debug << "found address at level: " << level << " : ";
301  for( core::Size ii = 1; ii <= tmp.size(); ii++ ) {
302  TR.Debug << tmp[ ii] << " ";
303  }
304  TR.Debug << " size of pool: " << (*itr).pool_->size() << std::endl;
305  }
306  return true;
307  }
308  }
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 );
311  return false;
312  }
313 
314 
315  core::Size
317  utility::vector1< core::Size > & address2 ){
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++;
323  }
324  }
325  return num_matching_levels;
326  }
327 
328 
329  bool
331  utility::vector1<core::Size> & address2) {
332  //runtime_assert( address1.size() == address2.size() );
333  if( address1.size() != address2.size() ) return false;
334  bool is_same = true;
335  for( core::Size ii = 1; ii <= address1.size(); ii++ ) {
336  if( address1[ ii ] != address2[ ii ] && address1[ ii ] != 0 && address2[ ii ] != 0 ) {
337  is_same = false;
338  }
339  }
340  return is_same;
341  }
342 
343 
344  void
346  std::string & tag,
348  bool write_to_file,
349  core::Size new_level) {
350  ObjexxFCL::FArray2D_double coord( 3, pose.total_residue(), 0.0 );
351  protocols::toolbox::fill_CA_coords( pose, coord );
353  if( new_level == 0 ) {
354  new_level = tmp_address.size() + 1; //no new levels
355  } else {
356  for( core::Size ii = new_level; ii <= tmp_address.size(); ii++ ) {
357  tmp_address[ ii ] = 0;
358  } //reset so we can write to all new-levels
359  }
360  add_new( coord, tag, address );
361  if( write_to_file ) {
362  if( TR.visible() ) { TR.Debug << "does this file exist? " << lib_full_path(tmp_address) << " " << utility::file::file_exists(lib_full_path( tmp_address )) << std::endl; }
364  sfd.strict_column_mode( true );
366  ss->fill_struct(pose, tag);
367 
368  for( core::Size ii = ( new_level - 1 ); ii <= tmp_address.size(); ii++ ) { //need to add to very last level as well
369  std::string silent_outfile = lib_full_path( tmp_address );
370  utility::file::FileName file( silent_outfile );
371  if( !utility::file::file_exists(silent_outfile) ) {
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() );
375  std::ofstream os;
376  os.open( (file.name()).c_str() );
377  ss->print_header( os ); //temporary fix
378  os.close();
379  } else {
380  std::ofstream os;
381  os.open( (file.name()).c_str(), std::ios::app );
382  ss->print_header( os ); //temporary fix
383  os.close();
384  }
385  //runtime_assert( utility::file::file_exists(silent_outfile) ) ;
386  if( TR.visible() ) { TR.Debug << "writing " << ss->decoy_tag() << " to " << silent_outfile << std::endl; }
387  std::ofstream os;
388  os.open( (silent_outfile).c_str(), std::ios::app );
389  sfd._write_silent_struct( (*ss), os, false );
390  os.close();
391  if( ii < tmp_address.size() ) {
392  tmp_address[ ii + 1 ] = address[ ii + 1 ];
393  }
394  }
395  }
396  }
397 
398  void
400  std::string & tag,
402  bool write_to_file,
403  core::Size new_level ) {
406  if( new_level == 0 ) {
407  new_level = tmp_address.size() + 1;
408  } else {
409  for( core::Size ii = new_level; ii <= tmp_address.size(); ii++ ) {
410  tmp_address[ ii ] = 0;
411  }
412  }
413  add_new( coord, tag, address );
414  if( write_to_file ) {
415  //actually requires some book-keeping to keep track of which ones to write
416  for( core::Size ii = ( new_level - 1 ); ii <= address.size(); ii++ ) {
418  sfd.strict_column_mode( true );
419  std::string silent_outfile = lib_full_path( tmp_address );
420  utility::file::FileName file( silent_outfile ); //temp fix
421  if( !utility::file::file_exists(silent_outfile)) {
422  utility::file::create_directory_recursive( file.path() );
423  utility::file::create_blank_file( file.name() );
424  std::ofstream os;
425  os.open( (file.name()).c_str() );//temp fix
426  ss.print_header( os ); //temporary fix
427  os.close();
428  } else {
429  std::ofstream os;
430  os.open( (file.name()).c_str(), std::ios::app );
431  ss.print_header( os ); //temporary fix
432  os.close();
433  }
434  runtime_assert( utility::file::file_exists(silent_outfile));
435  std::ofstream os;
436  os.open( (silent_outfile).c_str(), std::ios::app );
437  sfd._write_silent_struct( ss, os, false );
438  os.close();
439  if( ii < tmp_address.size() ) {
440  tmp_address[ ii + 1 ] = address[ ii + 1 ];
441  }
442  }
443  }
444 
445  }
446 
447 
448  core::Size
450  core::pose::Pose const& pose,
451  std::string & best_decoy,
452  utility::vector1< core::Real > & best_rmsd,
453  utility::vector1< core::Size > & best_address
454  ) {
455  ObjexxFCL::FArray2D_double coord( 3, pose.total_residue(), 0.0 );
456  protocols::toolbox::fill_CA_coords( pose, coord );
457  core::Size last_level_address = evaluate( coord, best_decoy, best_rmsd, best_address );
458  return last_level_address;
459  }
460 
461  core::Size
464  std::string & best_decoy,
465  utility::vector1< core::Real > & best_rmsd,
466  utility::vector1< core::Size > & best_address
467  ) {
469  core::Size last_level_address = evaluate( coord, best_decoy, best_rmsd, best_address );
470  return last_level_address;
471  }
472 
473  core::Size
476  for( first_zero_pos = 1; first_zero_pos <= address.size(); first_zero_pos++ ) {
477  if( address[ first_zero_pos ] == 0 ) break;
478  }
479  return first_zero_pos;
480  }
481 
482  void
484  addr.resize( max_levels_, 0 );
485  addr[ 1 ] = 1;
486  for( core::Size ii = 2; ii <= addr.size(); ii++ ) {
487  addr[ ii ] = 0;
488  }
489  if( level_ == 1 && has_next_level() ) {
490  next_level_->max_level_index( addr );
491  } else {
492  if( next_free_address_index_ > 0 ) {
494  } else {
495  std::string test_file = lib_full_path( addr );
496  while( utility::file::file_exists( test_file ) ) {
497  addr[ level_ ] = addr[ level_ ] + 1;
498  test_file = lib_full_path( addr );
499  }
500  addr[ level_ ] = addr[ level_ ] - 1;
501  }
502  }
503  }
504 
505  void
507  Address max_levels_seen( max_levels_, 0 );
508  max_level_index( max_levels_seen );
509  Address path_address( max_levels_, 0 );
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;
513  std::string filename = lib_full_path( path_address );
514  std::ofstream os;
515  os.open( filename.c_str(), std::ios::app );
516  ss->print_header( os );
517  os.close();
518  }
519  }
520  }
521 
522  void
524  PROF_START( basic::SORT_POOL );
525  if( TR.visible() ) TR.Debug << "now going to sort pool" << std::endl;
526  Pool_RMSD_OP sorted_pool = new Pool_RMSD();
528  utility::vector1< Address > initial_order;
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() );
532 
533  for( core::Size ii = 1; ii <= pool_ptr->size(); ii++ ) {
534  Address addr;
535  string_to_address( pool_ptr->get_tag( ii ), addr );
536  tags.push_back( addr );
537  initial_order.push_back( addr );
538  }
539 
540  sort_addresses( tags );
542  for( core::Size ii = 1; ii <= pool_ptr->size(); ii++ ) {
543  core::Size index = find_address( tags[ ii ], initial_order );
544  runtime_assert( index <= pool_ptr->size());
545  pool_ptr->get( index, coords );
546  std::string newtag = pool_ptr->get_tag( index );
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 );
549  }
550  pool_ptr = sorted_pool;
551  PROF_STOP( basic::SORT_POOL );
552  }
553 
554  core::Size
556  PROF_START( basic::HIERARCHICAL_FIND_ADDRESS );
557  core::Size ii;
558  for( ii = 1; ii <= addresses.size(); ii++ ) {
559  if( equal_addresses( addresses[ ii ], query ) ) {
560  break;
561  }
562  }
563  return ii;
564  PROF_STOP( basic::HIERARCHICAL_FIND_ADDRESS );
565  }
566 
567  void
568  HierarchicalLevel::sort_addresses( utility::vector1< Address >& addresses ) { //horribly inefficient, but just for starters
569  Address tmp;
570  PROF_START( basic::HIERARCHICAL_SORT_ADDRESSES );
571  for( core::Size ii = 1; ii <= addresses.size(); ii++ ) {
572  core::Size min_index = 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 ) ) { // jj less than min_index
576  min_index = jj;
577  min_index_addr = addresses[ jj ];
578  }
579  }
580  if( ii != min_index ) {
581  tmp = addresses[ ii ];
582  addresses[ ii ] = min_index_addr;
583  addresses[ min_index ] = tmp;
584  }
585  }
586  PROF_STOP( basic::HIERARCHICAL_SORT_ADDRESSES );
587  }
588 
589  void
591  core::Size pos= addr.find(".",0);
592  core::Size length = addr.length();
593  while( pos < length ) {
594  core::Size newpos = addr.find( ".", pos+1 );
595  result_addr.push_back( atoi(addr.substr( pos+1, newpos - pos - 1).c_str() ) );
596  pos = newpos;
597  }
598  }
599 
600  void
602  std::ostringstream q;
603  for( core::Size ii = 1; ii < addr.size(); ii++ ) {
604  q << addr[ ii ] << ".";
605  }
606  q << addr[ addr.size() ];
607  newtag = "new." + q.str();
608  }
609 
610  bool
611  HierarchicalLevel::less_than( Address& addr1, Address& addr2 ) { //addr1 less than addr2?
612  if(addr1.size() < addr2.size() ) {
613  return true; //probably doesn't have correct format, just put in front
614  }
615  for( core::Size ii = 1; ii <= addr1.size(); ii++ ) {
616  if( addr1[ ii ] != addr2[ ii ] ) { //ignore if numbers are equal
617  if( addr1[ ii ] < addr2[ ii ] ) {
618  return true;
619  } else {
620  return false;
621  }
622  }
623  }
624  return false;
625  }
626 
627 
628  /**
629  //this function not used
630  core::Size
631  HierarchicalLevel::next_free_address( Address & query_address, core::Size level ) {
632  runtime_assert( level != 1 );
633  core::Size next_index = 0;
634  if( level_ != level && has_next_level() ) {
635  next_index = next_level_->next_free_address( query_address, level );
636  }
637  else {
638  runtime_assert( level_ == level );
639  if ( next_free_address_index_ > 0 ) {
640  next_free_address_index_++;
641  next_index = next_free_address_index_;
642  } else {
643  runtime_assert( first_zero_pos( query_address ) == level ); //this level is unresolved
644  Address address = query_address;
645  address[ level_ ] = pool_cache_.size() + 1;
646  for( core::Size ii = level_ + 1; ii <= address.size(); ii++ ) {
647  address[ ii ] = 0; //just to be safe
648  }
649  std::string test_file = lib_full_path( address );
650  while( utility::file::file_exists( test_file ) ) {
651  address[ level_ ] = address[ level_ ] + 1;
652  test_file = lib_full_path( address );
653  }
654  next_free_address_index_ = address[ level_ ];
655  next_index = next_free_address_index_;
656  }
657  }
658  return next_index;
659  }
660  **/
661 
662  void
665  for( core::Size ii =1; ii <= addr.size(); ii++ ) {
666  addr[ ii ] = 0;
667  rms[ ii ] = 0.0;
668  }
669  }
670 
671  core::Size
674  std::string & best_decoy,
675  utility::vector1< core::Real > & best_rmsd,
676  Address & best_indices
677  ) {
678  return evaluate( coords, best_decoy, best_rmsd, best_indices, true, true );//when you evaluate, start from top-level
679  }
680 
681  core::Size
684  std::string & best_decoy,
685  utility::vector1< core::Real > & best_rmsd,
686  Address & best_indices,
687  bool reset_all_levels, //default true,
688  bool load_if_missing_from_cache //default true
689  ) {
690  using namespace basic;
691  PROF_START( basic::HIERARCHICAL_EVALUATE );
692  if( level_ == 1 ) {
693  best_rmsd.resize( max_levels_, 0.0 );
694  best_indices.resize( max_levels_, 0 );
695  if( reset_all_levels ) {
696  reset( best_indices, best_rmsd );
697  best_indices[ 1 ] = 1;
698  }
699  }
700 
701  if( !reset_all_levels && level_ < max_levels_ && best_indices[ level_ + 1 ] != 0 ) {
702  return next_level_->evaluate( coords, best_decoy, best_rmsd, best_indices, reset_all_levels, load_if_missing_from_cache );
703  }
704  std::string current_best_decoy="";
705  std::list<PoolData>::iterator addr_itr = find( best_indices );
706  PoolData matching_pool;
707  Pool_RMSD_OP matching_pool_ptr;
708  bool element_exists_in_cache = true;
709 
710  if( TR.visible() ) TR.Debug << "address at time of evaluation for level " << level_ << " is: "; print_address( best_indices );
711  if( addr_itr == pool_cache_.end() ) { //address not in cache, but exists as file
712  // if( pool_exists( best_indices ) ) { //ek elminated un-necessary file-checks 10/8/2010
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 ) {
716  while ( pool_cache_.size() >= max_cache_size_ ) { //make some room
717  pool_cache_.pop_back();
718  }
719  if( TR.visible() ) {
720  TR.Debug << "EVAL: address "; print_address(best_indices);
721  TR << "loading " << lib_full_path( best_indices ) << " from file" << std::endl;
722  }
723  matching_pool = load_pool( best_indices );
724  pool_cache_.push_front( matching_pool );
725  } else {
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;
727  return 0; //element doesn't exist in cache, and we're not allowed to load from file
728  }
729  //} //ek elminated un-necessary file-checks 10/8/2010
730  /** //ek elminated un-necessary file-checks 10/8/2010
731  else {
732  if( TR.visible() ) TR.Debug << "pool desired from address doesn't exist! exiting eval "; print_address( best_indices );
733  return 0;
734  }
735  **/
736  } else {
737  matching_pool = (*addr_itr);
738  }
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;}
742  pool_cache_.erase( addr_itr ); //take PoolData and put to front
743  pool_cache_.push_front( matching_pool );
744  }
745 
746  //evaluation begins
747  core::Real best_level_rmsd = 0.0;
748  core::Size level_address;
749  runtime_assert( pool_cache_.begin() == find( best_indices ));
750  level_address = ((*pool_cache_.begin()).pool_)->evaluate( coords, best_decoy, best_level_rmsd );
751  round( best_level_rmsd ); //ek 8/3/2010
752 
753  bool outside_known_structures = false;
754  core::Size last_level_address = 0;
755  //tolerance = 0.05;
756  if( has_next_level() ) {
757  if( TR.visible() ) TR.Debug << "going down to next level" << std::endl;
758  if( best_level_rmsd > radius_ ) {
759  // if( best_level_rmsd > radius_ + tolerance ) { // 10/12/10 ek added in tolerance for very close cases
760  // if( best_level_rmsd > radius_ + tolerance ) { // 10/12/10 ek added in tolerance for very close cases
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;
766  } else {
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;
770  }
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 );
774  }
775  } else { //last-level
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;
779  }
780  PROF_STOP( basic::HIERARCHICAL_EVALUATE );
781  return last_level_address;
782  }
783 
784  void
786  PROF_START( basic::HIERARCHICAL_ROUND );
787  //round to nearest 0.01
788  if( TR.visible() ) TR.Debug << "input to round is: " << best_rmsd << " ";
789  core::Real t = best_rmsd * 100;
790  core::Real remainder = t - floor(t);
791  //TR.Debug << "remainder: " << remainder << std::endl;
792  if( remainder >= 0.5 ) {
793  remainder *= 10;
794  remainder = ceil(remainder);
795  remainder /= 10;
796  //TR.Debug << " ceil-remainder: " << remainder << std::endl;
797  } else {
798  remainder *= 10;
799  remainder = floor(remainder);
800  remainder /= 10;
801  //TR.Debug << "floor-remainder: " << remainder << std::endl;
802  }
803 
804  //TR.Debug << "remainder: " << remainder << " floor(t): " << floor(t) << std::endl;
805  best_rmsd = (remainder + floor(t))/100;
806  //hack to cut off last digit when best_rmsd is x.0y such that 2.01 --> 2.0
807  if( (int)(floor( best_rmsd * 10.0 )) % 10 == 0 ) {
808  best_rmsd = (floor(best_rmsd * 10)) / 10;
809  }
810  if( TR.visible() ) TR.Debug << " output of round: " << best_rmsd << std::endl;
811  PROF_STOP( basic::HIERARCHICAL_ROUND );
812  }
813 
814  void
816  TR.Debug << "testing ROUND:\n";
817  for( core::Real t = 0; t <= 10.0; t += 0.0001) {
818  core::Real rounded = t;
819  round(rounded);
820  TR.Debug << t << " " << rounded << std::endl;
821  }
822  TR.Debug << "end testing ROUND\n";
823  exit(1);
824 
825  }
826 
827  core::Size
829  return pool_cache_.size();
830  }
831 
832 
833  core::Size
836  if( level_ != level ) {
837  runtime_assert( level <= max_levels_ );
838  if( has_next_level() ) {
839  level_size = next_level_->level_size( level );
840  }
841  } else {
842  level_size = size();
843  }
844  return level_size;
845  }
846 
847  core::Size
849  PROF_START( basic::HIERARCHICAL_POOL_SIZE );
850  // core::Size first_zero = first_zero_pos( addr );
851  // core::Size pool_size = 0;
852  std::list< PoolData >::iterator itr;
853  if( level_find( addr, level, itr ) ) {
854  if( TR.visible() ) TR.Debug << "pool size from pool_size function is: " << (*itr).pool_->size() << std::endl;
855  return (*itr).pool_->size();
856  }
857  else {
858  return 0;
859  }
860  PROF_STOP( basic::HIERARCHICAL_POOL_SIZE );
861  }
862 
863 
864  core::Size
866  runtime_assert( level_ == 1 );
867  runtime_assert( pool_cache_.size() == 1 );
868  return (*pool_cache_.begin()).pool_->size();
869  }
870 
871  void
873  PROF_START( basic::HIERARCHICAL_ADD_ELEM_TO_CACHE );
874  runtime_assert( find(input_addr) == pool_cache_.end() );
875  PoolData newpooldat = PoolData( new Pool_RMSD(), input_addr );
876  newpooldat.pool_->add( coords, coords.u2(), tag );
877  while( pool_cache_.size() >= max_cache_size_ ) {
878  pool_cache_.pop_back();
879  }
880  pool_cache_.push_front( newpooldat );
881  PROF_STOP( basic::HIERARCHICAL_ADD_ELEM_TO_CACHE );
882  }
883 
885  FArray2D_double& coord,
886  std::string & tag,
887  Address & address){
888  return add_new( coord, tag, address, false );
889  }
890 
891 
893  FArray2D_double& coord,
894  std::string & tag,
895  Address & address,
896  bool resolve_remaining_levels //default is false
897  ) {
898  using namespace basic;
899  PROF_START( basic::HIERARCHICAL_ADD );
900  //what if we're adding to a pool that exists but we haven't loaded yet?
901  //check for existence, load if exists, and then add
902  if( !address_exists_in_cache( address ) && pool_exists( address ) ) {
903  TR.Error << " CANNOT ADD IF ADDRESS DOESN'T EXIST IN CACHE. exiting without adding!" << std::endl;
904  utility_exit();
905  return false;
906  }
907 
908  bool added_level = false;
909  core::Size address_at_level = address[ level_ ];
910  if( ( address_at_level > 0 && find( address ) == pool_cache_.end() ) ||
911  address_at_level == 0 ) {
912  Address new_level_addr = address;
913  for( core::Size ii = ( level_ + 1 ); ii <= new_level_addr.size(); ii++ ) {
914  new_level_addr[ ii ] = 0;
915  }
916  add_elem_to_cache( coord, tag, new_level_addr );
917  added_level = true;
918  }
919  if( has_next_level() ) {
920  if( address[ level_ + 1 ] == 0 ) {
921  std::list<PoolData>::iterator itr;
922  if( level_find( address, level_, itr ) ) {
923  if( !added_level ) {
924  address[ level_ + 1 ] = (*itr).pool_->size() + 1;
925  } else {
926  runtime_assert( (*itr).pool_->size() > 0 );
927  address[ level_ + 1 ] = (*itr).pool_->size(); //to avoid double-counting
928  }
929  } else {
930  address[ level_ + 1 ] = 1;
931  }
932  }
933  bool added_levels_to_child = next_level_->add_new( coord, tag, address, resolve_remaining_levels );
934  if( added_levels_to_child && !added_level ) { //second condition avoids duplicate addition
935  ( *find( address ) ).pool_->add( coord, coord.u2(), tag );
936  }
937  } else {
938  if( address_at_level > 0 && find( address ) != pool_cache_.end() && !added_level ) { //no new levels, adding to lowest pool
939  ( *find( address ) ).pool_->add( coord, coord.u2(), tag );
940  }
941  }
942  PROF_STOP( basic::HIERARCHICAL_ADD );
943  return added_level;
944  }
945 
946 
947  void
949  //if the structure is new in the top-level and not in our branch,
950  // we need to be able to evaluate this structure, but we don't want to clutter our
951  // hierarchy by creating a tree-structure... so we avoid it by only adding to the top-level
952  // if we ever hit this structure later in the trajectory, we'll load the branch from file
953  runtime_assert(level_ == 1 && pool_cache_.size() == 1);
954  (*pool_cache_.begin()).pool_->add( coords, coords.u2(), tag);
955  }
956 
957  void
959  for( std::list< PoolData >::iterator it = pool_cache_.begin();
960  it != pool_cache_.end(); it++ ) {
961  print_address( (*it).address_ );
962  }
963  }
964 
965  void
967  if( TR.visible() ) TR.Debug << "level: " << level_ << " ";
968  for( std::list<PoolData>::iterator itr = pool_cache_.begin(); itr != pool_cache_.end(); itr++ ) {
969  Address addr = (*itr).address_;
970  if( TR.visible() ) {
971  for( core::Size ii = 1; ii <= addr.size(); ii++ ) {
972  TR.Debug << addr[ ii ] << " ";
973  }
974  TR.Debug << " , ";
975  }
976  }
977  if( TR.visible() ) TR.Debug << std::endl;
978  if( has_next_level() ) {
979  next_level_->debug_print_addresses();
980  }
981  }
982 
983  void
985  // runtime_assert( level_ == 1 );
986  if( TR.visible() ) { TR.Debug << "level: " << level_ << " size of level: " << size() << std::endl; }
987  for( std::list< PoolData >::iterator itr = pool_cache_.begin();
988  itr != pool_cache_.end(); itr++ ) {
989  Pool_RMSD_OP poolop = (*itr).pool_;
990  if( TR.visible() ) {
991  TR.Debug << "pool at address: "; print_address( (*itr).address_ );
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;
995  }
996  TR.Debug << "end pool at this level" << std::endl;
997  }
998  }
999  if( has_next_level() ) {
1000  next_level_->debug_print_hierarchy();
1001  }
1002  }
1003 
1004  void
1006  if( TR.visible() ) TR.Debug << "size per level: " << level_ << " " << this->size() << " ";
1007  for( std::list< PoolData >::iterator itr = pool_cache_.begin();
1008  itr != pool_cache_.end(); itr++ ) {
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 ] << " ";
1013  }
1014  TR.Debug << ", size: " << (*itr).pool_->size() << " | ";
1015  TR.Debug << std::endl;
1016  }
1017  }
1018  if( has_next_level() ) {
1019  next_level_->debug_print_size_per_level();
1020  }
1021 
1022  }
1023 
1024  bool
1026  bool has_address = (find(address) != pool_cache_.end()) || ( address[ level_ ] == 0 );
1027  if( this->has_next_level() && next_level_->level() <= address.size() && address[ level_ + 1 ] != 0 ) {
1028  //TR.Debug << "going one level down from " << level_ << " to " << next_level_->level() << std::endl;
1029  has_address = has_address && next_level_->address_exists_in_cache( address );
1030  }
1031  //TR.Debug << "address exists in cache: " << has_address << ": "; print_address(address);
1032  return has_address;
1033 
1034  }
1035 
1036  void
1038  if( level_ == 1 ) {
1039  sort_pool( top_level_pool );
1040  (*pool_cache_.begin()).pool_ = top_level_pool;
1041  }
1042  }
1043 
1044  //
1045  PoolData
1047  PROF_START( basic::LOAD_HIERARCHY );
1048  std::string file = lib_full_path(address);
1049  /**
1050  utility::io::izstream testin( file.c_str() );
1051  TR.Debug << "stream is " << (testin.good() ? "good" : "bad" ) << std::endl;
1052  while( !testin.good() ) {
1053  TR.Debug << "stream is " << (testin.good() ? "good" : "bad" ) << std::endl;
1054  testin.clear();
1055  testin.close();
1056  sleep( 5 );
1057  testin.open( file.c_str() );
1058  }
1059  **/
1060  Pool_RMSD_OP pool_ptr = new Pool_RMSD(file);
1061  core::Size ntries = 5;
1062  while( pool_ptr->size() == 0 && ntries > 0 ) { //we never try to open empty files
1063 #ifdef _WIN32
1064  #ifndef WIN32
1065  Sleep(5000); // REQUIRED FOR WINDOWS
1066  #endif
1067 #else
1068  sleep(5);
1069 #endif
1070  pool_ptr = new Pool_RMSD( file );
1071  ntries--;
1072  }
1073  runtime_assert( pool_ptr->size() > 0 );
1074  /**
1075  if( pool_ptr->size() == 0 ) {
1076  //runtime_assert( utility::file::file_exists( file ) );
1077  while( pool_ptr->size() == 0 ) {
1078  sleep( 5 );
1079  pool_ptr = new Pool_RMSD( file );
1080  }
1081  }
1082  **/
1083  sort_pool( pool_ptr );
1084  PROF_STOP( basic::LOAD_HIERARCHY );
1085  return PoolData( pool_ptr, address );
1086  }
1087 
1088  bool
1090  using namespace basic::options;
1091  using namespace basic::options::OptionKeys;
1092  std::string filename = lib_full_path( address );
1093  return utility::file::file_exists( filename ); //ek old way... replaced 10/8/2010
1094  /**
1095  utility::io::izstream testin( filename.c_str() );
1096  TR.Debug << "testing stream. stream is " << ( testin.good() ? "good" : "bad") << std::endl;
1097  core::Size ntries = 3;
1098  while( !testin.good() && ntries > 0 ) {
1099  sleep( 5 );
1100  ntries--;
1101  }
1102  if( !testin.good() ) {
1103  std::cerr << "expected file: " << filename << " was not found in file-system.. fatal error!" << std::endl;
1104  TR.Debug << "expected file: " << filename << " was not found in file-system... fatal error!" << std::endl;
1105  utility_exit();
1106  }
1107  **/
1108 
1109  }
1110 
1111 void
1113  pool_cache_.clear();
1114 }
1115 
1118  core::Size count = 0;
1119  std::list< PoolData >::iterator itr = pool_cache_.begin();
1120  while( count < index ) {
1121  itr++;
1122  }
1123  return (*itr).address_;
1124 }
1125 
1126 
1127 //for debugging
1128 void
1130  for( core::Size ii = 1; ii <= address.size(); ii++ ) {
1131  TR.Debug << address[ ii ] << " ";
1132  }
1133  TR.Debug << std::endl;
1134 }
1135 
1136 //get desired lib file name from tag
1138 
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;
1144  //TR.Debug << "getting lib_full_path of "; print_address( address );
1145  runtime_assert(address[ 1 ] > 0 ); //top-level must have something in it
1146 
1147  std::string subdir_prefix("sub_");
1148  std::string libdir_prefix("c_");
1149  std::string libdir_suffix("_lib");
1150  std::string rootpath_suffix("_dir");
1151  std::string s("/");
1152  int nofsubdir = option[cluster::K_n_sub];
1153  std::string rootpath = utility::file::FileName(option[mc::hierarchical_pool]()).path();
1154  std::string defaultpath = utility::file::FileName(option[mc::hierarchical_pool]()).base() + rootpath_suffix + s;
1155 
1156  //Size n = address.size();
1157 
1158 
1159  std::ostringstream fnstream;
1160  //fnstream << "c_" << setfill ('0') << setw (5) << address[n-1] << ".out";
1161 
1162  core::Size last_num_not_zero;
1163  if( address[ 1 ] == 0 ){
1164  last_num_not_zero = 1;
1165  }else {
1166  for( last_num_not_zero = 1; last_num_not_zero < address.size(); last_num_not_zero++ ) { //last number is not a level address
1167  if( address[ last_num_not_zero + 1 ] == 0 ) {
1168  break;
1169  }
1170  }
1171  }
1172  runtime_assert( last_num_not_zero > 0 ); //expect no elements to be sdasdzero
1173 
1174  fnstream << "c_" << setfill ('0') << setw (5) << address[last_num_not_zero] << ".out";
1175  std::string fn(fnstream.str());
1176  //TR.Debug << "silent file we're lookin for: " << fnstream.str() << std::endl;
1177  for (Size i=last_num_not_zero; i >= 1; i--)
1178  {
1179  ostringstream pathstream1;
1180  ostringstream pathstream2;
1181 
1182  //main dir
1183  if (i>1) pathstream1 << libdir_prefix << setfill ('0') << setw (5) << address[i-1] << libdir_suffix << s ;
1184  //sub dir
1185  pathstream2 << subdir_prefix << setfill ('0') << setw (3) << int((address[i]-1)/nofsubdir) << s;
1186  fn = pathstream1.str()+pathstream2.str()+fn;
1187  //TR.Debug << "fn is now " << fn << std::endl;
1188  }
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 ] << " ";
1193  }
1194  TR.Debug << " got file-name: " << defaultpath+fn;
1195  }
1196  PROF_STOP( basic::LIB_FULL_PATH );
1197  return defaultpath+fn;
1198 
1199 }
1200 
1201  /**
1202  std::string HierarchicalLevel::lib_full_path(std::string tag_origin)
1203 {
1204  using namespace std;
1205  using namespace core;
1206  using namespace basic::options;
1207  using namespace basic::options::OptionKeys;
1208 
1209  std::string subdir_prefix("sub_");
1210  std::string libdir_prefix("c_");
1211  std::string libdir_suffix("_lib");
1212  std::string s("/");
1213  //int nofsubdir = option[cluster::K_n_sub];
1214  std::string rootpath = utility::file::FileName(option[mc::known_structures]()).path();
1215  std::string defaultpath = utility::file::FileName(option[mc::known_structures]()).base() + libdir_suffix + s;
1216 
1217  std::string tag = tag_origin + ".0000";
1218 
1219  Size pos=1;
1220  Size len=tag.length();
1221  utility::vector1<Size> address;
1222  while (pos<len)
1223  {
1224  Size newpos = tag.find(".", pos+1);
1225  address.push_back(atoi(tag.substr(pos+1,newpos-pos-1).c_str()));
1226  pos = newpos;
1227  }
1228  return lib_full_path( address );
1229 }
1230  **/
1231 
1232 
1233 }
1234 }
1235 }