27 #include <basic/options/option.hh>
29 #include <basic/datacache/BasicDataCache.hh>
34 #include <basic/Tracer.hh>
39 #include <ObjexxFCL/format.hh>
49 #include <utility/excn/Exceptions.hh>
50 #include <utility/io/izstream.hh>
51 #include <utility/io/ozstream.hh>
55 #include <basic/options/keys/in.OptionKeys.gen.hh>
56 #include <basic/options/keys/rdc.OptionKeys.gen.hh>
58 #include <numeric/nls/lmmin.hh>
61 #include <utility/vector1.hh>
62 #include <numeric/random/random.fwd.hh>
63 #include <numeric/NumericTraits.hh>
65 static basic::Tracer
tr(
"core.scoring.ResidualDipolarCoupling");
104 out <<
"RDC "<<++ct <<
" ";
105 out << (*it) << std::endl;
110 using namespace ObjexxFCL::fmt;
126 basic::datacache::CacheableData(other) {
136 basic::datacache::CacheableData::operator=(other);
147 utility::io::izstream infile(filename.c_str());
148 if ( !infile.good() ) {
149 throw( utility::excn::EXCN_FileNotFound( filename ) );
152 tr.Info <<
"Reading RDC file " << filename << std::endl;
154 while (getline(infile, line)) {
155 std::istringstream line_stream(line);
159 line_stream >> res1 >> atom1 >> res2 >> atom2 >> Jdipolar;
161 if ( atom1 ==
"HN" ) atom1 =
"H";
162 if ( atom2 ==
"HN" ) atom2 =
"H";
165 if ( line_stream.fail() ) {
166 tr.Error <<
"couldn't read line " << line <<
" in rdc-file " << filename << std::endl;
167 throw( utility::excn::EXCN_BadInput(
" invalid line "+line+
" in rdc-file "+filename));
170 if ( res1 < 1 || res2 < 1 ) {
171 tr.Error <<
"negative residue number in line " << line <<
" in rdc-file " << filename << std::endl;
172 throw( utility::excn::EXCN_BadInput(
" invalid line "+line+
" in rdc_file " + filename ) );
176 line_stream >> weight;
177 if (line_stream.fail()) {
178 tr.Debug <<
" set weight for RDC " << res1 <<
" to 1.0 ";
182 tr.Debug <<
"... added to dataset!";
184 weight, expid - 1 ));
186 tr.Debug << std::endl;
189 tr.Error <<
"file empty ? " << std::endl;
190 throw( utility::excn::EXCN_BadInput(
" no valid RDCs found in file " + filename +
"\n" ));
198 using namespace basic::options;
199 using namespace basic::options::OptionKeys;
201 tr.Warning <<
"no RDC file specified" << std::endl;
219 if (option[OptionKeys::rdc::weights].user()) {
221 std::ifstream infile(filename.c_str());
223 while (getline(infile, line)) {
224 std::istringstream line_stream(line);
227 line_stream >> res1 >> weight;
228 if (line_stream.fail()) {
229 tr.Error <<
"[Error] reading rdc-weight-file " << filename
231 throw(utility::excn::EXCN_BadInput(
" invalid line " + line
232 +
" in rdc-weight-file " + filename));
236 if (it->res1() == res1) {
238 tr.Info <<
"set tensor-weight for RDCs to " << weight
239 <<
" at residue (res1) " << res1 << std::endl;
261 tr.Trace <<
"reserve buffers for nex: " << nex <<
" and nrows " << nrows << std::endl;
309 if (it->expid() >=
nex_)
310 nex_ = it->expid() + 1;
317 if (atom ==
"HN" || atom ==
"H" || atom ==
"HA" || atom ==
"1H" )
319 if (atom ==
"C" || atom ==
"CA")
323 throw(utility::excn::EXCN_BadInput(
"unknown atom for RDC: " + atom));
335 if ((elem1 ==
"N" && elem2 ==
"H") || (elem1 ==
"H" && elem2 ==
"N"))
336 RDC_type = RDC_TYPE_NH;
337 else if ((elem1 ==
"CA" && elem2 ==
"HA") || (elem1 ==
"HA" && elem2 ==
"CA"))
338 RDC_type = RDC_TYPE_CH;
339 else if ((elem1 ==
"C" && elem2 ==
"N") || (elem1 ==
"N" && elem2 ==
"C"))
340 RDC_type = RDC_TYPE_NC;
341 else if ((elem1 ==
"C" && elem2 ==
"C"))
342 RDC_type = RDC_TYPE_CC;
344 throw(utility::excn::EXCN_BadInput(
345 "unknown combination of atoms for RDC " + atom1 +
" " + atom2));
404 tr.Debug <<
"wRDC: iter wsum wRDC" << std::endl;
407 while (std::abs(wsum_old - wsum) > tolerance) {
413 Real dev = it->Jcomputed() - it->Jdipolar();
414 it->weight(exp(-dev * dev / sigma2));
415 wsum += it->weight() * invn;
416 wMSD += it->weight() * dev * dev;
418 tr.Debug <<
"wRMSD: " << ++ct <<
" " << wsum <<
" " << sqrt(wMSD)
421 tr.Warning <<
"no convergence in wRDC aka iterate_tensor_weights"
436 bool const correct_NH( basic::options::option[basic::options::OptionKeys::rdc::correct_NH_length]);
437 bool const bReduced( basic::options::option[basic::options::OptionKeys::rdc::reduced_couplings]);
442 for (
Size i = 0; i < 5; i++) {
444 for (
Size j = 0; j <= i; j++) {
452 tr.Warning <<
"non-existing residue, ignore RDC" << std::endl;
456 if ( it->res1() == 1 || it->res2() == 1 ) {
457 tr.Warning <<
"residue 1, always problematic with 1H vs H, just ignore RDC" << std::endl;
463 if ((ft.is_cutpoint(std::min((
int) it->res1(), (
int) it->res2())))
464 && it->res1() != it->res2()) {
465 tr.Warning <<
"cutpoint: ignore RDC " << *it << std::endl;
480 invr = 1.0 / sqrt(r2);
486 pfac *= invr * invr * invr;
488 Size const d(nrow - 1);
493 D_[d][0] = pfac * (2* r [0] * r[0] + r[1] * r[1] - r.norm_squared());
494 D_[d][1] = pfac * (2* r [0] * r[1]);
495 D_[d][2] = pfac * (2* r [0] * r[2]);
496 D_[d][3] = pfac * (2* r [1] * r[1] + r[0] * r[0] - r.norm_squared());
497 D_[d][4] = pfac * (2* r [1] * r[2]);
508 for (
Size i = 0; i < 5; i++) {
509 rhs_[ex][i] += D_[d][i] * obs * weight;
510 for (
Size j = 0; j <= i; j++)
511 T_[ex][i][j] += D_[d][i] * D_[d][j] * weight;
516 runtime_assert( nex_ < 200 );
518 for (
Size ex = 0; ex <
nex_; ex++) {
521 for (
Size i = 0; i < 5; i++) {
522 for (
Size j = 0; j < i; j++) {
523 T_[ex][j][i] =
T_[ex][i][j];
531 }
catch (utility::excn::EXCN_BadInput &excn) {
544 for (
Size i = 0; i < 5; i++) {
545 S_[ex][0][0] +=
T_[ex][0][i] *
rhs_[ex][i];
546 S_[ex][0][1] +=
T_[ex][1][i] * rhs_[ex][i];
547 S_[ex][0][2] +=
T_[ex][2][i] * rhs_[ex][i];
548 S_[ex][1][1] +=
T_[ex][3][i] * rhs_[ex][i];
549 S_[ex][1][2] +=
T_[ex][4][i] * rhs_[ex][i];
551 S_[ex][1][0] =
S_[ex][0][1];
552 S_[ex][2][0] =
S_[ex][0][2];
553 S_[ex][2][1] =
S_[ex][1][2];
554 S_[ex][2][2] = -
S_[ex][0][0] -
S_[ex][1][1];
563 using namespace basic::options;
565 if ( option[ OptionKeys::rdc::fix_normAzz ].user() ) {
566 if ( option[ OptionKeys::rdc::fix_normAzz ]().
size() != nex_ ) {
567 utility_exit_with_message(
"fix_normAzz must have one value for each alignment medium !");
569 Smax[ ex ] = option[ OptionKeys::rdc::fix_normAzz ]()[ ex+1 ];
573 tr.Debug <<
"Smax( " << ex <<
" ): " << Smax[ex] << std::endl;
585 }
catch (utility::excn::EXCN_BadInput &excn) {
586 if (
tr.Debug.visible() ) {
610 tr.Warning <<
"non-existing residue, ignore RDC" << *it << std::endl;
613 if ((ft.is_cutpoint(std::min((
int) it->res1(), (
int) it->res2())))
614 && it->res1() != it->res2()) {
615 tr.Warning <<
"cutpoint: ignore RDC " << *it << std::endl;
618 if ( it->res1() == 1 || it->res2() == 1 ) {
619 tr.Warning <<
"residue 1, always problematic with 1H vs H, just ignore RDC" << std::endl;
625 Size const d(irow - 1);
629 Real computed_coupling = it->Jdipolar_computed_ =
S_[ex][0][0] *
D_[d][0] +
S_[ex][0][1] *
D_[d][1] +
S_[ex][0][2] *
D_[d][2] +
S_[ex][1][1] *
D_[d][3] +
S_[ex][1][2] *
D_[d][4];
640 Real obs = it->Jdipolar();
641 Real dev = computed_coupling - obs;
642 Real weight = it->weight()*Smax[ex];
647 core::Real const pfac_NH = weight * 36.5089/1.041/1.041/1.041;
650 if (
tr.Trace.visible() )
tr.Trace <<
"reducing coupling for " << rdc <<
" dev: " << dev
651 <<
" pfac: " << pfac <<
" pfac_NH " << pfac_NH;
653 dev *= pfac_NH / pfac;
654 obs *= pfac_NH / pfac;
655 if (
tr.Trace.visible() )
tr.Trace <<
" new dev: " << dev << std::endl;
667 rdc.
fij_[0]= -dev * pfac * (
S_[ex][0][0]*2*r.x()+
S_[ex][0][1]*2*r.y()+
S_[ex][0][2]*2*r.z()+
S_[ex][1][1]*0+
S_[ex][1][2]*0);
668 rdc.
fij_[1]= -dev * pfac * (
S_[ex][0][0]*0+
S_[ex][0][1]*2*r.x()+
S_[ex][0][2]*0+
S_[ex][1][1]*2*r.y()+
S_[ex][1][2]*2*r.z());
669 rdc.
fij_[2]= -dev * pfac * (-
S_[ex][0][0]*2*r.z()+
S_[ex][0][1]*0+
S_[ex][0][2]*2*r.x()-
S_[ex][1][1]*2*r.z()+
S_[ex][1][2]*2*r.y());
686 vtot += 0.5*
sqr( dev )*weight;
690 wsv2 += weight*
sqr(dev);
699 R_ = sqrt( Q/Qnorm/2 );
700 rmsd_ = sqrt(wsv2/sw);
711 using namespace basic::options;
712 using namespace basic::options::OptionKeys;
713 using namespace ObjexxFCL;
714 using namespace ObjexxFCL::fmt;
715 if ( option[ OptionKeys::rdc::print_rdc_values ].user() ) {
717 utility::io::ozstream out;
719 out.open_append( filename ) ;
720 using namespace core::pose::datacache;
726 for (
Size ex = 0; ex <
nex_; ex++) {
734 out <<
"//" <<std::endl;
744 double frdc(
double r0,
double r1,
double r2,
double rdcconst,
const double *par)
748 double Az=-par[0]-par[1];
753 double rdcx=0.0,rdcy=0.0,rdcz=0.0;
754 rdcx = cos(b)*cos(c)*r0+(-cos(a)*sin(c)+sin(a)*sin(b)*cos(c))*r1+(sin(a)*sin(c)+cos(a)*sin(b)*cos(c))*r2;
755 rdcy = cos(b)*sin(c)*r0+(cos(a)*cos(c)+sin(a)*sin(b)*sin(c))*r1+(-sin(a)*cos(c)+cos(a)*sin(b)*sin(c))*r2;
756 rdcz = -sin(b)*r0+sin(a)*cos(b)*r1+cos(a)*cos(b)*r2;
757 return rdcconst*(rdcx*rdcx*Ax+rdcy*rdcy*Ay+rdcz*rdcz*Az);
760 double frdcDa(
double r0,
double r1,
double r2,
double rdcconst,
double const tensorDa,
const double *par)
762 double Ax=(3.0*par[0]/2.0-1.0)*tensorDa/(36.5089/1.041/1.041/1.041);
763 double Ay=-(3.0*par[0]/2.0+1.0)*tensorDa/(36.5089/1.041/1.041/1.041);
764 double Az=2.0*tensorDa/(36.5089/1.041/1.041/1.041);
769 double rdcx=0.0,rdcy=0.0,rdcz=0.0;
770 rdcx = cos(b)*cos(c)*r0+(-cos(a)*sin(c)+sin(a)*sin(b)*cos(c))*r1+(sin(a)*sin(c)+cos(a)*sin(b)*cos(c))*r2;
771 rdcy = cos(b)*sin(c)*r0+(cos(a)*cos(c)+sin(a)*sin(b)*sin(c))*r1+(-sin(a)*cos(c)+cos(a)*sin(b)*sin(c))*r2;
772 rdcz = -sin(b)*r0+sin(a)*cos(b)*r1+cos(a)*cos(b)*r2;
773 return rdcconst*(rdcx*rdcx*Ax+rdcy*rdcy*Ay+rdcz*rdcz*Az);
776 double frdcR(
double r0,
double r1,
double r2,
double rdcconst,
double const tensorR,
const double *par)
778 double Ax=(3.0*tensorR/2.0-1.0)*par[0]/(36.5089/1.041/1.041/1.041);
779 double Ay=-(3.0*tensorR/2.0+1.0)*par[0]/(36.5089/1.041/1.041/1.041);
780 double Az=2.0*par[0]/(36.5089/1.041/1.041/1.041);
785 double rdcx=0.0,rdcy=0.0,rdcz=0.0;
786 rdcx = cos(b)*cos(c)*r0+(-cos(a)*sin(c)+sin(a)*sin(b)*cos(c))*r1+(sin(a)*sin(c)+cos(a)*sin(b)*cos(c))*r2;
787 rdcy = cos(b)*sin(c)*r0+(cos(a)*cos(c)+sin(a)*sin(b)*sin(c))*r1+(-sin(a)*cos(c)+cos(a)*sin(b)*sin(c))*r2;
788 rdcz = -sin(b)*r0+sin(a)*cos(b)*r1+cos(a)*cos(b)*r2;
789 return rdcconst*(rdcx*rdcx*Ax+rdcy*rdcy*Ay+rdcz*rdcz*Az);
792 double frdcDaR(
double r0,
double r1,
double r2,
double rdcconst,
double const tensorDa,
double const tensorR,
const double *par)
794 double Ax=(3.0*tensorR/2.0-1.0)*tensorDa/(36.5089/1.041/1.041/1.041);
795 double Ay=-(3.0*tensorR/2.0+1.0)*tensorDa/(36.5089/1.041/1.041/1.041);
796 double Az=2.0*tensorDa/(36.5089/1.041/1.041/1.041);
801 double rdcx=0.0,rdcy=0.0,rdcz=0.0;
802 rdcx = cos(b)*cos(c)*r0+(-cos(a)*sin(c)+sin(a)*sin(b)*cos(c))*r1+(sin(a)*sin(c)+cos(a)*sin(b)*cos(c))*r2;
803 rdcy = cos(b)*sin(c)*r0+(cos(a)*cos(c)+sin(a)*sin(b)*sin(c))*r1+(-sin(a)*cos(c)+cos(a)*sin(b)*sin(c))*r2;
804 rdcz = -sin(b)*r0+sin(a)*cos(b)*r1+cos(a)*cos(b)*r2;
805 return rdcconst*(rdcx*rdcx*Ax+rdcy*rdcy*Ay+rdcz*rdcz*Az);
810 double *r0, *r1, *
r2;
814 double (*
frdc)(
double r0,
double r1,
double r2,
double rdcconst,
const double *par );
818 double *r0, *r1, *
r2;
823 double (*
frdcDa)(
double r0,
double r1,
double r2,
double rdcconst,
double const tensorDa,
const double *par );
827 double *r0, *r1, *
r2;
832 double (*
frdcR)(
double r0,
double r1,
double r2,
double rdcconst,
double const tensorR,
const double *par );
836 double *r0, *r1, *
r2;
842 double (*
frdcDaR)(
double r0,
double r1,
double r2,
double rdcconst,
double const tensorDa,
double const tensorR,
const double *par );
846 void evaluaterdc(
const double *par,
int m_dat,
const void *data,
double *fvec,
int * ) {
850 for ( i = 0; i < m_dat; i++ ) {
855 void evaluaterdcDa(
const double *par,
int m_dat,
const void *data,
double *fvec,
int * ) {
859 for ( i = 0; i < m_dat; i++ ) {
864 void evaluaterdcR(
const double *par,
int m_dat,
const void *data,
double *fvec,
int * ) {
868 for ( i = 0; i < m_dat; i++ ) {
873 void evaluaterdcDaR(
const double *par,
int m_dat,
const void *data,
double *fvec,
int * ) {
877 for ( i = 0; i < m_dat; i++ ) {
888 bool const correct_NH( basic::options::option[basic::options::OptionKeys::rdc::correct_NH_length]);
894 for (
id = 0;
id <
nex_+1;
id++) {
899 core::Real scale_to_NH = 36.5089/1.041/1.041/1.041;
903 if (
tr.Debug.visible() )
tr.Debug <<
"non-existing residue, ignore RDC" << std::endl;
909 if ((ft.is_cutpoint(std::min((
int) it->res1(), (
int) it->res2()))) && it->res1() != it->res2()) {
910 if (
tr.Trace.visible() )
tr.Trace <<
"cutpoint: ignore RDC " << *it << std::endl;
924 scale_to_NH = 36.5089/1.041/1.041/1.041;
927 r2 = r.norm_squared();
928 invr = 1.0 / sqrt(r2);
929 }
else if ( it->type() ==
RDC::RDC_TYPE_NC && std::abs((
int) it->res1()-(
int) it->res2())==1 ) {
931 r2 = r.norm_squared();
932 invr = 1.0 / sqrt(r2);
933 }
else if ( it->type() ==
RDC::RDC_TYPE_CH && std::abs((
int) it->res1()-(
int) it->res2())==0 ) {
935 r2 = r.norm_squared();
936 invr = 1.0 / sqrt(r2);
937 }
else if ( it->type() ==
RDC::RDC_TYPE_CC && std::abs((
int) it->res1()-(
int) it->res2())==0 ) {
939 r2 = r.norm_squared();
940 invr = 1.0 / sqrt(r2);
942 tr.Error <<
"unreognized type or residue sequence separation does not allow using correct_NH" << std::endl;
943 throw( utility::excn::EXCN_BadInput(
"unreognized type or residue sequence separation does not allow using correct_NH "));
951 pfac *= invr * invr * invr;
963 r0_[nrow-1] = r.normalized().x();
964 r1_[nrow-1] = r.normalized().y();
965 r2_[nrow-1] = r.normalized().z();
985 std::vector<double> parbest(n_par*nex_);
988 std::vector<double> par(n_par*nex_);
995 runtime_assert( nex_ < 200 );
999 for (
Size ex = 0; ex <
nex_; ex++) {
1003 for (
Size cnt=0; cnt<=ex; cnt++) {
1010 numeric::nls::lm_status_struct status;
1014 using namespace basic::options;
1015 if ( option[ OptionKeys::rdc::fix_normAzz ].user() ) {
1016 if ( option[ OptionKeys::rdc::fix_normAzz ]().
size() != nex_ ) {
1017 utility_exit_with_message(
"fix_normAzz must have one value for each alignment medium !");
1019 Smax[ ex ] = option[ OptionKeys::rdc::fix_normAzz ]()[ ex+1 ];
1025 for (j = 0; j < nrepeat; j++) {
1027 par[ex*n_par+0]=numeric::random::uniform();
1028 par[ex*n_par+1]=numeric::random::uniform();
1029 par[ex*n_par+2]=2.0*numeric::NumericTraits<Real>::pi()*numeric::random::uniform();
1030 par[ex*n_par+3]=2.0*numeric::NumericTraits<Real>::pi()*numeric::random::uniform();
1031 par[ex*n_par+4]=2.0*numeric::NumericTraits<Real>::pi()*numeric::random::uniform();
1033 numeric::nls::lmmin( n_par, &par[ex*n_par],
lenex_[ex+1], (
const void*) &data,
evaluaterdc, &status,numeric::nls::lm_printout_std);
1034 if (
tr.Trace.visible() ) {
1035 tr.Trace << std::endl;
1036 tr.Trace <<
"Iteration: " << j <<
"status.fnorm:" << status.fnorm <<
"bestnorm: "<< bestnorm << std::endl;
1039 if (status.fnorm < bestnorm) {
1040 bestnorm=status.fnorm;
1041 for (i=0; i<n_par ; i++)
1042 parbest[ex*n_par+i]=par[ex*n_par+i];
1047 for (i=0; i<n_par ; i++)
1048 par[ex*n_par+i]=parbest[ex*n_par+i];
1057 if (parbest[ex*n_par+0]>0) {
1058 if (parbest[ex*n_par+1]>0) {
1059 if (parbest[ex*n_par+0]<parbest[ex*n_par+1]) {
1060 Ax=parbest[ex*n_par+0];
1061 Ay=parbest[ex*n_par+1];
1063 Ax=parbest[ex*n_par+1];
1064 Ay=parbest[ex*n_par+0];
1067 if (parbest[ex*n_par+0]<-parbest[ex*n_par+1]) {
1068 Ax=std::min(parbest[ex*n_par+0],-parbest[ex*n_par+1]-parbest[ex*n_par+0]);
1069 Ay=std::max(parbest[ex*n_par+0],-parbest[ex*n_par+1]-parbest[ex*n_par+0]);
1071 Ax=std::max(parbest[ex*n_par+1],-parbest[ex*n_par+1]-parbest[ex*n_par+0]);
1072 Ay=std::min(parbest[ex*n_par+1],-parbest[ex*n_par+1]-parbest[ex*n_par+0]);
1076 if (parbest[ex*n_par+1]>0) {
1077 if (-parbest[ex*n_par+0]<parbest[ex*n_par+1]) {
1078 Ax=std::max(parbest[ex*n_par+0],-parbest[ex*n_par+1]-parbest[ex*n_par+0]);
1079 Ay=std::min(parbest[ex*n_par+0],-parbest[ex*n_par+1]-parbest[ex*n_par+0]);
1081 Ax=std::min(parbest[ex*n_par+1],-parbest[ex*n_par+1]-parbest[ex*n_par+0]);
1082 Ay=std::max(parbest[ex*n_par+1],-parbest[ex*n_par+1]-parbest[ex*n_par+0]);
1085 if (parbest[ex*n_par+0]<parbest[ex*n_par+1]) {
1086 Ax=parbest[ex*n_par+1];
1087 Ay=parbest[ex*n_par+0];
1089 Ax=parbest[ex*n_par+0];
1090 Ay=parbest[ex*n_par+1];
1095 parbest[ex*n_par+0]=1.0/2.0*(-Ax-Ay);
1096 parbest[ex*n_par+1]=2.0/3.0*(Ay-Ax)/(Ax+Ay);
1098 if (
tr.Trace.visible() ) {
1100 tr.Trace << std::endl;
1101 tr.Trace <<
"ex: " << ex << std::endl;
1102 tr.Trace <<
"Ax: " << Ax << std::endl;
1103 tr.Trace <<
"Ay: " << Ay << std::endl;
1104 tr.Trace <<
"alpha: " << par[ex*n_par+2]*180/numeric::NumericTraits<Real>::pi()<< std::endl;
1105 tr.Trace <<
"beta: " << par[ex*n_par+3]*180/numeric::NumericTraits<Real>::pi()<< std::endl;
1106 tr.Trace <<
"gamma:" << par[ex*n_par+4]*180/numeric::NumericTraits<Real>::pi()<< std::endl;
1107 tr.Trace <<
"Da:" << 1.0/2.0*(-Ax-Ay)*(36.5089/1.041/1.041/1.041)<< std::endl;
1108 tr.Trace <<
"R:" << 2.0/3.0*(Ay-Ax)/(Ax+Ay)<< std::endl;
1109 tr.Trace <<
"norm:" << bestnorm<<std::endl;
1110 tr.Trace <<
"Pales Da:" << 3.0/4.0*(-Ax-Ay)<< std::endl;
1111 tr.Trace <<
"Pales Dr:" << 1.0/2.0*(Ax-Ay)<< std::endl;
1127 Size ex = it->expid();
1133 for (
Size cnt=0; cnt<=ex; cnt++) {
1149 r2 = r.norm_squared();
1150 invr = 1.0 / sqrt(r2);
1151 }
else if ( it->type() ==
RDC::RDC_TYPE_NC && std::abs((
int) it->res1()-(
int) it->res2())==1 ) {
1153 r2 = r.norm_squared();
1154 invr = 1.0 / sqrt(r2);
1155 }
else if ( it->type() ==
RDC::RDC_TYPE_CH && std::abs((
int) it->res1()-(
int) it->res2())==0 ) {
1157 r2 = r.norm_squared();
1158 invr = 1.0 / sqrt(r2);
1159 }
else if ( it->type() ==
RDC::RDC_TYPE_CC && std::abs((
int) it->res1()-(
int) it->res2())==0 ) {
1161 r2 = r.norm_squared();
1162 invr = 1.0 / sqrt(r2);
1164 tr.Error <<
"unreognized type or residue sequence separation does not allow using correct_NH" << std::endl;
1165 throw( utility::excn::EXCN_BadInput(
"unreognized type or residue sequence separation does not allow using correct_NH "));
1172 Real weight = it->weight()*Smax[ex];
1174 core::Real pfac = scale_to_NH*(1/r.length())*(1/r_copy.length())*weight;
1176 Real dev = computed_coupling - obs;
1178 it->Jdipolar_computed_ = computed_coupling/((scale_to_NH)/(rdc.
Dconst() * invr2 * invr));
1183 core::Real Azz=-par[ex*n_par+0]-par[ex*n_par+1];
1189 core::Real r01=-cos(a)*sin(c)+sin(a)*sin(b)*cos(c);
1190 core::Real r02=sin(a)*sin(c)+cos(a)*sin(b)*cos(c);
1192 core::Real r11=cos(a)*cos(c)+sin(a)*sin(b)*sin(c);
1193 core::Real r12=-sin(a)*cos(c)+cos(a)*sin(b)*sin(c);
1201 rdc.
fij_[0] = - dev * pfac * 2 * (Axx*rx*r00+Ayy*ry*r10+Azz*rz*r20) ;
1202 rdc.
fij_[1] = - dev * pfac * 2 * (Axx*rx*r01+Ayy*ry*r11+Azz*rz*r21);
1203 rdc.
fij_[2] = - dev * pfac * 2 * (Axx*rx*r02+Ayy*ry*r12+Azz*rz*r22) ;
1214 vtot += 0.5*
sqr( dev )*weight;
1245 wsv2 += weight*
sqr(dev);
1250 Qnorm +=
sqr( obs );
1253 if ( irow==
lenex_[ex+1]-1 ) {
1254 if (
tr.Trace.visible() ) {
1255 tr.Trace <<
"ex: " << ex <<
" Qbax: " << sqrt(Qex/
lenex_[ex+1])/sqrt(
sqr(parbest[ex*n_par+0]*(36.5089/1.041/1.041/1.041))*(4+3*
sqr(parbest[ex*n_par+1]))/5) << std::endl;
1256 tr.Trace <<
"ex: " << ex <<
" rms: " << sqrt(Qex/
lenex_[ex+1]) << std::endl;
1265 if (irow<
lenex_[ex+1]-1) {
1274 R_ = sqrt( Q/Qnorm/2 );
1275 rmsd_ = sqrt(wsv2/sw);
1277 if (
tr.Trace.visible() ) {
1278 tr.Trace <<
"R_: " <<
R_ << std::endl;
1279 tr.Trace <<
"Q_: " << sqrt(2.)*
R_ << std::endl;
1280 tr.Trace <<
"rmsd_: " <<
rmsd_ << std::endl;
1281 tr.Trace <<
"All_RDC_lines_.size(): " <<
All_RDC_lines_.size() << std::endl;
1284 using namespace basic::options;
1285 using namespace basic::options::OptionKeys;
1286 using namespace ObjexxFCL;
1287 using namespace ObjexxFCL::fmt;
1290 if ( option[ OptionKeys::rdc::print_rdc_values ].user() ) {
1292 utility::io::ozstream out;
1294 out.open_append( filename ) ;
1295 using namespace core::pose::datacache;
1299 for (
Size ex = 0; ex <
nex_; ex++) {
1303 out <<
"//" <<std::endl;
1316 bool const correct_NH( basic::options::option[basic::options::OptionKeys::rdc::correct_NH_length]);
1322 for (
id = 0;
id <
nex_+1;
id++) {
1327 core::Real scale_to_NH = 36.5089/1.041/1.041/1.041;
1330 if (
tr.Debug.visible() )
tr.Debug <<
"non-existing residue, ignore RDC" << std::endl;
1336 if ((ft.is_cutpoint(std::min((
int) it->res1(), (
int) it->res2()))) && it->res1() != it->res2()) {
1337 if (
tr.Trace.visible() )
tr.Trace <<
"cutpoint: ignore RDC " << *it << std::endl;
1348 scale_to_NH = 36.5089/1.041/1.041/1.041;
1351 r2 = r.norm_squared();
1352 invr = 1.0 / sqrt(r2);
1353 }
else if ( it->type() ==
RDC::RDC_TYPE_NC && std::abs((
int) it->res1()-(
int) it->res2())==1 ) {
1355 r2 = r.norm_squared();
1356 invr = 1.0 / sqrt(r2);
1357 }
else if ( it->type() ==
RDC::RDC_TYPE_CH && std::abs((
int) it->res1()-(
int) it->res2())==0 ) {
1359 r2 = r.norm_squared();
1360 invr = 1.0 / sqrt(r2);
1361 }
else if ( it->type() ==
RDC::RDC_TYPE_CC && std::abs((
int) it->res1()-(
int) it->res2())==0 ) {
1363 r2 = r.norm_squared();
1364 invr = 1.0 / sqrt(r2);
1366 tr.Error <<
"unreognized type or residue sequence separation does not allow using correct_NH" << std::endl;
1367 throw( utility::excn::EXCN_BadInput(
"unreognized type or residue sequence separation does not allow using correct_NH "));
1374 pfac *= invr * invr * invr;
1381 r0_[nrow-1] = r.normalized().x();
1382 r1_[nrow-1] = r.normalized().y();
1383 r2_[nrow-1] = r.normalized().z();
1396 std::vector<double> parbest(n_par*nex_);
1399 std::vector<double> par(n_par*nex_);
1407 runtime_assert( nex_ < 200 );
1411 for (
Size ex = 0; ex <
nex_; ex++) {
1414 for (
Size cnt=0; cnt<=ex; cnt++) {
1421 numeric::nls::lm_status_struct status;
1425 using namespace basic::options;
1426 if ( option[ OptionKeys::rdc::fix_normAzz ].user() ) {
1427 if ( option[ OptionKeys::rdc::fix_normAzz ]().
size() != nex_ ) {
1428 utility_exit_with_message(
"fix_normAzz must have one value for each alignment medium !");
1430 Smax[ ex ] = option[ OptionKeys::rdc::fix_normAzz ]()[ ex+1 ];
1436 for (j = 0; j < nrepeat; j++) {
1438 par[ex*n_par+0]=numeric::random::uniform();
1439 par[ex*n_par+1]=2.0*numeric::NumericTraits<Real>::pi()*numeric::random::uniform();
1440 par[ex*n_par+2]=2.0*numeric::NumericTraits<Real>::pi()*numeric::random::uniform();
1441 par[ex*n_par+3]=2.0*numeric::NumericTraits<Real>::pi()*numeric::random::uniform();
1443 numeric::nls::lmmin( n_par, &par[ex*n_par],
lenex_[ex+1], (
const void*) &data,
evaluaterdcDa, &status,numeric::nls::lm_printout_std);
1444 if (
tr.Trace.visible() ) {
1445 tr.Trace << std::endl;
1446 tr.Trace <<
"Iteration: " << j <<
"status.fnorm:" << status.fnorm <<
"bestnorm: "<< bestnorm << std::endl;
1449 if (status.fnorm < bestnorm) {
1450 bestnorm=status.fnorm;
1451 for (i=0; i<n_par ; i++)
1452 parbest[ex*n_par+i]=par[ex*n_par+i];
1456 for (i=0; i<n_par ; i++)
1457 par[ex*n_par+i]=parbest[ex*n_par+i];
1460 if (
tr.Trace.visible() ) {
1461 tr.Trace << std::endl;
1462 tr.Trace <<
"ex: " << ex << std::endl;
1463 tr.Trace <<
"Ax: " << (3.0*par[ex*n_par+0]/2.0-1.0)*tensorDa[ex+1]/(36.5089/1.041/1.041/1.041)<< std::endl;
1464 tr.Trace <<
"Ay: " << -(3.0*par[ex*n_par+0]/2.0+1.0)*tensorDa[ex+1]/(36.5089/1.041/1.041/1.041)<< std::endl;
1465 tr.Trace <<
"alpha: " << par[ex*n_par+1]<< std::endl;
1466 tr.Trace <<
"beta: " << par[ex*n_par+2]<< std::endl;
1467 tr.Trace <<
"gamma:" << par[ex*n_par+3]<< std::endl;
1468 tr.Trace <<
"norm:" << bestnorm<<std::endl;
1484 Size ex = it->expid();
1488 for (
Size cnt=0; cnt<=ex; cnt++) {
1492 Real computed_coupling =
frdcDa(
r0_[prelen+irow],
r1_[prelen+irow],
r2_[prelen+irow],
rdcconst_[prelen+irow], tensorDa[ex+1], &par[ex*n_par]);
1504 r2 = r.norm_squared();
1505 invr = 1.0 / sqrt(r2);
1506 }
else if ( it->type() ==
RDC::RDC_TYPE_NC && std::abs((
int) it->res1()-(
int) it->res2())==1 ) {
1508 r2 = r.norm_squared();
1509 invr = 1.0 / sqrt(r2);
1510 }
else if ( it->type() ==
RDC::RDC_TYPE_CH && std::abs((
int) it->res1()-(
int) it->res2())==0 ) {
1512 r2 = r.norm_squared();
1513 invr = 1.0 / sqrt(r2);
1514 }
else if ( it->type() ==
RDC::RDC_TYPE_CC && std::abs((
int) it->res1()-(
int) it->res2())==0 ) {
1516 r2 = r.norm_squared();
1517 invr = 1.0 / sqrt(r2);
1519 tr.Error <<
"unreognized type or residue sequence separation does not allow using correct_NH" << std::endl;
1520 throw( utility::excn::EXCN_BadInput(
"unreognized type or residue sequence separation does not allow using correct_NH "));
1527 Real weight = it->weight()*Smax[ex];
1529 core::Real pfac = scale_to_NH*(1/r.length())*(1/r_copy.length())*weight;
1531 Real dev = computed_coupling - obs;
1532 it->Jdipolar_computed_ = computed_coupling/((scale_to_NH)/(rdc.
Dconst() * invr2 * invr));
1535 core::Real Axx=(3.0*par[ex*n_par+0]/2.0-1.0)*tensorDa[ex+1]/(36.5089/1.041/1.041/1.041);
1536 core::Real Ayy=-(3.0*par[ex*n_par+0]/2.0+1.0)*tensorDa[ex+1]/(36.5089/1.041/1.041/1.041);
1537 core::Real Azz=2.0*tensorDa[ex+1]/(36.5089/1.041/1.041/1.041);
1543 core::Real r01=-cos(a)*sin(c)+sin(a)*sin(b)*cos(c);
1544 core::Real r02=sin(a)*sin(c)+cos(a)*sin(b)*cos(c);
1546 core::Real r11=cos(a)*cos(c)+sin(a)*sin(b)*sin(c);
1547 core::Real r12=-sin(a)*cos(c)+cos(a)*sin(b)*sin(c);
1556 rdc.
fij_[0] = - dev * pfac * 2 * (Axx*rx*r00+Ayy*ry*r10+Azz*rz*r20) ;
1557 rdc.
fij_[1] = - dev * pfac * 2 * (Axx*rx*r01+Ayy*ry*r11+Azz*rz*r21);
1558 rdc.
fij_[2] = - dev * pfac * 2 * (Axx*rx*r02+Ayy*ry*r12+Azz*rz*r22) ;
1561 vtot += 0.5*
sqr( dev )*weight;
1566 wsv2 += weight*
sqr(dev);
1570 Qnorm +=
sqr( obs );
1573 if ( irow==
lenex_[ex+1]-1 ) {
1574 if (
tr.Trace.visible() ) {
1575 tr.Trace <<
"ex: " << ex <<
" Qbax_: " << sqrt(Qex/
lenex_[ex+1])/sqrt(
sqr(tensorDa[ex+1])*(4+3*
sqr(par[ex*n_par+0]))/5) << std::endl;
1576 tr.Trace <<
"ex: " << ex <<
" rms_dc: " << sqrt(Qex/
lenex_[ex+1]) << std::endl;
1583 if (irow<
lenex_[ex+1]-1) {
1591 R_ = sqrt( Q/Qnorm/2 );
1592 rmsd_ = sqrt(wsv2/sw);
1594 if (
tr.Trace.visible() ) {
1595 tr.Trace <<
"R_: " <<
R_ << std::endl;
1596 tr.Trace <<
"rmsd_: " <<
rmsd_ << std::endl;
1597 tr.Trace <<
"All_RDC_lines_.size(): " <<
All_RDC_lines_.size() << std::endl;
1600 using namespace basic::options;
1601 using namespace basic::options::OptionKeys;
1602 using namespace ObjexxFCL;
1603 using namespace ObjexxFCL::fmt;
1606 if ( option[ OptionKeys::rdc::print_rdc_values ].user() ) {
1608 utility::io::ozstream out;
1610 out.open_append( filename ) ;
1611 using namespace core::pose::datacache;
1615 for (
Size ex = 0; ex <
nex_; ex++) {
1618 out <<
"//" <<std::endl;
1631 bool const correct_NH( basic::options::option[basic::options::OptionKeys::rdc::correct_NH_length]);
1637 for (
id = 0;
id <
nex_+1;
id++) {
1642 core::Real scale_to_NH = 36.5089/1.041/1.041/1.041;
1646 if (
tr.Debug.visible() )
tr.Debug <<
"non-existing residue, ignore RDC" << std::endl;
1652 if ((ft.is_cutpoint(std::min((
int) it->res1(), (
int) it->res2()))) && it->res1() != it->res2()) {
1653 if (
tr.Trace.visible() )
tr.Trace <<
"cutpoint: ignore RDC " << *it << std::endl;
1664 scale_to_NH = 36.5089/1.041/1.041/1.041;
1667 r2 = r.norm_squared();
1668 invr = 1.0 / sqrt(r2);
1669 }
else if ( it->type() ==
RDC::RDC_TYPE_NC && std::abs((
int) it->res1()-(
int) it->res2())==1 ) {
1671 r2 = r.norm_squared();
1672 invr = 1.0 / sqrt(r2);
1673 }
else if ( it->type() ==
RDC::RDC_TYPE_CH && std::abs((
int) it->res1()-(
int) it->res2())==0 ) {
1675 r2 = r.norm_squared();
1676 invr = 1.0 / sqrt(r2);
1677 }
else if ( it->type() ==
RDC::RDC_TYPE_CC && std::abs((
int) it->res1()-(
int) it->res2())==0 ) {
1679 r2 = r.norm_squared();
1680 invr = 1.0 / sqrt(r2);
1682 tr.Error <<
"unreognized type or residue sequence separation does not allow using correct_NH" << std::endl;
1683 throw( utility::excn::EXCN_BadInput(
"unreognized type or residue sequence separation does not allow using correct_NH "));
1690 pfac *= invr * invr * invr;
1697 r0_[nrow-1] = r.normalized().x();
1698 r1_[nrow-1] = r.normalized().y();
1699 r2_[nrow-1] = r.normalized().z();
1712 std::vector<double> parbest(n_par*nex_);
1713 std::vector<double> par(n_par*nex_);
1720 runtime_assert( nex_ < 200 );
1724 for (
Size ex = 0; ex <
nex_; ex++) {
1728 for (
Size cnt=0; cnt<=ex; cnt++) {
1734 numeric::nls::lm_status_struct status;
1738 using namespace basic::options;
1739 if ( option[ OptionKeys::rdc::fix_normAzz ].user() ) {
1740 if ( option[ OptionKeys::rdc::fix_normAzz ]().
size() != nex_ ) {
1741 utility_exit_with_message(
"fix_normAzz must have one value for each alignment medium !");
1743 Smax[ ex ] = option[ OptionKeys::rdc::fix_normAzz ]()[ ex+1 ];
1749 for (j = 0; j < nrepeat; j++) {
1751 par[ex*n_par+0]=numeric::random::uniform();
1752 par[ex*n_par+1]=2.0*numeric::NumericTraits<Real>::pi()*numeric::random::uniform();
1753 par[ex*n_par+2]=2.0*numeric::NumericTraits<Real>::pi()*numeric::random::uniform();
1754 par[ex*n_par+3]=2.0*numeric::NumericTraits<Real>::pi()*numeric::random::uniform();
1756 numeric::nls::lmmin( n_par, &par[ex*n_par],
lenex_[ex+1], (
const void*) &data,
evaluaterdcR, &status,numeric::nls::lm_printout_std);
1757 if (
tr.Trace.visible() ) {
1758 tr.Trace << std::endl;
1759 tr.Trace <<
"Iteration: " << j <<
"status.fnorm:" << status.fnorm <<
"bestnorm: "<< bestnorm << std::endl;
1762 if (status.fnorm < bestnorm) {
1763 bestnorm=status.fnorm;
1764 for (i=0; i<n_par ; i++)
1765 parbest[ex*n_par+i]=par[ex*n_par+i];
1769 for (i=0; i<n_par ; i++)
1770 par[ex*n_par+i]=parbest[ex*n_par+i];
1773 if (
tr.Trace.visible() ) {
1774 tr.Trace << std::endl;
1775 tr.Trace <<
"ex: " << ex << std::endl;
1776 tr.Trace <<
"Ax: " << (3.0*tensorR[ex+1]/2.0-1.0)*par[ex*n_par+0]/(36.5089/1.041/1.041/1.041)<< std::endl;
1777 tr.Trace <<
"Ay: " << -(3.0*tensorR[ex+1]/2.0+1.0)*par[ex*n_par+0]/(36.5089/1.041/1.041/1.041)<< std::endl;
1778 tr.Trace <<
"alpha: " << par[ex*n_par+1]<< std::endl;
1779 tr.Trace <<
"beta: " << par[ex*n_par+2]<< std::endl;
1780 tr.Trace <<
"gamma:" << par[ex*n_par+3]<< std::endl;
1781 tr.Trace <<
"norm:" << bestnorm<<std::endl;
1796 Size ex = it->expid();
1801 for (
Size cnt=0; cnt<=ex; cnt++) {
1805 Real computed_coupling =
frdcR(
r0_[prelen+irow],
r1_[prelen+irow],
r2_[prelen+irow],
rdcconst_[prelen+irow], tensorR[ex+1], &par[ex*n_par]);
1817 r2 = r.norm_squared();
1818 invr = 1.0 / sqrt(r2);
1819 }
else if ( it->type() ==
RDC::RDC_TYPE_NC && std::abs((
int) it->res1()-(
int) it->res2())==1 ) {
1821 r2 = r.norm_squared();
1822 invr = 1.0 / sqrt(r2);
1823 }
else if ( it->type() ==
RDC::RDC_TYPE_CH && std::abs((
int) it->res1()-(
int) it->res2())==0 ) {
1825 r2 = r.norm_squared();
1826 invr = 1.0 / sqrt(r2);
1827 }
else if ( it->type() ==
RDC::RDC_TYPE_CC && std::abs((
int) it->res1()-(
int) it->res2())==0 ) {
1829 r2 = r.norm_squared();
1830 invr = 1.0 / sqrt(r2);
1832 tr.Error <<
"unreognized type or residue sequence separation does not allow using correct_NH" << std::endl;
1833 throw( utility::excn::EXCN_BadInput(
"unreognized type or residue sequence separation does not allow using correct_NH "));
1839 Real weight = it->weight()*Smax[ex];
1841 core::Real pfac = scale_to_NH*(1/r.length())*(1/r_copy.length())*weight;
1843 Real dev = computed_coupling - obs;
1844 it->Jdipolar_computed_ = computed_coupling/((scale_to_NH)/(rdc.
Dconst() * invr2 * invr));
1847 core::Real Axx=(3.0*tensorR[ex+1]/2.0-1.0)*par[ex*n_par+0]/(36.5089/1.041/1.041/1.041);
1848 core::Real Ayy=-(3.0*tensorR[ex+1]/2.0+1.0)*par[ex*n_par+0]/(36.5089/1.041/1.041/1.041);
1849 core::Real Azz=2.0*par[ex*n_par+0]/(36.5089/1.041/1.041/1.041);
1855 core::Real r01=-cos(a)*sin(c)+sin(a)*sin(b)*cos(c);
1856 core::Real r02=sin(a)*sin(c)+cos(a)*sin(b)*cos(c);
1858 core::Real r11=cos(a)*cos(c)+sin(a)*sin(b)*sin(c);
1859 core::Real r12=-sin(a)*cos(c)+cos(a)*sin(b)*sin(c);
1868 rdc.
fij_[0] = - dev * pfac * 2 * (Axx*rx*r00+Ayy*ry*r10+Azz*rz*r20) ;
1869 rdc.
fij_[1] = - dev * pfac * 2 * (Axx*rx*r01+Ayy*ry*r11+Azz*rz*r21);
1870 rdc.
fij_[2] = - dev * pfac * 2 * (Axx*rx*r02+Ayy*ry*r12+Azz*rz*r22) ;
1873 vtot += 0.5*
sqr( dev )*weight;
1879 wsv2 += weight*
sqr(dev);
1883 Qnorm +=
sqr( obs );
1886 if ( irow==
lenex_[ex+1]-1 ) {
1887 if (
tr.Trace.visible() ) {
1888 tr.Trace <<
"ex: " << ex <<
" Qbax_: " << sqrt(Qex/
lenex_[ex+1])/sqrt(
sqr(par[ex*n_par+0])*(4+3*
sqr(tensorR[ex+1]))/5) << std::endl;
1889 tr.Trace <<
"ex: " << ex <<
" rms_dc: " << sqrt(Qex/
lenex_[ex+1]) << std::endl;
1896 if (irow<
lenex_[ex+1]-1) {
1904 R_ = sqrt( Q/Qnorm/2 );
1905 rmsd_ = sqrt(wsv2/sw);
1907 if (
tr.Trace.visible() ) {
1908 tr.Trace <<
"R_: " <<
R_ << std::endl;
1909 tr.Trace <<
"rmsd_: " <<
rmsd_ << std::endl;
1910 tr.Trace <<
"All_RDC_lines_.size(): " <<
All_RDC_lines_.size() << std::endl;
1913 using namespace basic::options;
1914 using namespace basic::options::OptionKeys;
1915 using namespace ObjexxFCL;
1916 using namespace ObjexxFCL::fmt;
1919 if ( option[ OptionKeys::rdc::print_rdc_values ].user() ) {
1921 utility::io::ozstream out;
1923 out.open_append( filename ) ;
1924 using namespace core::pose::datacache;
1930 for (
Size ex = 0; ex <
nex_; ex++) {
1933 out <<
"//" <<std::endl;
1946 bool const correct_NH( basic::options::option[basic::options::OptionKeys::rdc::correct_NH_length]);
1952 for (
id = 0;
id <
nex_+1;
id++) {
1957 core::Real scale_to_NH = 36.5089/1.041/1.041/1.041;
1961 if (
tr.Debug.visible() )
tr.Debug <<
"non-existing residue, ignore RDC" << std::endl;
1967 if ((ft.is_cutpoint(std::min((
int) it->res1(), (
int) it->res2()))) && it->res1() != it->res2()) {
1968 if (
tr.Trace.visible() )
tr.Trace <<
"cutpoint: ignore RDC " << *it << std::endl;
1978 scale_to_NH = 36.5089/1.041/1.041/1.041;
1981 r2 = r.norm_squared();
1982 invr = 1.0 / sqrt(r2);
1983 }
else if ( it->type() ==
RDC::RDC_TYPE_NC && std::abs((
int) it->res1()-(
int) it->res2())==1 ) {
1985 r2 = r.norm_squared();
1986 invr = 1.0 / sqrt(r2);
1987 }
else if ( it->type() ==
RDC::RDC_TYPE_CH && std::abs((
int) it->res1()-(
int) it->res2())==0 ) {
1989 r2 = r.norm_squared();
1990 invr = 1.0 / sqrt(r2);
1991 }
else if ( it->type() ==
RDC::RDC_TYPE_CC && std::abs((
int) it->res1()-(
int) it->res2())==0 ) {
1993 r2 = r.norm_squared();
1994 invr = 1.0 / sqrt(r2);
1996 tr.Error <<
"unreognized type or residue sequence separation does not allow using correct_NH" << std::endl;
1997 throw( utility::excn::EXCN_BadInput(
"unreognized type or residue sequence separation does not allow using correct_NH "));
2004 pfac *= invr * invr * invr;
2011 r0_[nrow-1] = r.normalized().x();
2012 r1_[nrow-1] = r.normalized().y();
2013 r2_[nrow-1] = r.normalized().z();
2027 std::vector<double> parbest(n_par*nex_);
2028 std::vector<double> par(n_par*nex_);
2035 runtime_assert( nex_ < 200 );
2039 for (
Size ex = 0; ex <
nex_; ex++) {
2042 for (
Size cnt=0; cnt<=ex; cnt++) {
2049 numeric::nls::lm_status_struct status;
2053 using namespace basic::options;
2054 if ( option[ OptionKeys::rdc::fix_normAzz ].user() ) {
2055 if ( option[ OptionKeys::rdc::fix_normAzz ]().
size() != nex_ ) {
2056 utility_exit_with_message(
"fix_normAzz must have one value for each alignment medium !");
2058 Smax[ ex ] = option[ OptionKeys::rdc::fix_normAzz ]()[ ex+1 ];
2064 for (j = 0; j < nrepeat; j++) {
2066 par[ex*n_par+0]=2.0*numeric::NumericTraits<Real>::pi()*numeric::random::uniform();
2067 par[ex*n_par+1]=2.0*numeric::NumericTraits<Real>::pi()*numeric::random::uniform();
2068 par[ex*n_par+2]=2.0*numeric::NumericTraits<Real>::pi()*numeric::random::uniform();
2070 numeric::nls::lmmin( n_par, &par[ex*n_par],
lenex_[ex+1], (
const void*) &data,
evaluaterdcDaR, &status,numeric::nls::lm_printout_std);
2071 if (
tr.Trace.visible() ) {
2072 tr.Trace << std::endl;
2073 tr.Trace <<
"Iteration: " << j <<
" status.fnorm: " << status.fnorm <<
" bestnorm: "<< bestnorm << std::endl;
2076 if (status.fnorm < bestnorm) {
2077 tr.Trace <<
"status.fnorm: " << status.fnorm <<
" replaced by bestnorm: " << bestnorm << std::endl;
2078 bestnorm=status.fnorm;
2079 for (i=0; i<n_par ; i++)
2080 parbest[ex*n_par+i]=par[ex*n_par+i];
2085 for (i=0; i<n_par ; i++)
2086 par[ex*n_par+i]=parbest[ex*n_par+i];
2089 if (
tr.Trace.visible() ) {
2090 tr.Trace << std::endl;
2091 tr.Trace <<
"ex: " << ex << std::endl;
2092 tr.Trace <<
" tensorDa["<<ex<<
"]: "<<tensorDa[ex+1]<< std::endl;
2093 tr.Trace <<
" tensorR["<<ex<<
"]: "<<tensorR[ex+1]<< std::endl;
2094 tr.Trace <<
"Ax: " << (3.0*tensorR[ex+1]/2.0-1.0)*tensorDa[ex+1]/(36.5089/1.041/1.041/1.041)<< std::endl;
2095 tr.Trace <<
"Ay: " << -(3.0*tensorR[ex+1]/2.0+1.0)*tensorDa[ex+1]/(36.5089/1.041/1.041/1.041)<< std::endl;
2096 tr.Trace <<
"alpha: " << par[ex*n_par+0]<< std::endl;
2097 tr.Trace <<
"beta: " << par[ex*n_par+1]<< std::endl;
2098 tr.Trace <<
"gamma:" << par[ex*n_par+2]<< std::endl;
2099 tr.Trace <<
"norm:" << bestnorm<<std::endl;
2114 Size ex = it->expid();
2118 for (
Size cnt=0; cnt<=ex; cnt++) {
2122 Real computed_coupling =
frdcDaR(
r0_[prelen+irow],
r1_[prelen+irow],
r2_[prelen+irow],
rdcconst_[prelen+irow], tensorDa[ex+1], tensorR[ex+1], &par[ex*n_par]);
2138 r2 = r.norm_squared();
2139 invr = 1.0 / sqrt(r2);
2140 }
else if ( it->type() ==
RDC::RDC_TYPE_NC && std::abs((
int) it->res1()-(
int) it->res2())==1 ) {
2142 r2 = r.norm_squared();
2143 invr = 1.0 / sqrt(r2);
2144 }
else if ( it->type() ==
RDC::RDC_TYPE_CH && std::abs((
int) it->res1()-(
int) it->res2())==0 ) {
2146 r2 = r.norm_squared();
2147 invr = 1.0 / sqrt(r2);
2148 }
else if ( it->type() ==
RDC::RDC_TYPE_CC && std::abs((
int) it->res1()-(
int) it->res2())==0 ) {
2150 r2 = r.norm_squared();
2151 invr = 1.0 / sqrt(r2);
2153 tr.Error <<
"unreognized type or residue sequence separation does not allow using correct_NH" << std::endl;
2154 throw( utility::excn::EXCN_BadInput(
"unreognized type or residue sequence separation does not allow using correct_NH "));
2161 Real weight = it->weight()*Smax[ex];
2162 core::Real pfac = scale_to_NH*(1/r.length())*(1/r_copy.length())*weight;
2164 Real dev = computed_coupling - obs;
2165 it->Jdipolar_computed_ = computed_coupling/((scale_to_NH)/(rdc.
Dconst() * invr2 * invr));
2168 core::Real Axx=(3.0*tensorR[ex+1]/2.0-1.0)*tensorDa[ex+1]/(36.5089/1.041/1.041/1.041);
2169 core::Real Ayy=-(3.0*tensorR[ex+1]/2.0+1.0)*tensorDa[ex+1]/(36.5089/1.041/1.041/1.041);
2170 core::Real Azz=2.0*tensorDa[ex+1]/(36.5089/1.041/1.041/1.041);
2176 core::Real r01=-cos(a)*sin(c)+sin(a)*sin(b)*cos(c);
2177 core::Real r02=sin(a)*sin(c)+cos(a)*sin(b)*cos(c);
2179 core::Real r11=cos(a)*cos(c)+sin(a)*sin(b)*sin(c);
2180 core::Real r12=-sin(a)*cos(c)+cos(a)*sin(b)*sin(c);
2189 rdc.
fij_[0] = - dev * pfac * 2 * (Axx*rx*r00+Ayy*ry*r10+Azz*rz*r20) ;
2190 rdc.
fij_[1] = - dev * pfac * 2 * (Axx*rx*r01+Ayy*ry*r11+Azz*rz*r21);
2191 rdc.
fij_[2] = - dev * pfac * 2 * (Axx*rx*r02+Ayy*ry*r12+Azz*rz*r22) ;
2194 vtot += 0.5*
sqr( dev )*weight;
2197 wsv2 += weight*
sqr(dev);
2201 Qnorm +=
sqr( obs );
2204 if ( irow==
lenex_[ex+1]-1 ) {
2205 if (
tr.Trace.visible() ) {
2206 tr.Trace <<
"ex: " << ex <<
" Qbax_: " << sqrt(Qex/
lenex_[ex+1])/sqrt(
sqr(tensorDa[ex+1])*(4+3*
sqr(tensorR[ex+1]))/5) << std::endl;
2207 tr.Trace <<
"ex: " << ex <<
" rms_dc: " << sqrt(Qex/
lenex_[ex+1]) << std::endl;
2214 if (irow<
lenex_[ex+1]-1) {
2222 R_ = sqrt( Q/Qnorm/2 );
2223 rmsd_ = sqrt(wsv2/sw);
2225 if (
tr.Trace.visible() ) {
2226 tr.Trace <<
"R_: " <<
R_ << std::endl;
2227 tr.Trace <<
"rmsd_: " <<
rmsd_ << std::endl;
2228 tr.Trace <<
"All_RDC_lines_.size(): " <<
All_RDC_lines_.size() << std::endl;
2231 using namespace basic::options;
2232 using namespace basic::options::OptionKeys;
2233 using namespace ObjexxFCL;
2234 using namespace ObjexxFCL::fmt;
2237 if ( option[ OptionKeys::rdc::print_rdc_values ].user() ) {
2239 utility::io::ozstream out;
2241 out.open_append( filename ) ;
2242 using namespace core::pose::datacache;
2246 for (
Size ex = 0; ex <
nex_; ex++) {
2249 out <<
"//" <<std::endl;
2257 using namespace ObjexxFCL;
2258 using namespace ObjexxFCL::fmt;
2263 Size const width( 10 );
2265 Real rhombicity = Ar/Aa;
2266 out <<
A( width,
"Ev[ex][0]" ) <<
" " <<
A( width,
"Ev[ex][1]" ) <<
A( width,
"Ev[ex][2]" ) << std::endl;
2267 out << F( width, precision,
EV_[ex][0] ) << F( width, precision,
EV_[ex][1] ) << F( width, precision,
EV_[ex][2]) << std::endl;
2268 out <<
A( width,
"Aa" ) <<
" " <<
A( width,
"Ar" ) <<
A( width,
"rhombicity" ) << std::endl;
2269 out << F( width, precision, Aa ) << F( width, precision, Ar ) << F( width, precision, rhombicity ) << std::endl;
2273 using namespace ObjexxFCL;
2274 using namespace ObjexxFCL::fmt;
2278 Real Az = -par[0]-par[1];
2279 Size const width( 10 );
2281 out <<
A( width,
"Ax" ) <<
" " <<
A( width,
"Ay" ) <<
A( width,
"Az" ) << std::endl;
2282 out << F( width, precision, Ax ) << F( width, precision, Ay ) << F( width, precision, Az) << std::endl;
2286 using namespace ObjexxFCL;
2287 using namespace ObjexxFCL::fmt;
2289 Size const width( 8 );
2293 out <<
A( width,
"AL.EVAL ") << F(width, precision,
EV_[ex][0]) << F(width, precision,
EV_[ex][1]) << F(width, precision,
EV_[ex][2]) << std::endl
2294 <<
A( width,
"AL.EVEC XX") << F(width, precision,
EIG_[ex][0][0]) << F(width, precision,
EIG_[ex][1][0]) << F(width, precision,
EIG_[ex][2][0]) << std::endl
2295 <<
A( width,
"AL.EVEC YY") << F(width, precision,
EIG_[ex][0][1]) << F(width, precision,
EIG_[ex][1][1]) << F(width, precision,
EIG_[ex][2][1]) << std::endl
2296 <<
A( width,
"AL.EVEC ZZ") << F(width, precision,
EIG_[ex][0][2]) << F(width, precision,
EIG_[ex][1][2]) << F(width, precision,
EIG_[ex][2][2]) << std::endl;
2300 using namespace ObjexxFCL;
2301 using namespace ObjexxFCL::fmt;
2303 Size const width( 8 );
2309 if(it->expid() == ex){
2310 Size count( it->res1() );
2316 Real rdc_exp( it->Jdipolar() );
2317 Real rdc_computed ( it->Jcomputed());
2318 out <<
A( width,
"RDC" )
2320 << I( width, count )
2321 << F( width, precision, rdc_exp )
2322 << F( width, precision, rdc_computed )
2329 for (
Size ex = 0; ex <
nex_; ex++) {
2332 SD_[ex][0][0] =
S_[ex][0][0];
2333 SD_[ex][0][1] =
S_[ex][0][1];
2334 SD_[ex][0][2] =
S_[ex][0][2];
2335 SD_[ex][1][1] =
S_[ex][1][1];
2336 SD_[ex][1][2] =
S_[ex][1][2];
2337 SD_[ex][1][0] =
S_[ex][1][0];
2338 SD_[ex][2][0] =
S_[ex][2][0];
2339 SD_[ex][2][1] =
S_[ex][2][1];
2340 SD_[ex][2][2] =
S_[ex][2][2];
2352 EIG_[ex][0][0] = v2[0][0];
2353 EIG_[ex][0][1] = v2[0][1];
2354 EIG_[ex][0][2] = v2[0][2];
2355 EIG_[ex][1][1] = v2[1][1];
2356 EIG_[ex][1][2] = v2[1][2];
2357 EIG_[ex][1][0] = v2[1][0];
2358 EIG_[ex][2][0] = v2[2][0];
2359 EIG_[ex][2][1] = v2[2][1];
2360 EIG_[ex][2][2] = v2[2][2];
2364 EV_[ex][0] = ev2[2];
2365 EV_[ex][1] = ev2[1];
2366 EV_[ex][2] = ev2[0];
2374 trace_[ex] = v2[0][0] + v2[1][1] + v2[2][2];
2376 tempvec[0] = v2[0][2];
2377 tempvec[1] = v2[1][2];
2378 tempvec[2] = v2[2][2];
2380 maxz_[ex] = tempvec[0];
2399 int nzero,i,j,k,nrot;
2413 tol += fabs(md[i][i]);
2420 if (fabs(eig[i]) < tol) {
2424 eig[i] = 1.0/eig[i];
2427 for(j=0; j<n; j++) {
2430 s += eig[k]*v[i][k]*v[j][k];
2446 #define ROTATE(a,i,j,k,l) g=a[i][j];h=a[k][l];a[i][j]=g-s*(h+g*tau);\
2447 a[k][l]=h+s*(g-h*tau);
2453 Real tresh,theta,tau,
t,sm,s,h,g,
c;
2457 for (ip=0; ip<n; ip++) {
2458 for (iq=0; iq<n; iq++) v[ip][iq]=0.0;
2461 for (ip=0; ip<n;ip++) {
2462 b[ip]=d[ip]=a[ip][ip];
2466 for (i=1; i<=50; i++) {
2468 for (ip=0; ip<n-1; ip++) {
2469 for (iq=ip+1; iq<n; iq++)
2470 sm += fabs(a[ip][iq]);
2479 for (ip=0; ip<n-1; ip++) {
2480 for (iq=ip+1; iq<n; iq++) {
2481 g=100.0*fabs(a[ip][iq]);
2482 if (i > 4 && fabs(d[ip])+g == fabs(d[ip])
2483 && fabs(d[iq])+g == fabs(d[iq]))
2485 else if (fabs(a[ip][iq]) > tresh) {
2487 if (fabs(h)+g == fabs(h))
2490 theta=0.5*h/(a[ip][iq]);
2491 t=1.0/(fabs(theta)+sqrt(1.0+theta*theta));
2492 if (theta < 0.0) t = -
t;
2503 for (j=0; j<ip; j++) {
2506 for (j=ip+1; j<iq; j++) {
2509 for (j=iq+1; j<n; j++) {
2512 for (j=0; j<n; j++) {
2519 for (ip=0; ip<n; ip++) {
2526 throw( utility::excn::EXCN_BadInput(
" too many iterations in Jacobi when compute RDC tensor") );
2534 Real tresh,theta,tau,
t,sm,s,h,g,
c;
2538 for (ip=0; ip<n; ip++) {
2539 for (iq=0; iq<n; iq++) v[ip][iq]=0.0;
2542 for (ip=0; ip<n;ip++) {
2543 b[ip]=d[ip]=a[ip][ip];
2547 for (i=1; i<=50; i++) {
2549 for (ip=0; ip<n-1; ip++) {
2550 for (iq=ip+1; iq<n; iq++)
2551 sm += fabs(a[ip][iq]);
2560 for (ip=0; ip<n-1; ip++) {
2561 for (iq=ip+1; iq<n; iq++) {
2562 g=100.0*fabs(a[ip][iq]);
2563 if (i > 4 && fabs(d[ip])+g == fabs(d[ip])
2564 && fabs(d[iq])+g == fabs(d[iq]))
2566 else if (fabs(a[ip][iq]) > tresh) {
2568 if (fabs(h)+g == fabs(h))
2571 theta=0.5*h/(a[ip][iq]);
2572 t=1.0/(fabs(theta)+sqrt(1.0+theta*theta));
2573 if (theta < 0.0) t = -
t;
2584 for (j=0; j<ip; j++) {
2587 for (j=ip+1; j<iq; j++) {
2590 for (j=iq+1; j<n; j++) {
2593 for (j=0; j<n; j++) {
2600 for (ip=0; ip<n; ip++) {
2607 throw( utility::excn::EXCN_BadInput(
" too many iterations in Jacobi when compute RDC tensor") );