StepWiseSampleAndScreen
carries out the main loop for stepwise sampling, either in enumerative mode or in stochastic mode. Look in src/protocols/stepwise/modeler/StepWiseConnectionSampler
for example setup.
StepWiseSampleAndScreen
is initialized with two things:
• a StepWiseSampler
objects which delineates the degrees of freedom to be sampled, their discrete values, and what order these go in. There are some tricks here to handle rigid body sampling. This StepWiseSampler
object is typically itself the composition of several StepWiseSampler
objects.
• a vector of StepWiseScreener
objects which delineate the gauntlet of filters, packers, and loop closers that are run after each sample is applied to the pose. Having these screeners in a particular order can accelerate sampling, and in a few cases there are some dependencies (e.g. a pose selection screener should go last, after side-chain packers, and after any loop closers pinpoint the backbone).
The architectures of each of these objects are described in the StepWiseSampler and StepWiseScreener pages.
Not checked yet
StepWiseSamplerBaseOP sampler = new StepWiseSampler;
// initialize -- see link to documentation for StepWiseSampler...
sampler->set_random( true );
utility::vector1< screener::StepWiseScreenerOP > screeners_;
// initialize -- see link to documentation for StepWiseScreener...
clusterer_ = new align::StepWiseClusterer( options_ );
screeners_.push_back( new PoseSelectionScreener( pose, scorefxn_, clusterer_ ) );
StepWiseSampleAndScreen sample_and_screen( sampler, screeners );
sample_and_screen.set_verbose( true );
sample_and_screen.set_max_ntries( 100 ); // if sampler is in random mode
sample_and_screen.set_num_random_samples( 5 ); // find 5 poses
sample_and_screen.run();
pose_list_ = clusterer_->pose_list(); // list of up to 5 poses in the last screener.
Basically this object replaces the massive loops within loops within loops that originally plagued the stepwise
code. We replaced it because:
• With the old nested loops:
The StepWiseSampleAndScreen mostly solves these issues.
• Another good feature of the StepWiseSampleAndScreen framework: it only saves poses into memory when they've passed all the screens. That allows it to handle sampling calculations that literally enumerate through tens of millions of samples. Alternatives that we considered, where we passed lists of Poses serially through different samplers, led to memory explosions.
The way these objects works is best seen in the code itself, which is really short, actually:
for ( sampler_->reset(); sampler_->not_end(); ++( *sampler_ ) ) {
if ( sampler_->random() && ( num_tries() >= max_ntries_ || num_successes() >= num_random_samples_ ) ) break;
update_movers->clear();
restore_movers->clear();
set_ok_to_increment();
for ( n = 1; n <= num_screeners(); n++ ){
StepWiseScreenerOP screener = screeners_[ n ];
screener->get_update( sampler_ );
if ( n > 1 ) screener->apply_mover( update_movers, 1, n - 1 ); //info from previous screeners.
if ( screener->check_screen() ){
screener->increment_count();
screener->add_mover( update_movers, restore_movers );
early_exit_check( n ); // for debugging.
} else {
screener->fast_forward( sampler_ ); break;
}
} // check screens
Size const last_passed_screener = n - 1;
for ( Size m = 2; m <= last_passed_screener; m++ ) screeners_[ m ]->apply_mover( restore_movers, m - 1, 1 );
} // sampler
• Note that this StepWiseSampleAndScreen
does not take a pose
! Instead the various poses at play are encoded in the StepWiseScreener
objects, which hold the actual pose that is displayed in graphics, copies of the pose, a collection of poses (e.g. for the final clustering step), or no pose at all (e.g., in rigid body docking some Screeners just manipulate Stubs for speed).
• As promised, the main loop involves traversing through the StepWiseSampler
in sampler
.
• Stochastic sampling involves setting choose_random()
to true. In this case the sampling proceeds until num_random_samples
poses are found.
• Enumerative sampling involves setting choose_random()
to galse. In this case the sampling proceeds until the sampler_
is exhausted, i.e., when sampler_->not_end()
returns false
. There is a way to stop early for integration tests (a type of StepWiseScreener
called IntegrationTestBreaker
, equivalent to a break
in a loop).
• At the heart of the loop through the screeners_
gauntlet, is the check_screen()
. If pass, we increment that screener's counter. This allows the output of a final 'cut table' at the end of the StepWiseSampleAndScreen
via output_counts()
. If we do not pass the check, the screener may hold instructions on how to fast-forward
through the sampler loop. The latter action is equivalent to a continue
in a loop.
• The update_movers
objects store information that can be passed from one StepWiseScreener
to later ones. For example, if early on, there is a ProteinCCD_ClosureScreener, it solves for backbone torsions that close a loop within its own private pose, and then encodes the application of those torsions into a Mover (see screener->add_mover
line). That mover is passed to later screeners (e.g., packers) holding their own private copies of the pose with potentially different variants or sequences -- they apply the closure solution and then do their thing. That's the line if ( n > 1 ) screener->apply_mover( update_movers, 1, n - 1 );
.
• The restore_movers
list is supposed to store the exact opposite of each update_mover
. That's the line at the end of the loop for ( Size m = 2; m <= last_passed_screener; m++ ) screeners_[ m ]->apply_mover( restore_movers, m - 1, 1 );
. The restore_mover
is not put in yet for some StepWiseScreener
objects to match some historical choices during code development, but will be implemented soon -- its conceptually the right way to go.
• The set_ok_to_increment()
function is a kind of hack that makes these StepWiseScreener
counters for inner loops bypass incrementing for certain RNA ribose sampling. (May deprecate soon -- working on a more intuitive way to handle these sampling steps).
• Debugging what is happening in StepWiseSampleAndScreener can require digging into the screeners and finding their internal state and/or poses; an example of this is in early_exit_check
. This code block is currently bypassed through an early return
but was left in as an example of how to dig into the main loop.
Go back to StepWise Overview.