23 #include <basic/options/option.hh>
24 #include <basic/options/keys/OptionKeys.hh>
25 #include <basic/options/keys/in.OptionKeys.gen.hh>
26 #include <numeric/util.hh>
27 #include <numeric/xyzVector.hh>
28 #include <numeric/random/DistributionSampler.hh>
29 #include <ObjexxFCL/FArray1D.hh>
30 #include <ObjexxFCL/FArray2D.hh>
31 #include <utility/vector1.hh>
55 #include <basic/Tracer.hh>
60 static basic::Tracer
TR(
"protocols.hybridization.HybridizeFoldtreeDynamic" );
61 static numeric::random::RandomGenerator
RG(65433);
64 namespace hybridization {
84 cut_options[ires] =
false;
94 if (loop_start >= loop_end) {
99 bool cut_found =
false;
100 for (
core::Size i_cut_old = 1; i_cut_old <= cuts_orig.size(); ++i_cut_old) {
101 if (cuts_orig[i_cut_old] >= loop_start && cuts_orig[i_cut_old] <= loop_end) {
102 cut = cuts_orig[i_cut_old];
103 TR.Debug <<
"Respect the input cut position: " << cut << std::endl;
109 if ( cut_point_decision ==
"middle") {
110 cut = (loop_start + loop_end ) /2;
112 else if ( cut_point_decision ==
"middle_L" ) {
113 cut = (loop_start + loop_end ) /2;
116 for (
core::Size ic = cut-1; ic>=loop_start;--ic) {
118 candidates.push_back(ic);
122 for (
core::Size ic = cut+1; ic<=loop_end;++ic) {
124 candidates.push_back(ic);
128 if (candidates.size())
129 cut = candidates[
RG.random_range(1,candidates.size())];
132 else if ( cut_point_decision ==
"combine" ) {
134 for (
core::Size ires = loop_start; ires <= loop_end; ++ires) {
135 if (cut_options[ires]) {
136 cut_residues.push_back(ires);
139 if (cut_residues.size() > 0) {
140 using boost::math::normal;
142 using numeric::random::DistributionSampler;
144 double mu = cut_residues.size() / 2.0;
145 double sigma = cut_residues.size() / 5.0;
146 normal distribution(mu, sigma);
147 DistributionSampler<normal> sampler(distribution);
150 Size position =
static_cast<Size>(sampler.sample());
151 position = numeric::clamp<core::Size>(position, 1, cut_residues.size());;
153 cut = cut_residues[position];
156 cut = (loop_start + loop_end ) /2;
160 utility_exit_with_message(
"do not know how to make cut points");
164 cut_positions.push_back(cut);
165 TR <<
"Cutpoint " << i <<
" at " << cut << std::endl;
168 for (
core::Size ic = loop_start; ic<=loop_end;++ic) {
170 jnk += (ic == cut) ?
"*" :
"-";
173 TR <<
" " << jnk << std::endl;
175 return cut_positions;
186 for (
core::Size i=1; i<=chunks_.num_loop(); ++i) {
188 chunks_[i].set_start(1);
190 core::Size new_start = cut_positions[i-1] + 1;
191 chunks_[i].set_start( new_start );
194 if (i==chunks_.num_loop()) {
195 chunks_[i].set_stop(n_residues);
198 chunks_[i].set_stop( new_stop );
213 using boost::math::normal;
215 using numeric::random::DistributionSampler;
218 double sigma = chunk.
length() / 5.0;
219 normal distribution(mu, sigma);
220 DistributionSampler<normal> sampler(distribution);
223 Size position =
static_cast<Size>(sampler.sample());
224 return numeric::clamp<core::Size>(position, chunk.
start(), chunk.
stop());
231 utility::vector1< std::pair< core::Size, core::Size > >
const & strand_pairs,
232 std::set<core::Size>
const & strand_pair_library_positions
257 std::set<core::Size>::iterator set_iter;
259 bool pair_chunk =
false;
261 if (core_chunks[i].
start() <= *set_iter && core_chunks[i].stop() >= *set_iter) {
267 TR <<
"Identified template core chunk with index: " << i << std::endl;
268 TR << core_chunks[i] << std::endl;
277 dynamic_cast<core::conformation::symmetry::SymmetricConformation &> ( pose.
conformation()) );
322 if (idx) pair_chunks_pairs_tmp.push_back(std::pair<core::Size, core::Size>(
strand_pairs_[i].first,
strand_pairs_[i].second ));
325 if (idx) pair_chunks_pairs_tmp.push_back(std::pair<core::Size, core::Size>(
strand_pairs_[i].second,
strand_pairs_[i].first ));
327 if (idx) pair_chunks_tmp.push_back(idx);
329 assert( pair_chunks_tmp.size() == pair_chunks_pairs_tmp.size() );
330 pair_chunks = pair_chunks_tmp;
331 pair_chunks_pairs = pair_chunks_pairs_tmp;
363 jumps.push_back( std::pair<core::Size,core::Size>( down, up ) );
398 for (
Size i = 1; i <= jumps_old.size(); ++i) {
403 jumps.push_back(std::make_pair(jump_root, jumps_old[i].first));
404 TR.Debug <<
"Adding additional jump: " << jump_root << jumps_old[i].first << std::endl;
406 else if ( jumps_old[i].second > last_chunk_residue && jumps_old[i].second <=
num_nonvirt_residues_) {
407 jumps.push_back(std::make_pair(jump_root, jumps_old[i].second));
408 TR.Debug <<
"Adding additional jump: " << jump_root << jumps_old[i].second << std::endl;
411 for (
Size i = 1; i <= cuts_old.size(); ++i) {
413 cuts.push_back(cuts_old[i]);
414 TR.Debug <<
"Adding additional cut: " << cuts_old[i] << std::endl;
428 if (!root_chunk_indices.size()) {
429 TR <<
"Template core chunks do not exist so using first chunk" << std::endl;
430 root_chunk_indices.insert(1);
432 std::set<core::Size>::iterator set_iter;
441 TR.Debug <<
"Adding chunk cut: " << cut_point << std::endl;
442 cuts.push_back(cut_point);
444 if (root_chunk_indices.count(i)) {
446 TR.Debug <<
"Adding root jump: " << j_root <<
" " << jump_point << std::endl;
447 jumps.push_back(std::make_pair(j_root, jump_point));
455 std::set<core::Size> rooted_chunk_indices;
466 std::set<core::Size> floating_pair_chunks;
472 assert( i_index && j_index );
475 floating_pair_chunks.insert(i_index);
479 floating_pair_chunks.insert(j_index);
482 assert( paircnt == 0 || paircnt == 2 );
490 if (floating_pair_chunks.count(up_index) && !rooted_chunk_indices.count(up_index)) {
492 TR <<
"Removing root cut: " <<
chunks_[*set_iter].stop() << std::endl;
494 TR.Debug <<
"Adding floating pair chunk cut: " <<
chunks_[up_index].stop() << std::endl;
496 rooted_chunk_indices.insert(up_index);
502 if (floating_pair_chunks.count(down_index) && !rooted_chunk_indices.count(down_index)) {
503 rooted_chunk_indices.insert(down_index);
510 for (set_iter = rooted_chunk_indices.begin(); set_iter != rooted_chunk_indices.end(); ++set_iter)
511 floating_pair_chunks.erase(*set_iter);
515 while (floating_pair_chunks.size()) {
516 for (set_iter = rooted_chunk_indices.begin(); set_iter != rooted_chunk_indices.end(); ++set_iter) {
519 if (floating_pair_chunks.count(up_index) && !rooted_chunk_indices.count(up_index)) {
521 TR <<
"Removing root cut: " <<
chunks_[*set_iter].stop() << std::endl;
523 TR.Debug <<
"Adding floating pair chunk cut: " <<
chunks_[up_index].stop() << std::endl;
525 rooted_chunk_indices.insert(up_index);
531 if (floating_pair_chunks.count(down_index) && !rooted_chunk_indices.count(down_index)) {
532 rooted_chunk_indices.insert(down_index);
538 for (set_iter = rooted_chunk_indices.begin(); set_iter != rooted_chunk_indices.end(); ++set_iter)
539 floating_pair_chunks.erase(*set_iter);
553 TR.Debug <<
"jump size: " << jumps.size() <<
" cut size: " << cuts.size() << std::endl;
555 ObjexxFCL::FArray2D_int ft_jumps(2, jumps.size());
556 for (
Size i = 1; i <= jumps.size(); ++i) {
557 TR.Debug <<
"jump " << i <<
" " << jumps[i].first <<
" " << jumps[i].second << std::endl;
558 ft_jumps(1, i) = std::min(jumps[i].first, jumps[i].second);
559 ft_jumps(2, i) = std::max(jumps[i].first, jumps[i].second);
562 ObjexxFCL::FArray1D_int ft_cuts(cuts.size());
563 for (
Size i = 1; i <= cuts.size(); ++i) {
564 TR.Debug <<
"cut " << i <<
" " << cuts[i] << std::endl;
565 ft_cuts(i) = cuts[i];
580 TR <<
"tree_from_jumps_and_cuts: " << tree << std::endl;
582 bool join_edges =
true;
583 bool updated =
false;
590 if (it_next != it_end) {
592 it->stop() == it_next->start() ) {
599 tmp_tree.
add_edge( it->start(), it->stop(), it->label() );
601 tmp_tree.
add_edge( it->start(), it->stop(), it->label() );
606 if (updated)
TR <<
"joined adjacent peptide edges: " << tree << std::endl;
611 if (it->start() == (
int)jump_root) jump_points.push_back(it->stop());
613 for (
core::Size i=1;i<=jump_points.size();++i) {
614 std::set< std::pair< core::Size, core::Size > >
remove;
618 std::set< std::pair< core::Size, core::Size > > remove_tmp;
622 remove_tmp.insert(std::pair< core::Size, core::Size >( start, stop ));
626 remove_tmp.insert(std::pair< core::Size, core::Size >( jt->start(), jt->stop() ));
629 tmp_tree.
add_edge( start, stop, it->label() );
630 if (remove_tmp.size() > 1)
remove.
insert(remove_tmp.begin(),remove_tmp.end());
632 tmp_tree.
add_edge( it->start(), it->stop(), it->label() );
638 if (!
remove.count(std::pair< core::Size, core::Size >( it->start(), it->stop() ))) {
639 new_tree.
add_edge( it->start(), it->stop(), it->label() );
645 if (updated)
TR <<
"joined continuous rooted peptide edges: " << tree << std::endl;
650 utility_exit_with_message(
"HybridizeFoldtreeDynamic: failed to build fold tree from cuts and jumps");
663 std::set<core::Size> & rooted_chunk_indices
670 if ( pair_chunks.size() ) {
674 while (start_pair_chunks.size()) {
677 for (
core::Size i=1;i<=start_pair_chunks.size();++i) {
681 assert( this_pair_chunks.size() == this_pair_chunks_pairs.size() );
682 for (
core::Size j=1;j<=this_pair_chunks.size();++j) {
687 if (!rooted_chunk_indices.count(this_pair_chunks[j])) {
689 TR <<
"Adding strand pair root " << index <<
" tree jump: " << this_pair_chunks_pairs[j].first <<
" " << this_pair_chunks_pairs[j].second << std::endl;
690 jumps.push_back(this_pair_chunks_pairs[j]);
691 TR <<
"Adding strand pair root " << index <<
" tree cut: " <<
chunks_[this_pair_chunks[j]].stop() << std::endl;
692 cuts.push_back(
chunks_[this_pair_chunks[j]].
stop());
693 rooted_chunk_indices.insert(this_pair_chunks[j]);
697 if ( new_pair_chunks.size() ) {
704 start_pair_chunks = start_pair_chunks_tmp;
705 start_pair_chunks_pairs = start_pair_chunks_pairs_tmp;
712 if (cuts[i] != cut) cuts_tmp.push_back(cuts[i]);