24 #include <basic/database/open.hh>
26 #include <utility/io/izstream.hh>
27 #include <utility/vector1.hh>
28 #include <utility/exit.hh>
29 #include <numeric/conversions.hh>
30 #include <numeric/xyzVector.hh>
31 #include <numeric/xyzMatrix.hh>
32 #include <numeric/xyz.functions.hh>
34 #include <ObjexxFCL/FArray1D.hh>
35 #include <ObjexxFCL/format.hh>
38 using namespace ObjexxFCL;
39 using namespace ObjexxFCL::fmt;
46 DNA_BasePotential::~DNA_BasePotential() {}
50 DNA_BasePotential::DNA_BasePotential():
53 stiffness_( 6, 6, 2, 16 )
61 using namespace chemical;
72 utility_exit_with_message(
"bad rsd type for DNA_BasePotential: "+rsd.
name() );
83 char const b1( bases[0] ), b2( bases[1] );
89 }
else if ( b1 ==
'C' ) {
91 }
else if ( b1 ==
'G' ) {
93 }
else if ( b1 ==
'T' ) {
100 }
else if ( b1 ==
'C' ) {
102 }
else if ( b1 ==
'G' ) {
104 }
else if ( b1 ==
'T' ) {
107 utility_exit_with_message(
"Unknown first DNA base label: "+b1 );
112 }
else if ( b2 ==
'C' ) {
114 }
else if ( b2 ==
'G' ) {
116 }
else if ( b2 ==
'T' ) {
119 utility_exit_with_message(
"Unknown first DNA base label: "+b2 );
166 utility::io::izstream data;
167 basic::database::open( data,
"scoring/dna/dna_bs_bp.dat" );
172 while ( getline( data,line ) ) {
173 std::istringstream l( line );
177 if ( l.fail() )
continue;
178 if ( tag ==
"SD:" ) {
181 l >> type_name >> bases >> param_name >> param_index >> mean >>
stddev;
182 assert( type_name ==
"BS" || type_name ==
"BP" );
184 if ( l.fail() || param_index < 1 || param_index > 6 ) {
185 std::cout <<
"failline:" << line << std::endl;
192 }
else if ( tag ==
"stiffness:" ) {
196 l >> type_name >> bases >> tmp >> i;
197 assert( type_name ==
"BS" || type_name ==
"BP" );
199 for (
int j=1; j<= 6; ++j ) {
204 std::cout <<
"failline:" << line << std::endl;
212 utility_exit_with_message(
"Unable to find/parse the DNA basepair and basestep params -- update your mini-DB?" );
226 assert( params.size() == 6 );
230 Real const MAX_SCORE_DEV = 100.0;
235 for (
int i = 1; i <= 6; ++i ) {
236 Real const max_delta_i = MAX_SCORE_DEV *
stddev( type, bases, i );
238 Real delta_i = params[i] -
mean( type, bases, i );
241 if ( delta_i > max_delta_i ) delta_i = max_delta_i;
242 if ( delta_i < -max_delta_i ) delta_i = -max_delta_i;
244 for (
int j = 1; j <= 6; ++j ) {
245 Real const max_delta_j = MAX_SCORE_DEV *
stddev( type, bases, j );
247 Real delta_j = params[j] -
mean( type, bases, j );
250 if ( delta_j > max_delta_j ) delta_j = max_delta_j;
251 if ( delta_j < -max_delta_j ) delta_j = -max_delta_j;
253 score +=
stiffness( type, bases, i, j ) * delta_i * delta_j;
294 for (
Size i=1; i<= 6; ++i ) {
313 for (
Size i=1; i<= 6; ++i ) {
331 if ( bpstr ==
"AT" || bpstr ==
"CG" || bpstr ==
"GC" || bpstr ==
"TA" )
343 Real const external_weight_factor
346 using numeric::conversions::degrees;
347 using numeric::conversions::radians;
348 using numeric::arccos;
349 using numeric::cross;
351 bool const debug(
true ), verbose(
false );
358 Matrix M1( stub1.M ), M2( stub2.M );
363 if ( dot( M1.col_z(), M2.col_z() ) < 0.0 ) {
364 std::cout <<
"dna_bs_deriv: base flip!" << std::endl;
369 Real const gamma( arccos( dot( M1.col_z(), M2.col_z() ) ) );
371 Vector const rt( ( cross( M2.col_z(), M1.col_z() ) ).normalized() );
373 Matrix R_gamma_2( rotation_matrix( rt, gamma/2.0f ) );
376 M1 = R_gamma_2.transposed() * M1;
382 assert( M1.col_z().distance( M2.col_z() ) < 1e-3 );
383 assert( std::abs( dot( rt, M1.col_z() ) ) < 1e-3 );
386 MBT.col_z( M1.col_z() );
388 assert( std::abs( dot( M1.col_x(), MBT.col_z() ) ) < 1e-3 );
389 assert( std::abs( dot( M2.col_x(), MBT.col_z() ) ) < 1e-3 );
390 assert( std::abs( dot( M1.col_y(), MBT.col_z() ) ) < 1e-3 );
391 assert( std::abs( dot( M2.col_y(), MBT.col_z() ) ) < 1e-3 );
394 MBT.col_y( ( 0.5f * ( M1.col_y() + M2.col_y() ) ).normalized() );
395 MBT.col_x( ( 0.5f * ( M1.col_x() + M2.col_x() ) ).normalized() );
405 params[1] = std::atan2( dot( M1.col_x(), M2.col_y() ),
406 dot( M1.col_x(), M2.col_x() ) );
408 params[2] = gamma * dot( rt, MBT.col_y() );
411 params[3] = gamma * dot( rt, MBT.col_x() );
414 Vector const displacement( stub1.v - stub2.v );
416 params[4] = dot( displacement, MBT.col_x() );
417 params[5] = dot( displacement, MBT.col_y() );
418 params[6] = dot( displacement, MBT.col_z() );
421 assert( params[1] * dot( MBT.col_z(), cross( M2.col_y(), M1.col_y() ) ) > 0);
424 Real const twist( params[1] );
425 Real const roll ( params[2] );
426 Real const tilt ( params[3] );
428 params[1] = degrees( params[1] );
429 params[2] = degrees( params[2] );
430 params[3] = degrees( params[3] );
437 for (
Size i=1; i<= 6; ++i ) {
438 assert( std::abs( params[i] - new_params[i] ) < 1e-2 );
444 Real const MAX_SCORE_DEV = 100.0;
448 bool out_of_bounds(
false );
451 for (
int i = 1; i <= 6; ++i ) {
457 if ( delta_i > max_delta_i ) {
458 out_of_bounds =
true;
459 delta_i = max_delta_i;
461 if ( delta_i < -max_delta_i ) {
462 out_of_bounds =
true;
463 delta_i = -max_delta_i;
466 for (
int j = 1; j <= 6; ++j ) {
472 if ( delta_j > max_delta_j ) {
473 out_of_bounds =
true;
474 delta_j = max_delta_j;
476 if ( delta_j < -max_delta_j ) {
477 delta_j = -max_delta_j;
478 out_of_bounds =
true;
482 dE_dp(i) += Fij * delta_j;
483 dE_dp(j) += Fij * delta_i;
488 if ( out_of_bounds ) {
490 std::cout <<
"WARNING:: out_of_bounds in dna base-pair derivative!" <<
496 for (
int i=1; i<= 6; ++i ) dE_dp(i) *= external_weight_factor;
515 Real const rad2deg( degrees(1.0));
518 Real const dE_dtwist( dE_dp(1) );
521 static Real const small_angle( radians( 0.1f ) );
522 static Real const big_angle( radians( 179.9f ) );
523 static Real const max_c( std::cos( small_angle ));
524 static Real const min_c( std::cos( big_angle ));
526 Vector x1( stub1.M.col_x() );
527 Vector R_gamma_x2( rotation_matrix( rt, gamma) *
Vector(stub2.M.col_x()) );
529 assert(
Vector(stub1.M.col_z()).
distance( rotation_matrix(rt,gamma) *
Vector(stub2.M.col_z())) <1e-2);
531 Real c( std::cos( twist ) );
532 assert( std::abs( c - dot( x1,R_gamma_x2 ) ) < 1e-2 );
533 c = std::min( std::max( min_c, c ), max_c );
535 Real const dtwist_dc = -1 / std::sqrt( 1 - c * c );
540 int const sign_factor( twist < 0 ? -1 : 1 );
542 if ( verbose ) std::cout <<
"dE_dtwist: " <<
543 F(9,3, dE_dtwist ) <<
544 F(9,3, dtwist_dc ) <<
545 F(9,3, cross(R_gamma_x2,x1).length() ) << std::endl;
547 F1 += sign_factor * dE_dtwist * rad2deg * dtwist_dc*
548 cross( R_gamma_x2, x1 );
575 Real const dE_droll( dE_dp(2) );
576 Real const dE_dtilt( dE_dp(3) );
578 Vector const z1( stub1.M.col_z() ), z2( stub2.M.col_z() );
580 Real const gamma_sin_gamma( gamma / std::sin( gamma ) );
582 runtime_assert( std::abs( roll - gamma_sin_gamma *
583 dot( cross( z2, z1 ), MBT.col_y() ) ) < 1e-2 );
585 runtime_assert( std::abs( tilt - gamma_sin_gamma *
586 dot( cross( z2, z1 ), MBT.col_x() ) ) < 1e-2 );
588 F1 += dE_dtilt * gamma_sin_gamma * rad2deg *
589 ( cross( z1, cross( z2, MBT.col_x() ) ) +
590 0.5f * cross( MBT.col_x(), cross( z1, z2 ) ) );
592 F1 += dE_droll * gamma_sin_gamma * rad2deg *
593 ( cross( z1, cross( z2, MBT.col_y() ) ) +
594 0.5f * cross( MBT.col_y(), cross( z1, z2 ) ) );
612 Vector M( stub1.v ), F( stub2.v );
614 F1 += dE_dp(4) * ( cross( MBT.col_x(), M - 0.5f * ( M - F ) ) );
615 F2 += dE_dp(4) * ( MBT.col_x() );
617 F1 += dE_dp(5) * ( cross( MBT.col_y(), M - 0.5f * ( M - F ) ) );
618 F2 += dE_dp(5) * ( MBT.col_y() );
620 F1 += dE_dp(6) * ( cross( MBT.col_z(), M - 0.5f * ( M - F ) ) );
621 F2 += dE_dp(6) * ( MBT.col_z() );
636 Real const external_weight_factor
639 using numeric::conversions::degrees;
640 using numeric::conversions::radians;
641 using numeric::arccos;
642 using numeric::cross;
644 bool const debug(
true );
649 Real const MAX_SCORE_DEV = 100.0;
655 Matrix M1( stub1.M ), M2( stub2.
M );
660 if ( dot( M1.col_z(), M2.col_z() ) < 0.0 ) {
661 std::cout <<
"dna_bp_deriv: base flip!" << std::endl;
666 Real const gamma( arccos( dot( M1.col_y(), M2.col_y() ) ) );
668 Vector const bo( ( cross( M2.col_y(), M1.col_y() ) ).normalized() );
670 Matrix R_gamma_2( rotation_matrix( bo, gamma/2.0f ) );
673 M1 = R_gamma_2.transposed() * M1;
677 assert( M1.col_y().distance( M2.col_y() ) < 1e-3 );
678 assert( std::abs( dot( bo, M1.col_y() ) ) < 1e-3 );
682 MBT.col_y( M1.col_y() );
683 MBT.col_x( ( 0.5f * ( M1.col_x() + M2.col_x() ) ).normalized() );
684 MBT.col_z( ( 0.5f * ( M1.col_z() + M2.col_z() ) ).normalized() );
691 Real const omega = std::atan2( dot( M1.col_z(), M2.col_x() ),
692 dot( M1.col_z(), M2.col_z() ) );
694 assert( ( std::abs( std::abs( omega ) -
695 arccos( dot( M1.col_z(), M2.col_z() ) ) )<1e-2 ) &&
696 ( std::abs( std::abs( omega ) -
697 arccos( dot( M1.col_x(), M2.col_x() ) ) )<1e-2 ) );
700 Real const kappa = gamma * dot( bo, MBT.col_x() );
703 Real const sigma = gamma * dot( bo, MBT.col_z() );
707 Vector const displacement( stub1.v - stub2.
v );
709 params[4] = dot( displacement, MBT.col_x() );
710 params[5] = dot( displacement, MBT.col_y() );
711 params[6] = dot( displacement, MBT.col_z() );
715 assert( omega * dot( MBT.col_y(), cross( M2.col_x(), M1.col_x() ) ) > 0);
718 params[1] = degrees( omega );
719 params[2] = degrees( kappa );
720 params[3] = degrees( sigma );
726 for (
Size i=1; i<= 6; ++i ) {
727 assert( std::abs( params[i] - new_params[i] ) < 1e-2 );
734 bool out_of_bounds(
false );
737 for (
int i = 1; i <= 6; ++i ) {
743 if ( delta_i > max_delta_i ) {
744 delta_i = max_delta_i;
745 out_of_bounds =
true;
747 if ( delta_i < -max_delta_i ) {
748 delta_i = -max_delta_i;
749 out_of_bounds =
true;
752 for (
int j = 1; j <= 6; ++j ) {
758 if ( delta_j > max_delta_j ) {
759 delta_j = max_delta_j;
760 out_of_bounds =
true;
762 if ( delta_j < -max_delta_j ) {
763 delta_j = -max_delta_j;
764 out_of_bounds =
true;
769 dE_dp(i) += Fij * delta_j;
770 dE_dp(j) += Fij * delta_i;
774 if ( out_of_bounds ) {
776 std::cout <<
"WARNING:: out_of_bounds in dna base-pair derivative!" <<
781 for (
int i=1; i<= 6; ++i ) {
782 dE_dp(i) *= external_weight_factor;
802 Real const rad2deg( degrees(1.0));
805 Real const dE_domega( dE_dp(1) );
808 static Real const small_angle( radians( 0.1f ) );
809 static Real const big_angle( radians( 179.9f ) );
810 static Real const max_c( std::cos( small_angle ));
811 static Real const min_c( std::cos( big_angle ));
813 Vector x1( stub1.M.col_x() );
814 Vector R_gamma_x2( rotation_matrix( bo, gamma) *
Vector(stub2.
M.col_x()) );
816 assert(
Vector(stub1.M.col_y()).
distance( rotation_matrix(bo,gamma) *
Vector(stub2.
M.col_y())) <1e-2);
818 Real c( std::cos( omega ) );
819 assert( std::abs( c - dot( x1,R_gamma_x2 ) ) < 1e-2 );
820 c = std::min( std::max( min_c, c ), max_c );
822 Real const domega_dc = -1 / std::sqrt( 1 - c * c );
827 int const sign_factor2( omega < 0 ? -1 : 1 );
829 F1 += sign_factor2 * dE_domega * rad2deg * domega_dc *
830 cross( R_gamma_x2, x1 );
857 Real const dE_dkappa( dE_dp(2) );
858 Real const dE_dsigma( dE_dp(3) );
860 Vector const y1( stub1.M.col_y() ), y2( stub2.
M.col_y() );
862 Real const gamma_sin_gamma( gamma / std::sin( gamma ) );
864 F1 += dE_dkappa * gamma_sin_gamma * rad2deg *
865 ( cross( y1, cross( y2, MBT.col_x() ) ) +
866 0.5f * cross( MBT.col_x(), cross( y1, y2 ) ) );
868 F1 += dE_dsigma * gamma_sin_gamma * rad2deg *
869 ( cross( y1, cross( y2, MBT.col_z() ) ) +
870 0.5f * cross( MBT.col_z(), cross( y1, y2 ) ) );
888 Vector M( stub1.v ), F( stub2.
v );
890 F1 += dE_dp(4) * ( cross( MBT.col_x(), M - 0.5f * ( M - F ) ) );
891 F2 += dE_dp(4) * ( MBT.col_x() );
893 F1 += dE_dp(5) * ( cross( MBT.col_y(), M - 0.5f * ( M - F ) ) );
894 F2 += dE_dp(5) * ( MBT.col_y() );
896 F1 += dE_dp(6) * ( cross( MBT.col_z(), M - 0.5f * ( M - F ) ) );
897 F2 += dE_dp(6) * ( MBT.col_z() );