28 #include <basic/database/open.hh>
35 #include <basic/Tracer.hh>
38 #include <numeric/conversions.hh>
39 #include <numeric/NumericTraits.hh>
40 #include <numeric/xyz.functions.hh>
43 #include <utility/io/izstream.hh>
44 #include <utility/io/ozstream.hh>
46 #include <utility/vector1.hh>
52 using namespace core::scoring::mm;
54 static basic::Tracer
TR(
"protocols.moves.branch_angle.BranchAngleOptimizer");
57 namespace branch_angle {
59 BranchAngleOptimizer::BranchAngleOptimizer(
62 mm_bondangle_library_( mm_bondangle_library ),
63 bond_angle_residue_type_param_set_(NULL),
64 tolerance_(0.0000001),
69 mm_bondangle_library_( scoring::
ScoringManager::get_instance()->get_MMBondAngleLibrary() ),
70 bond_angle_residue_type_param_set_(NULL),
71 tolerance_(0.0000001),
78 mm_bondangle_library_(src.mm_bondangle_library_),
79 bond_angle_residue_type_param_set_(src.bond_angle_residue_type_param_set_),
82 coef_map1_(src.coef_map1_),
83 coef_map2_(src.coef_map2_),
84 undefined_coef1_(src.undefined_coef1_),
85 undefined_coef2_(src.undefined_coef2_),
86 tolerance_(src.tolerance_),
87 initialized_(src.initialized_)
139 bool optimize_for_minimum
142 Real static const pi(numeric::NumericTraits<Real>::pi());
153 runtime_assert(!pose.
residue(center_atomid.
rsd()).has_incomplete_connection(center_atomid.
atomno()));
156 Size num_neighbors(pose.
residue(center_atomid.
rsd()).n_bonded_neighbor_all_res(center_atomid.
atomno()));
158 Real m2_bond_angle(numeric::angle_radians(pose.
xyz(main_atomid1), pose.
xyz(center_atomid),
159 pose.
xyz(main_atomid2)));
161 if (num_neighbors == 3) {
165 branching_atomid1(pose, main_atomid1, center_atomid, main_atomid2, branch_atomid1);
172 if (branch_atom1->input_stub_atom2() == main_atom2) {
175 main_atomid1 = main_atomid2;
176 main_atom1 = main_atom2;
177 main_atomid2 = temp_atomid;
178 main_atom2 = temp_atom;
182 if (!(branch_atom1->input_stub_atom1() == center_atom && branch_atom1->input_stub_atom2() == main_atom1 &&
183 branch_atom1->input_stub_atom3() == main_atom2)) {
185 TR.Warning <<
"Warning: Branching atom (" << branch_atomid1 <<
") for segment" << main_atomid1 << center_atomid
186 << main_atomid2 <<
"does not use segment atoms for input stub, ignoring" << std::endl;
191 BranchParam1 const params(
param1(pose, main_atomid1, center_atomid, main_atomid2, branch_atomid1));
193 std::map<BranchParam1, Size>::iterator coef_map_iter(
coef_map1_.find(params));
198 coef_index = coef_map_iter->second;
201 if (optimize_for_minimum) m2_bond_angle =
coef1_[coef_index].overall_theta0();
204 Real b1_torsion_offset;
206 coef1_[coef_index].evaluate(m2_bond_angle, b1_torsion_offset, b1_bond_angle);
211 pose.
set_dof(branch_atom1_PHI, b1_torsion_offset);
212 pose.
set_dof(branch_atom1_THETA, pi - b1_bond_angle);
214 }
else if (num_neighbors == 4) {
219 branching_atomids2(pose, main_atomid1, center_atomid, main_atomid2, branch_atomid1, branch_atomid2);
227 if (branch_atom1->input_stub_atom2() == main_atom2 && branch_atom2->input_stub_atom2() == main_atom2) {
230 main_atomid1 = main_atomid2;
231 main_atom1 = main_atom2;
232 main_atomid2 = temp_atomid;
233 main_atom2 = temp_atom;
234 temp_atomid = branch_atomid1;
235 temp_atom = branch_atom1;
236 branch_atomid1 = branch_atomid2;
237 branch_atom1 = branch_atom2;
238 branch_atomid2 = temp_atomid;
239 branch_atom2 = temp_atom;
243 if (!(branch_atom1->input_stub_atom1() == center_atom && branch_atom1->input_stub_atom2() == main_atom1 &&
244 branch_atom2->input_stub_atom1() == center_atom && branch_atom2->input_stub_atom2() == main_atom1)) {
246 TR.Warning <<
"Warning: Branching atoms (" << branch_atomid1 << branch_atomid2 <<
") for segment" << main_atomid1
247 << center_atomid << main_atomid2 <<
"do not use segment atoms for input stub, ignoring" << std::endl;
252 BranchParam2 const params(
param2(pose, main_atomid1, center_atomid, main_atomid2, branch_atomid1, branch_atomid2));
254 std::map<BranchParam2, Size>::iterator coef_map_iter(
coef_map2_.find(params));
259 coef_index = coef_map_iter->second;
262 if (optimize_for_minimum) m2_bond_angle =
coef2_[coef_index].overall_theta0();
265 Real b1_torsion_offset;
267 Real b2_torsion_offset;
269 coef2_[coef_index].evaluate(m2_bond_angle, b1_torsion_offset, b1_bond_angle, b2_torsion_offset, b2_bond_angle);
278 if (branch_atom1->input_stub_atom3() == main_atom2 && branch_atom2->input_stub_atom3() == branch_atom1) {
279 pose.
set_dof(branch_atom1_PHI, b1_torsion_offset);
280 pose.
set_dof(branch_atom2_PHI, b2_torsion_offset - b1_torsion_offset);
284 }
else if (branch_atom1->input_stub_atom3() == branch_atom2 && branch_atom2->input_stub_atom3() == main_atom2) {
285 pose.
set_dof(branch_atom1_PHI, b1_torsion_offset - b2_torsion_offset);
286 pose.
set_dof(branch_atom2_PHI, b2_torsion_offset);
291 TR.Warning <<
"Warning: Branching atoms (" << branch_atomid1 << branch_atomid2 <<
") for segment" << main_atomid1
292 << center_atomid << main_atomid2 <<
"do not have main atom 2 as their direct descendent, ignoring"
297 pose.
set_dof(branch_atom1_THETA, pi - b1_bond_angle);
298 pose.
set_dof(branch_atom2_THETA, pi - b2_bond_angle);
302 TR <<
"Warning: Segment" << main_atomid1 << center_atomid << main_atomid2
303 <<
"does not have 1 or 2 branching atoms, ignoring" << std::endl;
331 runtime_assert(!pose.
residue(center_atomid.
rsd()).has_incomplete_connection(center_atomid.
atomno()));
334 Size num_neighbors(pose.
residue(center_atomid.
rsd()).n_bonded_neighbor_all_res(center_atomid.
atomno()));
336 if (num_neighbors == 3) {
340 branching_atomid1(pose, main_atomid1, center_atomid, main_atomid2, branch_atomid1);
347 if (branch_atom1->input_stub_atom2() == main_atom2) {
349 main_atomid1 = main_atomid2;
350 main_atomid2 = temp_atomid;
354 BranchParam1 const params(
param1(pose, main_atomid1, center_atomid, main_atomid2, branch_atomid1));
356 std::map<BranchParam1, Size>::iterator coef_map_iter(
coef_map1_.find(params));
363 coef_index = coef_map_iter->second;
364 Ktheta =
coef1_[coef_index].overall_Ktheta();
365 theta0 =
coef1_[coef_index].overall_theta0();
366 energy0 =
coef1_[coef_index].overall_energy0();
369 }
else if (num_neighbors == 4) {
374 branching_atomids2(pose, main_atomid1, center_atomid, main_atomid2, branch_atomid1, branch_atomid2);
382 if (branch_atom1->input_stub_atom2() == main_atom2 && branch_atom2->input_stub_atom2() == main_atom2) {
384 main_atomid1 = main_atomid2;
385 main_atomid2 = temp_atomid;
386 temp_atomid = branch_atomid1;
387 branch_atomid1 = branch_atomid2;
388 branch_atomid2 = temp_atomid;
392 BranchParam2 const params(
param2(pose, main_atomid1, center_atomid, main_atomid2, branch_atomid1, branch_atomid2));
394 std::map<BranchParam2, Size>::iterator coef_map_iter(
coef_map2_.find(params));
401 coef_index = coef_map_iter->second;
402 Ktheta =
coef2_[coef_index].overall_Ktheta();
403 theta0 =
coef2_[coef_index].overall_theta0();
404 energy0 =
coef2_[coef_index].overall_energy0();
409 TR <<
"Warning: Segment" << main_atomid1 << center_atomid << main_atomid2
410 <<
"does not have 1 or 2 branching atoms, ignoring" << std::endl;
429 Real m1_m2_Ktheta, m1_m2_theta0, m1_b1_Ktheta, m1_b1_theta0, m2_b1_Ktheta, m2_b1_theta0;
432 pose.
conformation(), main_atomid1, center_atomid, main_atomid2, m1_m2_Ktheta, m1_m2_theta0
435 pose.
conformation(), main_atomid1, center_atomid, branch_atomid1, m1_b1_Ktheta, m1_b1_theta0
438 pose.
conformation(), main_atomid2, center_atomid, branch_atomid1, m2_b1_Ktheta, m2_b1_theta0
441 return BranchParam1(m1_m2_Ktheta, m1_m2_theta0, m1_b1_Ktheta, m1_b1_theta0, m2_b1_Ktheta, m2_b1_theta0,
445 int const main_mmtype1(pose.
residue_type(main_atomid1.
rsd()).atom(main_atomid1.
atomno()).mm_atom_type_index());
446 int const center_mmtype(pose.
residue_type(center_atomid.
rsd()).atom(center_atomid.
atomno()).mm_atom_type_index());
447 int const main_mmtype2(pose.
residue_type(main_atomid2.
rsd()).atom(main_atomid2.
atomno()).mm_atom_type_index());
448 int const branch_mmtype1(pose.
residue_type(branch_atomid1.
rsd()).atom(branch_atomid1.
atomno()).mm_atom_type_index());
454 BranchParam1 const params((m1_m2.first->second).key1(), (m1_m2.first->second).key2(),
455 (m1_b1.first->second).key1(), (m1_b1.first->second).key2(),
456 (m2_b1.first->second).key1(), (m2_b1.first->second).key2(),
476 Real m1_m2_Ktheta, m1_m2_theta0, m1_b1_Ktheta, m1_b1_theta0, m2_b1_Ktheta, m2_b1_theta0,
477 m1_b2_Ktheta, m1_b2_theta0, m2_b2_Ktheta, m2_b2_theta0, b1_b2_Ktheta, b1_b2_theta0;
480 pose.
conformation(), main_atomid1, center_atomid, main_atomid2, m1_m2_Ktheta, m1_m2_theta0
483 pose.
conformation(), main_atomid1, center_atomid, branch_atomid1, m1_b1_Ktheta, m1_b1_theta0
486 pose.
conformation(), main_atomid2, center_atomid, branch_atomid1, m2_b1_Ktheta, m2_b1_theta0
489 pose.
conformation(), main_atomid1, center_atomid, branch_atomid2, m1_b2_Ktheta, m1_b2_theta0
492 pose.
conformation(), main_atomid2, center_atomid, branch_atomid2, m2_b2_Ktheta, m2_b2_theta0
495 pose.
conformation(), branch_atomid1, center_atomid, branch_atomid2, b1_b2_Ktheta, b1_b2_theta0
498 return BranchParam2(m1_m2_Ktheta, m1_m2_theta0, m1_b1_Ktheta, m1_b1_theta0, m2_b1_Ktheta, m2_b1_theta0,
499 m1_b2_Ktheta, m1_b2_theta0, m2_b2_Ktheta, m2_b2_theta0, b1_b2_Ktheta, b1_b2_theta0,
503 int const main_mmtype1(pose.
residue_type(main_atomid1.
rsd()).atom(main_atomid1.
atomno()).mm_atom_type_index());
504 int const center_mmtype(pose.
residue_type(center_atomid.
rsd()).atom(center_atomid.
atomno()).mm_atom_type_index());
505 int const main_mmtype2(pose.
residue_type(main_atomid2.
rsd()).atom(main_atomid2.
atomno()).mm_atom_type_index());
506 int const branch_mmtype1(pose.
residue_type(branch_atomid1.
rsd()).atom(branch_atomid1.
atomno()).mm_atom_type_index());
507 int const branch_mmtype2(pose.
residue_type(branch_atomid2.
rsd()).atom(branch_atomid2.
atomno()).mm_atom_type_index());
516 BranchParam2 const params((m1_m2.first->second).key1(), (m1_m2.first->second).key2(),
517 (m1_b1.first->second).key1(), (m1_b1.first->second).key2(),
518 (m2_b1.first->second).key1(), (m2_b1.first->second).key2(),
519 (m1_b2.first->second).key1(), (m1_b2.first->second).key2(),
520 (m2_b2.first->second).key1(), (m2_b2.first->second).key2(),
521 (b1_b2.first->second).key1(), (b1_b2.first->second).key2(),
578 TR <<
"Wrote " <<
undefined_coef1_.size() <<
" undefined single branch parameters to the database" << std::endl;
582 TR <<
"Wrote " <<
undefined_coef2_.size() <<
" undefined double branch parameters to the database" << std::endl;
611 Real overall_energy0;
612 Real b1_torsion_offset_A;
613 Real b1_torsion_offset_B;
614 Real b1_torsion_offset_C;
615 Real b1_bond_angle_A;
616 Real b1_bond_angle_B;
617 Real b1_bond_angle_C;
619 while (in >> m1_m2_Ktheta >> m1_m2_theta0
620 >> m1_b1_Ktheta >> m1_b1_theta0
621 >> m2_b1_Ktheta >> m2_b1_theta0
622 >> overall_Ktheta >> overall_theta0 >> overall_energy0
623 >> b1_torsion_offset_A >> b1_torsion_offset_B >> b1_torsion_offset_C
624 >> b1_bond_angle_A >> b1_bond_angle_B >> b1_bond_angle_C) {
626 numeric::conversions::to_radians(m1_m2_theta0);
627 numeric::conversions::to_radians(m1_b1_theta0);
628 numeric::conversions::to_radians(m2_b1_theta0);
629 numeric::conversions::to_radians(overall_theta0);
632 m1_b1_Ktheta, m1_b1_theta0,
633 m2_b1_Ktheta, m2_b1_theta0,
636 BranchCoef1 const coefs(overall_Ktheta, overall_theta0, overall_energy0,
637 b1_torsion_offset_A, b1_torsion_offset_B, b1_torsion_offset_C,
638 b1_bond_angle_A, b1_bond_angle_B, b1_bond_angle_C);
640 std::map<BranchParam1, core::Size>::iterator iter(
coef_map1_.find(params));
648 coef1_[iter->second] = coefs;
660 utility::io::izstream infile(filename);
676 utility::io::izstream infile;
677 basic::database::open(infile,
"sampling/branch_angle/branch_angle_1.txt");
687 return read_coef1(basic::database::full_name(
"branch_angle/branch_angle_1_user.txt",
false));
726 Real overall_energy0;
727 Real b1_torsion_offset_A;
728 Real b1_torsion_offset_B;
729 Real b1_torsion_offset_C;
730 Real b1_bond_angle_A;
731 Real b1_bond_angle_B;
732 Real b1_bond_angle_C;
733 Real b2_torsion_offset_A;
734 Real b2_torsion_offset_B;
735 Real b2_torsion_offset_C;
736 Real b2_bond_angle_A;
737 Real b2_bond_angle_B;
738 Real b2_bond_angle_C;
740 while (in >> m1_m2_Ktheta >> m1_m2_theta0
741 >> m1_b1_Ktheta >> m1_b1_theta0
742 >> m2_b1_Ktheta >> m2_b1_theta0
743 >> m1_b2_Ktheta >> m1_b2_theta0
744 >> m2_b2_Ktheta >> m2_b2_theta0
745 >> b1_b2_Ktheta >> b1_b2_theta0
746 >> overall_Ktheta >> overall_theta0 >> overall_energy0
747 >> b1_torsion_offset_A >> b1_torsion_offset_B >> b1_torsion_offset_C
748 >> b1_bond_angle_A >> b1_bond_angle_B >> b1_bond_angle_C
749 >> b2_torsion_offset_A >> b2_torsion_offset_B >> b2_torsion_offset_C
750 >> b2_bond_angle_A >> b2_bond_angle_B >> b2_bond_angle_C) {
752 numeric::conversions::to_radians(m1_m2_theta0);
753 numeric::conversions::to_radians(m1_b1_theta0);
754 numeric::conversions::to_radians(m2_b1_theta0);
755 numeric::conversions::to_radians(m1_b2_theta0);
756 numeric::conversions::to_radians(m2_b2_theta0);
757 numeric::conversions::to_radians(b1_b2_theta0);
758 numeric::conversions::to_radians(overall_theta0);
761 m1_b1_Ktheta, m1_b1_theta0,
762 m2_b1_Ktheta, m2_b1_theta0,
763 m1_b2_Ktheta, m1_b2_theta0,
764 m2_b2_Ktheta, m2_b2_theta0,
765 b1_b2_Ktheta, b1_b2_theta0,
768 BranchCoef2 const coefs(overall_Ktheta, overall_theta0, overall_energy0,
769 b1_torsion_offset_A, b1_torsion_offset_B, b1_torsion_offset_C,
770 b1_bond_angle_A, b1_bond_angle_B, b1_bond_angle_C,
771 b2_torsion_offset_A, b2_torsion_offset_B, b2_torsion_offset_C,
772 b2_bond_angle_A, b2_bond_angle_B, b2_bond_angle_C);
774 std::map<BranchParam2, core::Size>::iterator iter(
coef_map2_.find(params));
782 coef2_[iter->second] = coefs;
794 utility::io::izstream infile(filename);
810 utility::io::izstream infile;
811 basic::database::open(infile,
"sampling/branch_angle/branch_angle_2.txt");
821 return read_coef2(basic::database::full_name(
"branch_angle/branch_angle_2_user.txt",
false));
842 while (in >> m1_m2_Ktheta >> m1_m2_theta0
843 >> m1_b1_Ktheta >> m1_b1_theta0
844 >> m2_b1_Ktheta >> m2_b1_theta0) {
846 numeric::conversions::to_radians(m1_m2_theta0);
847 numeric::conversions::to_radians(m1_b1_theta0);
848 numeric::conversions::to_radians(m2_b1_theta0);
851 m1_b1_Ktheta, m1_b1_theta0,
852 m2_b1_Ktheta, m2_b1_theta0,
866 utility::io::izstream infile(filename);
882 return read_undefined_coef1(basic::database::full_name(
"branch_angle/branch_angle_1_undefined.txt",
false));
898 std::streamsize oldprecision = out.precision();
899 out << std::setprecision(16);
907 out << std::setprecision(oldprecision);
917 utility::io::ozstream outfile(filename);
934 return write_undefined_coef1(basic::database::full_name(
"branch_angle/branch_angle_1_undefined.txt",
false));
967 while (in >> m1_m2_Ktheta >> m1_m2_theta0
968 >> m1_b1_Ktheta >> m1_b1_theta0
969 >> m2_b1_Ktheta >> m2_b1_theta0
970 >> m1_b2_Ktheta >> m1_b2_theta0
971 >> m2_b2_Ktheta >> m2_b2_theta0
972 >> b1_b2_Ktheta >> b1_b2_theta0) {
974 numeric::conversions::to_radians(m1_m2_theta0);
975 numeric::conversions::to_radians(m1_b1_theta0);
976 numeric::conversions::to_radians(m2_b1_theta0);
977 numeric::conversions::to_radians(m1_b2_theta0);
978 numeric::conversions::to_radians(m2_b2_theta0);
979 numeric::conversions::to_radians(b1_b2_theta0);
982 m1_b1_Ktheta, m1_b1_theta0,
983 m2_b1_Ktheta, m2_b1_theta0,
984 m1_b2_Ktheta, m1_b2_theta0,
985 m2_b2_Ktheta, m2_b2_theta0,
986 b1_b2_Ktheta, b1_b2_theta0,
1000 utility::io::izstream infile(filename);
1016 return read_undefined_coef2(basic::database::full_name(
"branch_angle/branch_angle_2_undefined.txt",
false));
1035 std::streamsize oldprecision = out.precision();
1036 out << std::setprecision(16);
1047 out << std::setprecision(oldprecision);
1057 utility::io::ozstream outfile(filename);
1074 return write_undefined_coef2(basic::database::full_name(
"branch_angle/branch_angle_2_undefined.txt",
false));
1093 runtime_assert(neighbors.size() == 3);
1095 bool found_main_atomid1(
false);
1096 bool found_main_atomid2(
false);
1098 for (
Size i = 1; i <= 3; ++i) {
1100 if (atomid == main_atomid1) {
1101 found_main_atomid1 =
true;
1102 }
else if (atomid == main_atomid2) {
1103 found_main_atomid2 =
true;
1105 branch_atomid1 = atomid;
1109 runtime_assert(found_main_atomid1 && found_main_atomid2);
1127 Real static const pi_2(numeric::NumericTraits<Real>::pi_2());
1131 runtime_assert(neighbors.size() == 4);
1133 bool found_main_atomid1(
false);
1134 bool found_main_atomid2(
false);
1135 bool found_branch_atomid1(
false);
1137 for (
Size i = 1; i <= 4; ++i) {
1139 if (atomid == main_atomid1) {
1140 found_main_atomid1 =
true;
1141 }
else if (atomid == main_atomid2) {
1142 found_main_atomid2 =
true;
1143 }
else if (!found_branch_atomid1) {
1144 branch_atomid1 = atomid;
1145 found_branch_atomid1 =
true;
1147 branch_atomid2 = atomid;
1151 runtime_assert(found_main_atomid1 && found_main_atomid2);
1154 Real dihedral1(numeric::dihedral_radians(pose.
xyz(main_atomid2), pose.
xyz(main_atomid1), pose.
xyz(center_atomid),
1155 pose.
xyz(branch_atomid1)));
1156 if (dihedral1 < 0) dihedral1 += pi_2;
1157 Real dihedral2(numeric::dihedral_radians(pose.
xyz(main_atomid2), pose.
xyz(main_atomid1), pose.
xyz(center_atomid),
1158 pose.
xyz(branch_atomid2)));
1159 if (dihedral2 < 0) dihedral2 += pi_2;
1162 if (dihedral2 < dihedral1) {
1164 branch_atomid1 = branch_atomid2;
1165 branch_atomid2 = temp_atomid;
1181 Real static const pi_2(numeric::NumericTraits<Real>::pi_2());
1186 runtime_assert(parent);
1187 runtime_assert(parent->get_nonjump_atom(3));
1188 runtime_assert(!parent->get_nonjump_atom(4));
1194 for (
Size i = 1; i <= 3; ++i) {
1196 TR << sibling->id() << std::endl;
1197 if (sibling != main_atom2) {
1198 if (!branch_atom1) {
1199 branch_atom1 = sibling;
1201 branch_atom2 = sibling;
1206 runtime_assert(branch_atom1);
1207 runtime_assert(branch_atom2);
1210 Real dihedral1(parent->dihedral_between_bonded_children(main_atom2, branch_atom1));
1211 if (dihedral1 < 0) dihedral1 += pi_2;
1212 Real dihedral2(parent->dihedral_between_bonded_children(main_atom2, branch_atom2));
1213 if (dihedral2 < 0) dihedral2 += pi_2;
1216 if (dihedral2 < dihedral1) {
1218 branch_atom1 = branch_atom2;
1219 branch_atom2 = temp_atom;