21 #include <basic/Tracer.hh>
22 #include <basic/basic.hh>
30 #include <numeric/conversions.hh>
31 #include <numeric/xyzVector.hh>
32 #include <numeric/xyzMatrix.hh>
33 #include <numeric/xyz.functions.hh>
35 #include <ObjexxFCL/format.hh>
36 #include <ObjexxFCL/string.functions.hh>
38 #include <utility/vector1.hh>
46 using namespace ObjexxFCL;
47 using namespace ObjexxFCL::fmt;
65 std::pair< std::string, int > & pucker
70 names.push_back(
"C1*" );
71 names.push_back(
"C2*" );
72 names.push_back(
"C3*" );
73 names.push_back(
"C4*" );
74 names.push_back(
"O4*" );
77 for (
int i=1; i<= 5; ++i ) {
78 atoms.push_back( rsd.
xyz( names[i] ) );
83 for (
int ii=1; ii<= 5; ++ii ) {
85 Vector n12 = (( atoms[2]-atoms[1] ).cross( atoms[3]-atoms[2] ) ).normalized();
86 Real dot = std::abs( n12.dot( ( atoms[4]-atoms[3] ).normalized() ) );
92 pucker.first = names[5];
93 exxo = ( n12.dot( ( atoms[5] -
Real(0.5) * ( atoms[4] + atoms[1] ) ).normalized() ) > 0.0 );
96 atoms.push_back( atoms[1] );
97 atoms.erase( atoms.begin() );
99 names.push_back( names[1] );
100 names.erase( names.begin() );
107 int const atom_index( std::find( names.begin(), names.end(), pucker.first ) - names.begin() );
108 int const sign_index( exxo ? 0 : 1 );
109 if ( atom_index%2 == sign_index ) pucker.second = atom_index+1;
110 else pucker.second = atom_index-4;
113 if ( exxo ) pucker.first +=
" exxo";
114 else pucker.first +=
" endo";
122 phi = basic::periodic_range( phi, 360.0 );
123 if ( -120 <= phi && phi < 0 )
return "g-";
124 else if ( 0 <= phi && phi < 120 )
return "g+";
143 Real const dev( basic::subtract_degree_angles( epsilon, zeta ) );
149 b12_bin += ObjexxFCL::right_string_of( static_cast<int>( dev/10.0 ), 4 );
151 return ag_bin +
" " + b12_bin;
166 using namespace chemical;
184 std::cout << rsd_type.
aa() <<
" is unknown to me, tovarisch!\n";
197 return ( rsd.
xyz( a2 ) - rsd.
xyz( a1 ) ).normalized();
208 using namespace chemical;
210 return rsd.
xyz(
"C8");
213 return rsd.
xyz(
"C6");
216 utility_exit_with_message(
"get_base_pair_y_axis_atom_xyz: bad aa");
229 using namespace chemical;
233 xx = rsd.
xyz(
"C5") + rsd.
xyz(
"C6") - rsd.
xyz(
"N3") - rsd.
xyz(
"C2");
235 xx = rsd.
xyz(
"C5") + rsd.
xyz(
"C4") - rsd.
xyz(
"N1") - rsd.
xyz(
"C2");
237 utility_exit_with_message(
"get_z_axis: bad aa");
240 return xx.cross( y_axis ).normalized();
249 if ( strand == 2 ) orient *= -1.0f;
269 if ( dot( z_axis, orient ) < 0.0 ) {
275 assert( std::abs( z_axis.dot( y_axis ) ) < 1e-3 );
291 bool flipped(
false );
292 return get_z_axis( rsd, y_axis, strand, flipped );
307 for(
int i=1; i<=3; ++i ) {
308 for(
int j=1; j<=3; ++j ) {
309 dev += std::abs(
X(i,j) - ( i == j ? 1.0 : 0.0 ) );
326 using numeric::conversions::degrees;
334 Vector x_axis, y_axis, z_axis, origin;
339 origin = 0.5f * (v1 + v2 );
341 bool flipped(
false );
342 z_axis =
get_z_axis( rsd, y_axis, strand, flipped );
344 basic::T(
"core.scoring.dna.base_geometry", basic::t_warning ) <<
"base flip in get_base_stub!!!" <<
'\n';
346 assert( std::abs( dot(y_axis, z_axis) ) < 1e-3 );
348 x_axis = cross( y_axis, z_axis );
351 return kinematics::Stub( kinematics::Stub::Matrix::cols( x_axis, y_axis, z_axis ), origin );
362 using numeric::conversions::degrees;
366 Vector const origin(
Real( 0.5 )* ( y1 + y2 ) );
367 Vector const y_axis( ( y1 - y2 ).normalized() );
372 if ( z1_axis.dot( z2_axis ) < 0.0 ) {
373 basic::T(
"core.scoring.dna.base_geometry", basic::t_warning ) <<
"wacky base flip in get_base_pair_stub!!!" <<
'\n';
376 z_axis = ( z1_axis + z2_axis ).normalized();
378 assert( std::abs( y_axis.dot( z_axis ) ) <1e-3 );
379 Vector x_axis( cross( y_axis, z_axis ) );
382 return kinematics::Stub( kinematics::Stub::Matrix::cols( x_axis, y_axis, z_axis ), origin );
393 using numeric::conversions::degrees;
397 Vector const origin(
Real( 0.5 )* ( y1 + y2 ) );
398 Vector const y_axis( ( y1 - y2 ).normalized() );
407 ++first_base_sidechain_atom;
409 for (
Size i = first_base_sidechain_atom; i<= rsd1.
nheavyatoms(); ++i ) {
410 basepair_atoms.push_back( rsd1.
xyz(i) );
415 ++first_base_sidechain_atom;
417 for (
Size i = first_base_sidechain_atom; i<= rsd2.
nheavyatoms(); ++i ) {
418 basepair_atoms.push_back( rsd2.
xyz(i) );
422 z_axis = ( z_axis - y_axis.dot( z_axis ) * y_axis ).normalized();
423 assert( z_axis.is_normalized( 1e-3 ) && z_axis.dot( y_axis ) < 1e-3 );
426 Vector x_axis( cross( y_axis, z_axis ) );
429 return kinematics::Stub( kinematics::Stub::Matrix::cols( x_axis, y_axis, z_axis ), origin );
449 for (
Size i=1; i<= 6; ++i ) dev += z_scores[i]*z_scores[i];
450 out <<
"BP_PARAMS " <<
453 " Prop: " << F(7,1,params[1]) << F(6,1,z_scores[1]) <<
454 " Buck: " << F(7,1,params[2]) << F(6,1,z_scores[2]) <<
455 " Open: " << F(7,1,params[3]) << F(6,1,z_scores[3]) <<
456 " Sher: " << F(7,2,params[4]) << F(6,1,z_scores[4]) <<
457 " Strc: " << F(7,2,params[5]) << F(6,1,z_scores[5]) <<
458 " Stag: " << F(7,2,params[6]) << F(6,1,z_scores[6]) <<
'\n';
475 " Prop:" << F(6,1,params[1]) <<
476 " Buck:" << F(6,1,params[2]) <<
477 " Open:" << F(6,1,params[3]) <<
478 " Sher:" << F(6,2,params[4]) <<
479 " Strc:" << F(6,2,params[5]) <<
480 " Stag:" << F(6,2,params[6]) <<
'\n';
552 using numeric::conversions::degrees;
553 using numeric::arccos;
555 bool const local_debug(
true );
559 Matrix M1( stub1.
M ), M2( stub2.
M );
564 bool base_flipped =
false;
565 if ( dot( M1.col_z(), M2.col_z() ) < 0.0 ) {
567 basic::T(
"core.scoring.base_geometry") <<
"get_stub_stub_params: base flip!!!\n";
568 for (
Size i = 1; i <= 6; ++i) {
576 Real const gamma( arccos( dot( M1.col_y(), M2.col_y() ) ) );
578 Vector const bo( ( cross( M2.col_y(), M1.col_y() ) ).normalized() );
580 Matrix R_gamma_2( rotation_matrix( bo, gamma/2.0f ) );
583 M1 = R_gamma_2.transposed() * M1;
589 assert( M1.col_y().distance( M2.col_y() ) < 1e-3 );
590 assert( std::abs( dot( bo, M1.col_y() ) ) < 1e-3 );
593 MBT.col_y( M1.col_y() );
595 assert( std::abs( dot( M1.col_z(), MBT.col_y() ) ) < 1e-3 );
596 assert( std::abs( dot( M2.col_z(), MBT.col_y() ) ) < 1e-3 );
597 assert( std::abs( dot( M1.col_x(), MBT.col_y() ) ) < 1e-3 );
598 assert( std::abs( dot( M2.col_x(), MBT.col_y() ) ) < 1e-3 );
601 MBT.col_x( ( 0.5f * ( M1.col_x() + M2.col_x() ) ).normalized() );
602 MBT.col_z( ( 0.5f * ( M1.col_z() + M2.col_z() ) ).normalized() );
610 params[1] = std::atan2( dot( M1.col_z(), M2.col_x() ),
611 dot( M1.col_z(), M2.col_z() ) );
613 assert( !local_debug || ( std::abs( std::abs( params[1] ) - arccos( dot( M1.col_z(), M2.col_z() ) ) ) < 1e-2 ) );
616 params[2] = gamma * dot( bo, MBT.col_x() );
619 params[3] = gamma * dot( bo, MBT.col_z() );
622 Vector const displacement( stub1.
v - stub2.
v );
624 params[4] = dot( displacement, MBT.col_x() );
625 params[5] = dot( displacement, MBT.col_y() );
626 params[6] = dot( displacement, MBT.col_z() );
634 assert( abs( (sin( gamma ) * params[2] / gamma) -
635 dot(
Vector( cross( stub2.
M.col_y(), stub1.
M.col_y() ) ), MBT.col_x() )) < 1e-2 );
641 assert( abs( ( sin( gamma ) * params[3] / gamma ) -
642 dot(
Vector( cross( stub2.
M.col_y(), stub1.
M.col_y() )), MBT.col_z() ) ) < 1e-2 );
646 Real phi_prime( arccos( dot( bo, MBT.col_x() ) ) );
647 if ( dot( cross( bo, MBT.col_x() ), MBT.col_y() ) < 0.0f ) {
651 Vector tmp( cross( M2.col_z(), M1.col_z() ) );
652 assert( cross( tmp, MBT.col_y() ).length() <1e-2 );
656 assert( ( base_flipped ) ||
657 ( abs( params[1] - asin( dot( MBT.col_y(), cross( M2.col_x(), M1.col_x() ) ) ) ) +
658 abs( params[1] - asin( dot( MBT.col_y(), cross( M2.col_z(), M1.col_z() ) ) ) ) < 1e-2 ) );
666 assert( abs( gamma * cos( phi_prime ) - params[2] ) + abs( gamma * sin( phi_prime ) - params[3] ) < 1e-2 );
669 assert( params[1] * dot( MBT.col_y(), cross( M2.col_x(), M1.col_x() ) ) > 0);
673 params[1] = degrees( params[1] );
674 params[2] = degrees( params[2] );
675 params[3] = degrees( params[3] );
730 Stub( Stub::Matrix::cols( stub1.M.col_y(), stub1.M.col_z(), stub1.M.col_x() ), stub1.v ),
747 return ( seqpos < pose.
total_residue() && ( rsd.is_DNA() || rsd.is_RNA() )&& !rsd.is_lower_terminus() && partner[ seqpos ] &&
748 partner[ seqpos+1 ] && partner[seqpos] == partner[seqpos+1]+1 && partner[seqpos] != seqpos+1 );
768 out <<
"BS_PARAMS " << seqpos <<
" N/A\n";
778 out <<
"BS_PARAMS " <<
779 I(4,seqpos ) << I(4,partner[seqpos ]) <<
' ' << rsd11.name1() << rsd12.name1() <<
" to " <<
780 I(4,seqpos+1) << I(4,partner[seqpos+1]) <<
' ' << rsd21.name1() << rsd22.name1() <<
781 " Twst:" << F(6,1,params[1]) <<
782 " Roll:" << F(6,1,params[2]) <<
783 " Tilt:" << F(6,1,params[3]) <<
784 " Slid:" << F(6,2,params[4]) <<
785 " Rise:" << F(6,2,params[5]) <<
786 " Shft:" << F(6,2,params[6]) <<
'\n';
803 for (
Size i=1; i<= 6; ++i ) dev += z_scores[i]*z_scores[i];
804 std::cout <<
"BS-params: " <<
807 " Twst: " << F(7,1,params[1]) << F(6,1,z_scores[1]) <<
808 " Roll: " << F(7,1,params[2]) << F(6,1,z_scores[2]) <<
809 " Tilt: " << F(7,1,params[3]) << F(6,1,z_scores[3]) <<
810 " Shft: " << F(7,2,params[4]) << F(6,1,z_scores[4]) <<
811 " Slid: " << F(7,2,params[5]) << F(6,1,z_scores[5]) <<
812 " Rise: " << F(7,2,params[6]) << F(6,1,z_scores[6]) << std::endl;
841 if ( partner[i] > i ) {
875 for (
Size i=1; i<= nres; ++i ) {
877 if ( !rsd.is_DNA() || rsd.is_RNA() )
continue;
878 std::pair< std::string, int > pucker;
881 out <<
"DNA_DIHEDRALS " << I(4,i) <<
' ' << rsd.name1() <<
' ' <<
883 F(7,1,rsd.mainchain_torsion(1)) <<
884 F(7,1,rsd.mainchain_torsion(2)) <<
885 F(7,1,rsd.mainchain_torsion(3)) <<
886 F(7,1,rsd.mainchain_torsion(4)) <<
887 F(7,1,rsd.mainchain_torsion(5)) <<
888 F(7,1,rsd.mainchain_torsion(6)) <<
889 F(7,1,rsd.chi(1)) <<
'\n';
917 int const natoms( atoms_in.size() );
918 for (
int i=1; i<= natoms; ++i ) {
925 for (
int i=1; i<= natoms; ++i ) {
926 atoms.push_back( atoms_in[i] - cm );
933 for (
int i = 1; i <= 3; ++i ) {
934 for (
int j = i; j <= 3; ++j ) {
935 for (
int a = 1; a <= natoms; ++a ) {
936 A(i,j) += atoms[a](i) * atoms[a](j);
942 Real a =
A(1,1) +
A(2,2) +
A(3,3);
943 Real b =
A(1,3)*
A(1,3) +
A(1,2)*
A(1,2) +
A(2,3)*
A(2,3)
944 -
A(2,2)*
A(3,3) -
A(1,1)*
A(3,3) -
A(1,1)*
A(2,2);
945 Real g =
A(1,1)*
A(2,2)*
A(3,3) + 2*
A(1,2)*
A(2,3)*
A(1,3)
946 -
A(1,1)*
A(2,3)*
A(2,3) -
A(2,2)*
A(1,3)*
A(1,3)
947 -
A(3,3)*
A(1,2)*
A(1,2);
953 if (b*b - 4*a*g > 0) {
954 lambda = (-b - std::sqrt(b*b - 4*a*g) )/(2*a);
965 normal_f(1) = (
A(2,2)-lambda)*
A(1,3) -
A(1,2)*
A(2,3);
966 normal_f(2) = (
A(1,1)-lambda)*
A(2,3) -
A(1,2)*
A(1,3);
967 normal_f(3) =
A(1,2)*
A(1,2) - (
A(2,2)-lambda)*(
A(1,1)-lambda);
969 normal_f.normalize();
992 using numeric::conversions::degrees;
993 using numeric::arccos;
995 bool const local_debug(
false );
1002 Matrix M1( stub1.M ), M2( stub2.
M );
1007 bool base_flipped =
false;
1008 if ( dot( M1.col_z(), M2.col_z() ) < 0.0 ) {
1009 base_flipped =
true;
1010 basic::T(
"core.scoring.base_geometry") <<
"base_pair_params: base flip!!!\n";
1015 Real const gamma( arccos( dot( M1.col_y(), M2.col_y() ) ) );
1017 Vector const bo( ( cross( M2.col_y(), M1.col_y() ) ).normalized() );
1019 Matrix R_gamma_2( rotation_matrix( bo, gamma/2.0f ) );
1021 M2 = R_gamma_2 * M2;
1022 M1 = R_gamma_2.transposed() * M1;
1028 assert( M1.col_y().distance( M2.col_y() ) < 1e-3 );
1029 assert( std::abs( dot( bo, M1.col_y() ) ) < 1e-3 );
1032 MBT.col_y( M1.col_y() );
1034 assert( std::abs( dot( M1.col_z(), MBT.col_y() ) ) < 1e-3 );
1035 assert( std::abs( dot( M2.col_z(), MBT.col_y() ) ) < 1e-3 );
1036 assert( std::abs( dot( M1.col_x(), MBT.col_y() ) ) < 1e-3 );
1037 assert( std::abs( dot( M2.col_x(), MBT.col_y() ) ) < 1e-3 );
1040 MBT.col_x( ( 0.5f * ( M1.col_x() + M2.col_x() ) ).normalized() );
1041 MBT.col_z( ( 0.5f * ( M1.col_z() + M2.col_z() ) ).normalized() );
1049 params[1] = std::atan2( dot( M1.col_z(), M2.col_x() ),
1050 dot( M1.col_z(), M2.col_z() ) );
1052 if ( local_debug ) {
1053 assert( abs( abs( params[1] ) - arccos( dot( M1.col_z(), M2.col_z() ) ) ) < 1e-2 );
1057 params[2] = gamma * dot( bo, MBT.col_x() );
1060 params[3] = gamma * dot( bo, MBT.col_z() );
1063 Vector const displacement( stub1.v - stub2.
v );
1065 params[4] = dot( displacement, MBT.col_x() );
1066 params[5] = dot( displacement, MBT.col_y() );
1067 params[6] = dot( displacement, MBT.col_z() );
1071 if ( local_debug ) {
1075 assert( abs(sin( gamma ) * params[2] / gamma -
1076 dot(
Vector( cross( stub2.
M.col_y(), stub1.M.col_y() ) ), MBT.col_x() )) < 1e-2 );
1082 assert( abs(sin( gamma ) * params[3] / gamma -
1083 dot(
Vector( cross( stub2.
M.col_y(), stub1.M.col_y() )), MBT.col_z() )) < 1e-2 );
1087 Real phi_prime( arccos( dot( bo, MBT.col_x() ) ) );
1088 if ( dot( cross( bo, MBT.col_x() ), MBT.col_y() ) < 0.0f ) {
1092 Vector tmp( cross( M2.col_z(), M1.col_z() ) );
1093 assert( cross( tmp, MBT.col_y() ).length() <1e-2 );
1097 assert( ( base_flipped ) ||
1098 ( abs( params[1] - asin( dot( MBT.col_y(), cross( M2.col_x(), M1.col_x() ) ) ) ) +
1099 abs( params[1] - asin( dot( MBT.col_y(), cross( M2.col_z(), M1.col_z() ) ) ) ) < 1e-2 ) );
1107 assert( abs( gamma * cos( phi_prime ) - params[2] ) + abs( gamma * sin( phi_prime ) - params[3] ) < 1e-2 );
1110 assert( params[1] * dot( MBT.col_y(), cross( M2.col_x(), M1.col_x() ) ) > 0);
1114 params[1] = degrees( params[1] );
1115 params[2] = degrees( params[2] );
1116 params[3] = degrees( params[3] );
1130 using numeric::conversions::degrees;
1131 using numeric::arccos;
1132 using numeric::cross;
1134 bool const local_debug(
false );
1141 Matrix M1( stub1.M ), M2( stub2.
M );
1146 if ( dot( M1.col_z(), M2.col_z() ) < 0.0 ) {
1148 basic::T(
"core.scoring.base_geometry") <<
"base_pair_params: base flip!!!\n";
1154 Real const gamma( arccos( dot( M1.col_z(), M2.col_z() ) ) );
1156 Vector const rt( ( cross( M2.col_z(), M1.col_z() ) ).normalized() );
1158 Matrix R_gamma_2( rotation_matrix( rt, gamma/2.0f ) );
1160 M2 = R_gamma_2 * M2;
1161 M1 = R_gamma_2.transposed() * M1;
1167 assert( M1.col_z().distance( M2.col_z() ) < 1e-3 );
1168 assert( std::abs( dot( rt, M1.col_z() ) ) < 1e-3 );
1171 MBT.col_z( M1.col_z() );
1173 assert( std::abs( dot( M1.col_x(), MBT.col_z() ) ) < 1e-3 );
1174 assert( std::abs( dot( M2.col_x(), MBT.col_z() ) ) < 1e-3 );
1175 assert( std::abs( dot( M1.col_y(), MBT.col_z() ) ) < 1e-3 );
1176 assert( std::abs( dot( M2.col_y(), MBT.col_z() ) ) < 1e-3 );
1179 MBT.col_y( ( 0.5f * ( M1.col_y() + M2.col_y() ) ).normalized() );
1180 MBT.col_x( ( 0.5f * ( M1.col_x() + M2.col_x() ) ).normalized() );
1188 params[1] = atan2( dot( M1.col_x(), M2.col_y() ), dot( M1.col_x(), M2.col_x() ) );
1190 if ( local_debug ) {
1191 assert( abs( abs( params[1] ) - arccos( dot( M1.col_x(), M2.col_x() ) ) ) < 1e-2 );
1196 params[2] = gamma * dot( rt, MBT.col_y() );
1199 params[3] = gamma * dot( rt, MBT.col_x() );
1202 Vector const displacement( stub1.v - stub2.
v );
1204 params[4] = dot( displacement, MBT.col_x() );
1205 params[5] = dot( displacement, MBT.col_y() );
1206 params[6] = dot( displacement, MBT.col_z() );
1210 if ( local_debug ) {
1214 assert( abs( sin( gamma ) * params[2] / gamma -
1215 dot(
Vector( cross( stub2.
M.col_z(), stub1.M.col_z() ) ), MBT.col_y() )) < 1e-2 );
1221 assert( abs( sin( gamma ) * params[3] / gamma -
1222 dot(
Vector( cross( stub2.
M.col_z(), stub1.M.col_z() )), MBT.col_x() )) < 1e-2 );
1226 Real phi_prime( arccos( dot( rt, MBT.col_y() ) ) );
1227 if ( dot( cross( rt, MBT.col_y() ), MBT.col_z() ) < 0.0f ) {
1231 Vector tmp( cross( M2.col_x(), M1.col_x() ) );
1232 assert( cross( tmp, MBT.col_z() ).length() <1e-2 );
1238 assert( abs( params[1] - asin( dot( MBT.col_z(), cross( M2.col_y(), M1.col_y() ) ) ) ) +
1239 abs( params[1] - asin( dot( MBT.col_z(), cross( M2.col_x(), M1.col_x() ) ) ) ) < 1e-2 );
1245 assert( abs( gamma * cos( phi_prime ) - params[2] ) + abs( gamma * sin( phi_prime ) - params[3] ) < 1e-2 );
1248 assert( params[1] * dot( MBT.col_z(), cross( M2.col_y(), M1.col_y() ) ) > 0);
1252 params[1] = degrees( params[1] );
1253 params[2] = degrees( params[2] );
1254 params[3] = degrees( params[3] );
1262 std::pair< std::string, int > & pucker,
1263 Real & pseudorotation,
1267 using numeric::conversions::radians;
1268 using numeric::conversions::degrees;
1271 names.push_back(
"C1*" );
1272 names.push_back(
"C2*" );
1273 names.push_back(
"C3*" );
1274 names.push_back(
"C4*" );
1275 names.push_back(
"O4*" );
1278 for (
int i=1; i<= 5; ++i ) {
1279 atoms.push_back( rsd.
xyz( names[i] ) );
1282 Real mindot = 1000.0;
1285 for (
int ii=1; ii<= 5; ++ii ) {
1287 torsions[ ii ] = dihedral_radians(
1294 Vector n12 = (( atoms[2]-atoms[1] ).cross( atoms[3]-atoms[2] ) ).normalized();
1295 Real dot = std::abs( n12.dot( ( atoms[4]-atoms[3] ).normalized() ) );
1296 if ( dot < mindot ) {
1301 pucker.first = names[5];
1302 exxo = ( n12.dot( ( atoms[5] -
Real(0.5) * ( atoms[4] + atoms[1] ) ).normalized() ) > 0.0 );
1305 atoms.push_back( atoms[1] );
1306 atoms.erase( atoms.begin() );
1308 names.push_back( names[1] );
1309 names.erase( names.begin() );
1313 pseudorotation = atan(
1314 ( ( torsions[2] + torsions[5] ) - ( torsions[1] + torsions[4] ) ) /
1315 ( 2.0 * torsions[3] * ( sin( radians(36.0) ) + sin( radians(72.0)) ) )
1318 pseudorotation = degrees( pseudorotation );
1319 if( torsions[3] < 0.0 ) pseudorotation += 180.0;
1321 pseudorotation = basic::periodic_range( pseudorotation, 360.0 );
1323 amplitude = degrees( torsions[3] / ( cos( radians( pseudorotation ) ) + 1.0e-20 ) );
1327 int const atom_index( std::find( names.begin(), names.end(), pucker.first ) - names.begin() );
1328 int const sign_index( exxo ? 0 : 1 );
1329 if ( atom_index%2 == sign_index ) pucker.second = atom_index+1;
1330 else pucker.second = atom_index-4;
1333 if ( exxo ) pucker.first +=
" exxo";
1334 else pucker.first +=
" endo";
1344 using numeric::conversions::degrees;
1345 using numeric::arccos;
1348 kinematics::Stub stub1( kinematics::Stub::Matrix::cols( in_stub2.
M.col_y(), in_stub2.
M.col_z(), in_stub2.
M.col_x() ), in_stub2.
v );
1349 kinematics::Stub stub2( kinematics::Stub::Matrix::cols( in_stub1.
M.col_y(), in_stub1.
M.col_z(), in_stub1.
M.col_x() ), in_stub1.
v );
1352 Matrix M1( stub1.
M ), M2( stub2.
M );
1357 bool base_flipped =
false;
1358 if ( dot( M1.col_z(), M2.col_z() ) < 0.0 ) {
1359 base_flipped =
true;
1360 basic::T(
"core.scoring.base_geometry") <<
"get_midstep_stub: base flip!!!\n";
1369 Real const gamma( arccos( dot( M1.col_y(), M2.col_y() ) ) );
1371 Vector const bo( ( cross( M2.col_y(), M1.col_y() ) ).normalized() );
1373 Matrix R_gamma_2( rotation_matrix( bo, gamma/2.0f ) );
1375 M2 = R_gamma_2 * M2;
1376 M1 = R_gamma_2.transposed() * M1;
1382 assert( M1.col_y().distance( M2.col_y() ) < 1e-3 );
1383 assert( std::abs( dot( bo, M1.col_y() ) ) < 1e-3 );
1386 MBT.col_y( M1.col_y() );
1388 assert( std::abs( dot( M1.col_z(), MBT.col_y() ) ) < 1e-3 );
1389 assert( std::abs( dot( M2.col_z(), MBT.col_y() ) ) < 1e-3 );
1390 assert( std::abs( dot( M1.col_x(), MBT.col_y() ) ) < 1e-3 );
1391 assert( std::abs( dot( M2.col_x(), MBT.col_y() ) ) < 1e-3 );
1394 MBT.col_x( ( 0.5f * ( M1.col_x() + M2.col_x() ) ).normalized() );
1395 MBT.col_z( ( 0.5f * ( M1.col_z() + M2.col_z() ) ).normalized() );