22 #include <utility/tag/Tag.hh>
29 #include <basic/options/option.hh>
30 #include <basic/options/keys/in.OptionKeys.gen.hh>
35 #include <ObjexxFCL/FArray1D.hh>
37 #include <numeric/random/random.hh>
38 #include <numeric/xyzVector.hh>
39 #include <numeric/xyzMatrix.hh>
40 #include <numeric/xyz.functions.hh>
41 #include <numeric/model_quality/rms.hh>
43 #include <utility/string_util.hh>
44 #include <utility/vector0.hh>
45 #include <utility/vector1.hh>
46 #include <basic/Tracer.hh>
54 namespace simple_filters {
57 static basic::Tracer
TR(
"protocols.simple_filters.SymmetricMotifFilter" );
69 if ( R.xx() > R.yy() && R.xx() > R.zz() ) {
70 S = sqrt( 1.0 + R.xx() - R.yy() - R.zz() ) * 2;
72 Q.
y = (R.xy() + R.yx() ) / S;
73 Q.
z = (R.zx() + R.xz() ) / S;
74 Q.
w = (R.zy() - R.yz() ) / S;
75 }
else if ( R.yy() > R.zz() ) {
76 S = sqrt( 1.0 + R.yy() - R.xx() - R.zz() ) * 2;
77 Q.
x = (R.yx() + R.xy() ) / S;
79 Q.
z = (R.zy() + R.yz() ) / S;
80 Q.
w = (R.xz() - R.zx() ) / S;
82 S = sqrt( 1.0 + R.zz() - R.xx() - R.yy() ) * 2;
83 Q.
x = (R.xz() + R.zx() ) / S;
84 Q.
y = (R.zy() + R.yz() ) / S;
86 Q.
w = (R.yx() - R.xy()) / S;
95 R.xx(1-2*(yy+zz)); R.xy( 2*(xy-zw)); R.xz( 2*(xz+yw));
96 R.yx( 2*(xy+zw)); R.yy(1-2*(xx+zz)); R.yz( 2*(yz-xw));
97 R.zx( 2*(xz-yw)); R.zy( 2*(yz+xw)); R.zz(1-2*(xx+yy));
105 core::Size motiflen = std::min( chainA.size(), chainB.size() );
106 ObjexxFCL::FArray2D< core::Real > final_coords( 3, motiflen );
107 ObjexxFCL::FArray2D< core::Real > init_coords( 3, motiflen );
108 ObjexxFCL::FArray1D< numeric::Real > ww( motiflen, 1.0 );
109 ObjexxFCL::FArray2D< numeric::Real > uu( 3, 3, 0.0 );
113 for (
int j=1; j<=(
int)motiflen; ++j) {
114 for (
int k=0; k<3; ++k) {
115 init_coords(k+1,j) = chainA[j][k];
116 final_coords(k+1,j) = chainB[j][k];
123 for (
int j=1; j<=(
int)motiflen; ++j) {
124 for (
int k=0; k<3; ++k) {
125 init_coords(k+1,j) -= preT[k];
126 final_coords(k+1,j) -= postT[k];
131 numeric::model_quality::findUU( final_coords, init_coords, ww, motiflen, uu, ctx );
132 numeric::model_quality::calc_rms_fast( rms, final_coords, init_coords, ww, motiflen, ctx );
134 R.xx( uu(1,1) ); R.xy( uu(2,1) ); R.xz( uu(3,1) );
135 R.yx( uu(1,2) ); R.yy( uu(2,2) ); R.yz( uu(3,2) );
136 R.zx( uu(1,3) ); R.zy( uu(2,3) ); R.zz( uu(3,3) );
144 protocols::filters::
Filter(
"SymmetricMotif" )
150 : protocols::filters::
Filter(
"SymmetricMotif" ), symm_type_(symm_type_in)
182 bool found_motif =
compute( pose, bestscore, hitLocation );
184 TR.Debug <<
"Motif hit at " << hitLocation << std::endl;
186 return( found_motif );
198 bool found_motif =
compute( pose, bestscore, hitLocation );
200 TR <<
"Motif hit at " << hitLocation << std::endl;
202 TR <<
"No motif hits found." << std::endl;
221 return compute_d2( pose, best_score, motifhit );
230 using numeric::constants::d::pi;
237 bool foundOne =
false;
247 dynamic_cast<core::conformation::symmetry::SymmetricConformation const &> ( pose.
conformation()) );
249 nres = symm_info->num_independent_residues();
251 for (
Size i=1; i<=nres; ++i) {
268 for (
int i=1; i<=2; ++i) {
278 motif_hits_i[1].push_back( -1 );
282 for (
Size j=2; j<=motif_cuts_i.size(); ++j) {
283 prev_Is = motif_hits_i;
284 motif_hits_i.clear();
287 for (
Size k=1; k<=prev_Is.size(); ++k) {
292 for (
Size j_prev = 2; j_prev<j; ++j_prev) {
294 core::Size seglen_x = motif_cuts_i[j_prev] - motif_cuts_i[j_prev-1] - 1;
295 for (
Size l=segstart_x; l<=segstart_x+seglen_x; ++l) {
296 prevCAs.push_back( cas_pose[4*l-3] );
297 prevCAs.push_back( cas_pose[4*l-2] );
298 prevCAs.push_back( cas_pose[4*l-1] );
299 prevCAs.push_back( cas_pose[4*l] );
305 int lstart=1, lstop=nres_prot;
310 for (
int l=lstart; l<=lstop; ++l) {
312 core::Size seglen_l = motif_cuts_i[j] - motif_cuts_i[j-1] - 1;
314 if (segstart_l+seglen_l > nres_prot)
continue;
315 for (
Size m=segstart_l; m<=segstart_l+seglen_l && !
overlap; ++m) {
318 if (overlap)
continue;
321 for (
Size m=segstart_l; m<=segstart_l+seglen_l; ++m) {
322 ca_chunk_pose.push_back( cas_pose[4*m-3] );
323 ca_chunk_pose.push_back( cas_pose[4*m-2] );
324 ca_chunk_pose.push_back( cas_pose[4*m-1] );
325 ca_chunk_pose.push_back( cas_pose[4*m ] );
337 if (j != 2) newI = prev_Is[k];
339 motif_hits_i.push_back( newI );
341 TR.Debug <<
"Motif " << i <<
" hit at ";
342 for (
Size z=1; z<=newI.size(); ++z)
TR.Debug << newI[z] <<
" ";
343 TR.Debug <<
" rms = " << rms << std::endl;
345 if (j == motif_cuts_i.size()) {
347 motif_rms_i.push_back( rms );
348 preTs_i.push_back( preT );
349 postTs_i.push_back( postT );
358 for (
Size i=1; i<=motif_hits1.size(); ++i) {
359 for (
Size j=1; j<=motif_hits2.size(); ++j) {
362 for (
Size x=1; x<=motif_hits1[i].size(); ++x) {
365 for (
Size k=segstart_x; k<=segstart_x+seglen_x; ++k)
369 for (
Size x=1; x<=motif_hits2[j].size() && !
overlap; ++x) {
372 for (
Size k=segstart_x; k<=segstart_x+seglen_x && !
overlap; ++k) {
376 if (overlap)
continue;
382 core::Real angle12 = angle_of( x1, x2 ) * 180/pi;
384 TR.Debug <<
"Hit " << i <<
"," << j <<
": angle = " << angle_i << std::endl;
414 TR.Debug <<
"Hit " << i <<
"," << j <<
": trans = " << trans_i << std::endl;
417 core::Real rms_i = std::max( motif_rms1[i], motif_rms2[j] );
432 bool clashcheck =
false;
435 for (
Size x=1; x<=nres_prot && !clashcheck; ++x) {
436 for (
Size y=1; y<=nres_prot && !clashcheck; ++y) {
439 if (x_x.distance_squared(x_y) < CUTOFF2) {
445 for (
Size x=1; x<=cas_pose.size() && !clashcheck; ++x) {
446 for (
Size y=1; y<=cas_pose.size() && !clashcheck; ++y) {
449 if (x_x.distance_squared(x_y) < CUTOFF2) {
457 TR.Debug <<
"Hit " << i <<
"," << j <<
": clash > " <<
clash_thresh_ << std::endl;
464 if (score_i < best_score) {
466 std::ostringstream oss;
468 for (
Size k=1; k<=motif_hits1[i].size(); ++k) oss << motif_hits1[i][k] <<
" ";
470 for (
Size k=1; k<=motif_hits2[j].size(); ++k) oss << motif_hits2[j][k] <<
" ";
472 motifhit = oss.str();
473 best_score = score_i;
488 using numeric::constants::d::pi;
498 for (
Size i=1; i<=nmotifs; ++i) {
501 for (
Size j=1; j<=motif_i->total_residue(); ++j) {
502 if (motif_i->pdb_info()->chain(j) ==
'A') {
503 cas_chainA[i].push_back( motif_i->residue(j).atom(
" CA ").xyz() );
504 cas_chainA[i].push_back( motif_i->residue(j).atom(
" C ").xyz() );
505 cas_chainA[i].push_back( motif_i->residue(j).atom(
" N ").xyz() );
506 cas_chainA[i].push_back( motif_i->residue(j).atom(
" O ").xyz() );
508 if (j>1 && (motif_i->pdb_info()->number(j) != motif_i->pdb_info()->number(j-1)+1) ) {
510 TR.Debug << i <<
": add cut " << j-1 << std::endl;
513 cas_chainB[i].push_back( motif_i->residue(j).atom(
" CA ").xyz() );
514 cas_chainB[i].push_back( motif_i->residue(j).atom(
" C ").xyz() );
515 cas_chainB[i].push_back( motif_i->residue(j).atom(
" N ").xyz() );
516 cas_chainB[i].push_back( motif_i->residue(j).atom(
" O ").xyz() );
530 for (
Size i=1; i<=nmotifs; ++i) {
540 if (residual < 1e-6) {
541 utility_exit_with_message(
"Chains related by transformation only!" );
545 TR <<
"RMS = " << rms << std::endl;
546 utility_exit_with_message(
"Interchain RMS > 1 ... aborting" );
552 if (
Qs[i].w < 0) {
Qs[i].w = -
Qs[i].w; Wmult = -1; }
558 Qs[i].x *= newS;
Qs[i].y *= newS;
Qs[i].z *= newS;
571 TR <<
"nmotifs = " << nmotifs << std::endl;
572 utility_exit_with_message(
"Symmetry group D2: 2 motifs expected!" );
576 utility_exit_with_message(
"Symmetry group D2: 2 homodimeric motifs expected!" );
579 utility_exit_with_message(
"Symmetry type unknown!" );
595 for (
Size i=1; i<=motif_files.size(); ++i) {
601 TR <<
"Read " << nmotifs <<
" motifs" << std::endl;
605 if (tag->hasOption(
"angle_thresh"))
607 if (tag->hasOption(
"trans_thresh"))
609 if (tag->hasOption(
"rmsd_thresh"))
611 if (tag->hasOption(
"clash_thresh"))
613 if (tag->hasOption(
"angle_wt"))
615 if (tag->hasOption(
"trans_wt"))
617 if (tag->hasOption(
"rmsd_wt"))
619 if (tag->hasOption(
"clash_wt"))
622 if (tag->hasOption(
"force_pos")) {
624 for (
Size i=1; i<=forced.size(); ++i)
625 forced_pos_.push_back( std::atoi( forced[i].c_str() ) );