1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38 package ffx.algorithms.optimize;
39
40 import static java.lang.String.format;
41 import static org.junit.Assert.assertEquals;
42
43 import ffx.algorithms.misc.AlgorithmsTest;
44 import ffx.algorithms.optimize.manybody.EliminatedRotamers;
45 import ffx.algorithms.optimize.manybody.EnergyExpansion;
46 import ffx.potential.ForceFieldEnergy;
47 import ffx.potential.MolecularAssembly;
48 import ffx.potential.Utilities;
49 import ffx.potential.bonded.Polymer;
50 import ffx.potential.bonded.Residue;
51 import ffx.potential.bonded.Rotamer;
52 import ffx.potential.bonded.RotamerLibrary;
53 import ffx.potential.utils.PotentialsUtils;
54 import java.io.File;
55 import java.util.ArrayList;
56 import java.util.Arrays;
57 import java.util.Collection;
58 import java.util.List;
59 import org.junit.Test;
60 import org.junit.runner.RunWith;
61 import org.junit.runners.Parameterized;
62
63
64
65
66
67
68
69 @RunWith(Parameterized.class)
70 public class RotamerOptimizationTest extends AlgorithmsTest {
71
72 private final String info;
73 private final String filename;
74 private final String restartName;
75 private final int startResID;
76 private final int endResID;
77 private final int pruningLevel;
78 private final boolean useGoldstein;
79 private final boolean useThreeBody;
80 private final boolean useOriginalRotamers;
81 private final boolean doOverallOpt;
82 private final double expectedEnergy;
83 private final boolean doSelfOpt;
84 private final double expectedSelfEnergy;
85 private final boolean doPairOpt;
86 private final int pairResidue;
87 private final double expectedPairEnergy;
88 private final boolean doTripleOpt;
89 private final int tripleResidue1;
90 private final int tripleResidue2;
91 private final double expectedTripleEnergy;
92 private final double tolerance;
93 private File restartFile;
94 private MolecularAssembly molecularAssembly;
95 private ForceFieldEnergy forceFieldEnergy;
96
97 public RotamerOptimizationTest(
98 String info,
99 String filename,
100 String restartName,
101 int startResID,
102 int endResID,
103 int pruningLevel,
104 boolean useGoldstein,
105 boolean useThreeBody,
106 boolean useOriginalRotamers,
107 boolean doOverallOpt,
108 double expectedEnergy,
109 boolean doSelfOpt,
110 double expectedSelfEnergy,
111 boolean doPairOpt,
112 int pairResidue,
113 double expectedPairEnergy,
114 boolean doTripleOpt,
115 int tripleResidue1,
116 int tripleResidue2,
117 double expectedTripleEnergy,
118 double tolerance) {
119 this.info = info;
120 this.filename = filename;
121 this.restartName = restartName;
122 this.startResID = startResID;
123 this.endResID = endResID;
124 this.pruningLevel = pruningLevel;
125 this.useGoldstein = useGoldstein;
126 this.useThreeBody = useThreeBody;
127 this.useOriginalRotamers = useOriginalRotamers;
128 this.doOverallOpt = doOverallOpt;
129 this.expectedEnergy = expectedEnergy;
130 this.doSelfOpt = doSelfOpt;
131 this.expectedSelfEnergy = expectedSelfEnergy;
132 this.doPairOpt = doPairOpt;
133 this.pairResidue = pairResidue;
134 this.expectedPairEnergy = expectedPairEnergy;
135 this.doTripleOpt = doTripleOpt;
136 this.tripleResidue1 = tripleResidue1;
137 this.tripleResidue2 = tripleResidue2;
138 this.expectedTripleEnergy = expectedTripleEnergy;
139 this.tolerance = tolerance;
140 }
141
142 @Parameterized.Parameters
143 public static Collection<Object[]> data() {
144 return Arrays.asList(
145 new Object[][] {
146 {
147 "Chignolin Direct with Orig Rot - No Pruning (Goldstein)",
148 "5awl.pdb",
149 "5awl.direct.orig.prun0.residues1-4.restart",
150 1,
151 4,
152 0,
153 true,
154 false,
155 true,
156 true,
157 -212.8853397349646,
158 true,
159 -212.8853397349646,
160 true,
161 1,
162 992.7753296883213,
163 false,
164 1,
165 2,
166 0.0,
167 1.0e-3
168 },
169 {
170 "Chignolin Direct with Orig Rot - Singles Pruning (Goldstein)",
171 "5awl.pdb",
172 "5awl.direct.orig.prun1.residues1-4.restart",
173 1,
174 4,
175 1,
176 true,
177 false,
178 true,
179 true,
180 -212.8853397349646,
181 true,
182 -212.8853397349646,
183 true,
184 1,
185 -197.82425073284452,
186 false,
187 1,
188 2,
189 0.0,
190 1.0e-3
191 },
192 {
193 "Chignolin Direct with Orig Rot - Pairs Pruning (Goldstein)",
194 "5awl.pdb",
195 "5awl.direct.orig.prun2.residues1-4.restart",
196 1,
197 4,
198 2,
199 true,
200 false,
201 true,
202 true,
203 -212.8853397349646,
204 true,
205 -212.8853397349646,
206 true,
207 1,
208 -197.82425073284452,
209 false,
210 1,
211 2,
212 0.0,
213 1.0e-3
214 },
215 {
216 "Chignolin Direct with Orig Rot - 3-body (Goldstein)",
217 "5awl.pdb",
218 "5awl.direct.orig.prun1.3body.residues1-4.restart",
219 1,
220 4,
221 1,
222 true,
223 true,
224 true,
225 true,
226 -212.8853397349646,
227 true,
228 -212.8853397349646,
229 true,
230 1,
231 -197.82425073284452,
232 true,
233 1,
234 2,
235 -189.1182888424594,
236 1.0e-3
237 },
238 {
239 "Chignolin Direct with Orig Rot - No Pruning (DEE)",
240 "5awl.pdb",
241 "5awl.direct.orig.prun0.residues1-4.restart",
242 1,
243 4,
244 0,
245 false,
246 false,
247 true,
248 true,
249 -212.8853397349646,
250 true,
251 -212.8853397349646,
252 true,
253 1,
254 992.7753296883207,
255 false,
256 1,
257 2,
258 0.0,
259 1.0e-3
260 },
261 {
262 "Chignolin Direct with Orig Rot - Singles Pruning (DEE)",
263 "5awl.pdb",
264 "5awl.direct.orig.prun1.residues1-4.restart",
265 1,
266 4,
267 1,
268 false,
269 false,
270 true,
271 true,
272 -212.8853397349646,
273 true,
274 -212.8853397349646,
275 true,
276 1,
277 -197.82425073284452,
278 false,
279 1,
280 2,
281 0.0,
282 1.0e-3
283 },
284 {
285 "Chignolin Direct with Orig Rot - Pairs Pruning (DEE)",
286 "5awl.pdb",
287 "5awl.direct.orig.prun2.residues1-4.restart",
288 1,
289 4,
290 2,
291 false,
292 false,
293 true,
294 true,
295 -212.8853397349646,
296 true,
297 -212.8853397349646,
298 true,
299 1,
300 -197.82425073284452,
301 false,
302 1,
303 2,
304 0.0,
305 1.0e-3
306 },
307 {
308 "Chignolin Direct with Orig Rot - 3-body (DEE)",
309 "5awl.pdb",
310 "5awl.direct.orig.prun1.3body.residues1-4.restart",
311 1,
312 4,
313 1,
314 false,
315 true,
316 true,
317 true,
318 -212.8853397349646,
319 true,
320 -212.8853397349646,
321 true,
322 1,
323 -197.82425073284452,
324 true,
325 1,
326 2,
327 -189.1182888424594,
328 1.0e-3
329 }
330 });
331 }
332
333 @Test
334 public void testPairEnergyElimination() {
335
336 load();
337
338
339 RotamerLibrary rLib = new RotamerLibrary(useOriginalRotamers);
340
341 int counter = 1;
342 List<Residue> residueList = new ArrayList<>();
343 Polymer[] polymers = molecularAssembly.getChains();
344 for (Polymer polymer : polymers) {
345 List<Residue> residues = polymer.getResidues();
346 for (int i = 0; i < endResID; i++) {
347 Residue residue = residues.get(i);
348 Rotamer[] rotamers = residue.setRotamers(rLib);
349 if (rotamers != null) {
350 int nrot = rotamers.length;
351 if (nrot == 1) {
352 RotamerLibrary.applyRotamer(residue, rotamers[0]);
353 }
354 if (counter >= startResID) {
355 residueList.add(residue);
356 }
357 }
358 counter++;
359 }
360 }
361 Residue[] residues = residueList.toArray(new Residue[0]);
362
363 RotamerOptimization rotamerOptimization =
364 new RotamerOptimization(molecularAssembly, forceFieldEnergy, null);
365 rotamerOptimization.setRotamerLibrary(rLib);
366 rotamerOptimization.setThreeBodyEnergy(useThreeBody);
367 rotamerOptimization.setUseGoldstein(useGoldstein);
368 rotamerOptimization.setPruning(pruningLevel);
369 rotamerOptimization.setEnergyRestartFile(restartFile);
370
371 rotamerOptimization.setResidues(residueList);
372 rotamerOptimization.setSingletonClashThreshold(20.0);
373 rotamerOptimization.setPairClashThreshold(20.0);
374
375 double energy;
376 int nRes = residueList.size();
377 if (doOverallOpt) {
378 rotamerOptimization.turnRotamerSingleEliminationOff();
379 try {
380 energy = rotamerOptimization.optimize(RotamerOptimization.Algorithm.ALL);
381 } catch (Exception e) {
382 logger.warning(Utilities.stackTraceToString(e));
383 throw e;
384 }
385
386 assertEquals(info + " Total Energy", expectedEnergy, energy, tolerance);
387 }
388
389
390 if (doSelfOpt) {
391 rotamerOptimization.turnRotamerSingleEliminationOff();
392 rotamerOptimization.setTestSelfEnergyEliminations(true);
393 energy = rotamerOptimization.optimize(RotamerOptimization.Algorithm.ALL);
394
395 assertEquals(info + " Self-Energy", expectedSelfEnergy, energy, tolerance);
396
397
398 int[] optimum = rotamerOptimization.getOptimumRotamers();
399
400 EliminatedRotamers eR = rotamerOptimization.getEliminatedRotamers();
401
402
403 for (int i = 0; i < nRes; i++) {
404 Residue res = residueList.get(i);
405 Rotamer[] rotI = res.getRotamers();
406 int nRot = rotI.length;
407
408 int rotCounter = 0;
409 while (rotCounter < nRot && eR.checkPrunedSingles(i, rotCounter)) {
410 rotCounter++;
411 }
412
413 EnergyExpansion eE = rotamerOptimization.getEnergyExpansion();
414 double lowEnergy = eE.getSelf(i, rotCounter);
415 int bestRot = rotCounter;
416 for (int ri = 1; ri < nRot; ri++) {
417 if (!eR.checkPrunedSingles(i, ri)) {
418 double selfEnergy = eE.getSelf(i, ri);
419 if (selfEnergy < lowEnergy) {
420 lowEnergy = selfEnergy;
421 bestRot = ri;
422 }
423 }
424 }
425 assertEquals(format(" %s Self-Energy of residue %d", info, i), optimum[i], bestRot);
426 }
427 }
428
429
430 if (doPairOpt) {
431 rotamerOptimization.turnRotamerSingleEliminationOff();
432 rotamerOptimization.setTestPairEnergyEliminations(pairResidue);
433 energy = rotamerOptimization.optimize(RotamerOptimization.Algorithm.ALL);
434
435 assertEquals(info + " Pair-Energy", expectedPairEnergy, energy, tolerance);
436
437
438
439 int[] optimum = rotamerOptimization.getOptimumRotamers();
440
441 Residue resI = residueList.get(pairResidue);
442 Rotamer[] rotI = resI.getRotamers();
443 int ni = rotI.length;
444
445 double minEnergy = Double.POSITIVE_INFINITY;
446 int bestRotI = -1;
447
448 EliminatedRotamers eR = rotamerOptimization.getEliminatedRotamers();
449
450
451 for (int ri = 0; ri < ni; ri++) {
452 double energyForRi = 0.0;
453 if (eR.checkPrunedSingles(pairResidue, ri)) {
454 continue;
455 }
456
457 for (int j = 0; j < nRes; j++) {
458 if (j == pairResidue) {
459 continue;
460 }
461 Residue resJ = residueList.get(j);
462 Rotamer[] rotJ = resJ.getRotamers();
463 int nRot = rotJ.length;
464
465 int rj = 0;
466 while (eR.checkPrunedSingles(j, rj) || eR.checkPrunedPairs(pairResidue, ri, j, rj)) {
467 if (++rj >= nRot) {
468 logger.warning("RJ is too large.");
469 }
470 }
471
472 EnergyExpansion eE = rotamerOptimization.getEnergyExpansion();
473 double lowEnergy = eE.get2Body(pairResidue, ri, j, rj);
474
475 for (rj = 1; rj < nRot; rj++) {
476 if (!eR.checkPrunedSingles(j, rj) && !eR.checkPrunedPairs(pairResidue, ri, j, rj)) {
477 double pairEnergy = eE.get2Body(pairResidue, ri, j, rj);
478 if (pairEnergy < lowEnergy) {
479 lowEnergy = pairEnergy;
480 }
481 }
482 }
483 energyForRi += lowEnergy;
484 }
485 if (energyForRi < minEnergy) {
486 minEnergy = energyForRi;
487 bestRotI = ri;
488 }
489 }
490
491 assertEquals(
492 format(
493 " %s Best 2-body energy sum for residue %d is with rotamer %d at %10.4f.",
494 info, pairResidue, bestRotI, minEnergy),
495 optimum[pairResidue],
496 bestRotI);
497
498
499
500 for (int j = 0; j < nRes; j++) {
501 if (j == pairResidue) {
502 continue;
503 }
504 Residue resJ = residueList.get(j);
505 Rotamer[] rotJ = resJ.getRotamers();
506 int nRotJ = rotJ.length;
507
508 int rotCounter = 0;
509 while (eR.checkPrunedPairs(pairResidue, bestRotI, j, rotCounter) && rotCounter < nRotJ) {
510 rotCounter++;
511 }
512
513 EnergyExpansion eE = rotamerOptimization.getEnergyExpansion();
514 double lowEnergy = eE.get2Body(pairResidue, bestRotI, j, rotCounter);
515 int bestRotJ = rotCounter;
516 for (int rj = 1; rj < nRotJ; rj++) {
517 if (!eR.checkPrunedSingles(j, rj) && !eR.checkPrunedPairs(pairResidue, bestRotI, j, rj)) {
518 double pairEnergy = eE.get2Body(pairResidue, bestRotI, j, rj);
519 if (pairEnergy < lowEnergy) {
520 lowEnergy = pairEnergy;
521 bestRotJ = rj;
522 }
523 }
524 }
525 if (bestRotJ != optimum[j]) {
526
527 if (lowEnergy == eE.get2Body(pairResidue, bestRotI, j, optimum[j])) {
528 logger.warning(
529 format(
530 " Identical 2-body energies for %s: resi %d-%d, resj %d, best rotamer J %d, optimum J %d, 2-body energy (both) %10.6f",
531 info, pairResidue, bestRotI, j, bestRotJ, optimum[j], lowEnergy));
532 } else {
533 assertEquals(
534 format(
535 " %s Pair-Energy of residue (%d,%d) with residue %d",
536 info, pairResidue, bestRotI, j),
537 optimum[j],
538 bestRotJ);
539 }
540 }
541 }
542 }
543
544
545 if (doTripleOpt) {
546 rotamerOptimization.turnRotamerSingleEliminationOff();
547 rotamerOptimization.setTestTripleEnergyEliminations(tripleResidue1, tripleResidue2);
548 try {
549 energy = rotamerOptimization.optimize(RotamerOptimization.Algorithm.ALL);
550 assertEquals(info + " Triple-Energy", expectedTripleEnergy, energy, tolerance);
551 } catch (Exception e) {
552 e.fillInStackTrace();
553 e.printStackTrace();
554 logger.log(java.util.logging.Level.INFO, "Error in doTripleOpt", e);
555 }
556
557
558
559 int[] optimum = rotamerOptimization.getOptimumRotamers();
560
561
562 Residue resI = residueList.get(tripleResidue1);
563 Rotamer[] rotI = resI.getRotamers();
564 int ni = rotI.length;
565
566
567 Residue resJ = residueList.get(tripleResidue2);
568 Rotamer[] rotJ = resJ.getRotamers();
569 int nj = rotJ.length;
570
571 double minEnergyIJ = Double.POSITIVE_INFINITY;
572 int bestRotI = -1;
573 int bestRotJ = -1;
574
575 EliminatedRotamers eR = rotamerOptimization.getEliminatedRotamers();
576
577 for (int ri = 0; ri < ni; ri++) {
578 if (eR.check(tripleResidue1, ri)) {
579 continue;
580 }
581 for (int rj = 0; rj < nj; rj++) {
582 if (eR.checkPrunedSingles(tripleResidue2, rj)
583 || eR.checkPrunedPairs(tripleResidue1, ri, tripleResidue2, rj)) {
584 continue;
585 }
586 double currentEnergy = 0.0;
587 for (int k = 0; k < nRes; k++) {
588 if (k == tripleResidue1 || k == tripleResidue2) {
589 continue;
590 }
591 Residue resK = residueList.get(k);
592 Rotamer[] rotK = resK.getRotamers();
593 int nk = rotK.length;
594
595 int rkStart = 0;
596 while (eR.checkPrunedSingles(k, rkStart)
597 || eR.checkPrunedPairs(tripleResidue1, ri, k, rkStart)
598 || eR.checkPrunedPairs(tripleResidue2, rj, k, rkStart)) {
599 if (++rkStart >= nk) {
600 logger.warning("RJ is too large.");
601 }
602 }
603
604 EnergyExpansion eE = rotamerOptimization.getEnergyExpansion();
605 double lowEnergy =
606 eE.get3Body(residues, tripleResidue1, ri, tripleResidue2, rj, k, rkStart);
607 for (int rk = rkStart; rk < nk; rk++) {
608 if (!eR.checkPrunedSingles(k, rk)
609 && !eR.checkPrunedPairs(tripleResidue1, ri, k, rk)
610 && !eR.checkPrunedPairs(tripleResidue2, rj, k, rk)) {
611 double tripleEnergy =
612 eE.get3Body(residues, tripleResidue1, ri, tripleResidue2, rj, k, rk);
613 if (tripleEnergy < lowEnergy) {
614 lowEnergy = tripleEnergy;
615 }
616 }
617 }
618 currentEnergy +=
619 lowEnergy;
620 }
621 if (currentEnergy < minEnergyIJ) {
622 minEnergyIJ = currentEnergy;
623 bestRotI = ri;
624 bestRotJ = rj;
625 }
626 }
627 }
628
629 assertEquals(
630 format(
631 " %s Best three-body energy sum for residue %d is with rotamer %d at %10.4f.",
632 info, tripleResidue1, bestRotI, minEnergyIJ),
633 optimum[tripleResidue1],
634 bestRotI);
635
636 assertEquals(
637 format(
638 " %s Best three-body energy sum for residue %d is with rotamer %d at %10.4f.",
639 info, tripleResidue2, bestRotJ, minEnergyIJ),
640 optimum[tripleResidue2],
641 bestRotJ);
642
643
644 for (int k = 0; k < nRes; k++) {
645 if (k == tripleResidue1 || k == tripleResidue2) {
646 continue;
647 }
648 Residue resK = residueList.get(k);
649 Rotamer[] rotK = resK.getRotamers();
650 int nk = rotK.length;
651
652 int rotCounter = 0;
653 while (eR.checkPrunedPairs(tripleResidue1, bestRotI, k, rotCounter)
654 && eR.checkPrunedPairs(tripleResidue2, bestRotJ, k, rotCounter)
655 && rotCounter < nk) {
656 rotCounter++;
657 }
658 EnergyExpansion eE = rotamerOptimization.getEnergyExpansion();
659 double lowEnergy =
660 eE.get3Body(
661 residues, tripleResidue1, bestRotI, tripleResidue2, bestRotJ, k, rotCounter);
662 int bestRotK = rotCounter;
663 for (int rk = 1; rk < nk; rk++) {
664 if (!eR.checkPrunedSingles(k, rk)
665 && !eR.checkPrunedPairs(tripleResidue1, bestRotI, k, rk)
666 && !eR.checkPrunedPairs(tripleResidue2, bestRotJ, k, rk)) {
667 double tripleEnergy =
668 eE.get3Body(residues, tripleResidue1, bestRotI, tripleResidue2, bestRotJ, k, rk);
669 if (tripleEnergy < lowEnergy) {
670 lowEnergy = tripleEnergy;
671 bestRotK = rk;
672 }
673 }
674 }
675 assertEquals(
676 format(
677 " %s Triple-Energy of residue (%d,%d) and residue (%d,%d) with residue %d",
678 info, tripleResidue1, bestRotI, tripleResidue2, bestRotJ, k),
679 optimum[k],
680 bestRotK);
681 }
682 }
683 }
684
685 @Test
686 public void testSelfEnergyElimination() {
687
688 load();
689
690
691 RotamerLibrary rLib = new RotamerLibrary(useOriginalRotamers);
692
693 int counter = 1;
694 List<Residue> residueList = new ArrayList<>();
695 Polymer[] polymers = molecularAssembly.getChains();
696 for (Polymer polymer : polymers) {
697 List<Residue> residues = polymer.getResidues();
698 for (int i = 0; i < endResID; i++) {
699 Residue residue = residues.get(i);
700 Rotamer[] rotamers = residue.setRotamers(rLib);
701 if (rotamers != null) {
702 int nrot = rotamers.length;
703 if (nrot == 1) {
704 RotamerLibrary.applyRotamer(residue, rotamers[0]);
705 }
706 if (counter >= startResID) {
707 residueList.add(residue);
708 }
709 }
710 counter++;
711 }
712 }
713 Residue[] residues = residueList.toArray(new Residue[0]);
714
715 RotamerOptimization rotamerOptimization =
716 new RotamerOptimization(molecularAssembly, forceFieldEnergy, null);
717 rotamerOptimization.setRotamerLibrary(rLib);
718 rotamerOptimization.setThreeBodyEnergy(useThreeBody);
719 rotamerOptimization.setUseGoldstein(useGoldstein);
720 rotamerOptimization.setPruning(pruningLevel);
721 rotamerOptimization.setEnergyRestartFile(restartFile);
722 rotamerOptimization.setResidues(residueList);
723 rotamerOptimization.setSingletonClashThreshold(20.0);
724 rotamerOptimization.setPairClashThreshold(20.0);
725
726 double energy;
727 int nRes = residueList.size();
728 if (doOverallOpt) {
729 rotamerOptimization.turnRotamerPairEliminationOff();
730 rotamerOptimization.setTestOverallOpt(true);
731 try {
732 energy = rotamerOptimization.optimize(RotamerOptimization.Algorithm.ALL);
733 } catch (Exception e) {
734 logger.warning(Utilities.stackTraceToString(e));
735 throw e;
736 }
737
738 assertEquals(info + " Total Energy", expectedEnergy, energy, tolerance);
739 }
740
741 if (doSelfOpt) {
742 rotamerOptimization.turnRotamerPairEliminationOff();
743 rotamerOptimization.setTestSelfEnergyEliminations(true);
744 energy = rotamerOptimization.optimize(RotamerOptimization.Algorithm.ALL);
745
746 assertEquals(info + " Self-Energy", expectedSelfEnergy, energy, tolerance);
747
748
749 int[] optimum = rotamerOptimization.getOptimumRotamers();
750
751 EliminatedRotamers eR = rotamerOptimization.getEliminatedRotamers();
752
753
754 for (int i = 0; i < nRes; i++) {
755 Residue res = residueList.get(i);
756 Rotamer[] rotI = res.getRotamers();
757 int nRot = rotI.length;
758
759 int rotCounter = 0;
760 while (rotCounter < nRot && eR.checkPrunedSingles(i, rotCounter)) {
761 rotCounter++;
762 }
763
764 EnergyExpansion eE = rotamerOptimization.getEnergyExpansion();
765 double lowEnergy = eE.getSelf(i, rotCounter);
766 int bestRot = rotCounter;
767 for (int ri = 1; ri < nRot; ri++) {
768 if (!eR.checkPrunedSingles(i, ri)) {
769 double selfEnergy = eE.getSelf(i, ri);
770 if (selfEnergy < lowEnergy) {
771 lowEnergy = selfEnergy;
772 bestRot = ri;
773 }
774 }
775 }
776 assertEquals(format(" %s Self-Energy of residue %d", info, i), optimum[i], bestRot);
777 }
778 }
779
780 if (doPairOpt) {
781 rotamerOptimization.turnRotamerPairEliminationOff();
782 rotamerOptimization.setTestPairEnergyEliminations(pairResidue);
783 energy = rotamerOptimization.optimize(RotamerOptimization.Algorithm.ALL);
784 assertEquals(info + " Pair-Energy", expectedPairEnergy, energy, tolerance);
785
786
787
788 int[] optimum = rotamerOptimization.getOptimumRotamers();
789
790 Residue resI = residueList.get(pairResidue);
791 Rotamer[] rotI = resI.getRotamers();
792 int ni = rotI.length;
793
794 double minEnergy = Double.POSITIVE_INFINITY;
795 int bestRotI = -1;
796
797 EliminatedRotamers eR = rotamerOptimization.getEliminatedRotamers();
798
799
800 for (int ri = 0; ri < ni; ri++) {
801 double energyForRi = 0.0;
802 if (eR.checkPrunedSingles(pairResidue, ri)) {
803 continue;
804 }
805
806 for (int j = 0; j < nRes; j++) {
807 if (j == pairResidue) {
808 continue;
809 }
810 Residue resJ = residueList.get(j);
811 Rotamer[] rotJ = resJ.getRotamers();
812 int nRot = rotJ.length;
813
814 int rj = 0;
815 while (eR.checkPrunedSingles(j, rj) || eR.checkPrunedPairs(pairResidue, ri, j, rj)) {
816 if (++rj >= nRot) {
817 logger.warning("RJ is too large.");
818 }
819 }
820
821 EnergyExpansion eE = rotamerOptimization.getEnergyExpansion();
822 double lowEnergy = eE.get2Body(pairResidue, ri, j, rj);
823
824 for (rj = 1; rj < nRot; rj++) {
825 if (!eR.checkPrunedSingles(j, rj) && !eR.checkPrunedPairs(pairResidue, ri, j, rj)) {
826 double pairEnergy = eE.get2Body(pairResidue, ri, j, rj);
827 if (pairEnergy < lowEnergy) {
828 lowEnergy = pairEnergy;
829 }
830 }
831 }
832 energyForRi += lowEnergy;
833 }
834 if (energyForRi < minEnergy) {
835 minEnergy = energyForRi;
836 bestRotI = ri;
837 }
838 }
839
840 assertEquals(
841 format(
842 " %s Best 2-body energy sum for residue %d is with rotamer %d at %10.4f.",
843 info, pairResidue, bestRotI, minEnergy),
844 optimum[pairResidue],
845 bestRotI);
846
847
848
849 for (int j = 0; j < nRes; j++) {
850 if (j == pairResidue) {
851 continue;
852 }
853 Residue resJ = residueList.get(j);
854 Rotamer[] rotJ = resJ.getRotamers();
855 int nRotJ = rotJ.length;
856
857 int rotCounter = 0;
858 while (eR.checkPrunedPairs(pairResidue, bestRotI, j, rotCounter) && rotCounter < nRotJ) {
859 rotCounter++;
860 }
861
862 EnergyExpansion eE = rotamerOptimization.getEnergyExpansion();
863 double lowEnergy = eE.get2Body(pairResidue, bestRotI, j, rotCounter);
864 int bestRotJ = rotCounter;
865 for (int rj = 1; rj < nRotJ; rj++) {
866 if (!eR.checkPrunedSingles(j, rj) && !eR.checkPrunedPairs(pairResidue, bestRotI, j, rj)) {
867 double pairEnergy = eE.get2Body(pairResidue, bestRotI, j, rj);
868 if (pairEnergy < lowEnergy) {
869 lowEnergy = pairEnergy;
870 bestRotJ = rj;
871 }
872 }
873 }
874 assertEquals(
875 format(
876 " %s Pair-Energy of residue (%d,%d) with residue %d",
877 info, pairResidue, bestRotI, j),
878 optimum[j],
879 bestRotJ);
880 }
881 }
882
883
884 if (doTripleOpt) {
885 rotamerOptimization.turnRotamerPairEliminationOff();
886 rotamerOptimization.setTestTripleEnergyEliminations(tripleResidue1, tripleResidue2);
887 try {
888 energy = rotamerOptimization.optimize(RotamerOptimization.Algorithm.ALL);
889 assertEquals(info + " Triple-Energy", expectedTripleEnergy, energy, tolerance);
890 } catch (Exception e) {
891 e.fillInStackTrace();
892 e.printStackTrace();
893 logger.log(java.util.logging.Level.INFO, "Error in doTripleOpt", e);
894 }
895
896
897
898 int[] optimum = rotamerOptimization.getOptimumRotamers();
899
900
901 Residue resI = residueList.get(tripleResidue1);
902 Rotamer[] rotI = resI.getRotamers();
903 int ni = rotI.length;
904
905
906 Residue resJ = residueList.get(tripleResidue2);
907 Rotamer[] rotJ = resJ.getRotamers();
908 int nj = rotJ.length;
909
910 double minEnergyIJ = Double.POSITIVE_INFINITY;
911 int bestRotI = -1;
912 int bestRotJ = -1;
913
914 EliminatedRotamers eR = rotamerOptimization.getEliminatedRotamers();
915
916 for (int ri = 0; ri < ni; ri++) {
917 if (eR.check(tripleResidue1, ri)) {
918 continue;
919 }
920 for (int rj = 0; rj < nj; rj++) {
921 if (eR.checkPrunedSingles(tripleResidue2, rj)
922 || eR.checkPrunedPairs(tripleResidue1, ri, tripleResidue2, rj)) {
923 continue;
924 }
925 double currentEnergy = 0.0;
926 for (int k = 0; k < nRes; k++) {
927 if (k == tripleResidue1 || k == tripleResidue2) {
928 continue;
929 }
930 Residue resK = residueList.get(k);
931 Rotamer[] rotK = resK.getRotamers();
932 int nk = rotK.length;
933
934 int rkStart = 0;
935 while (eR.checkPrunedSingles(k, rkStart)
936 || eR.checkPrunedPairs(tripleResidue1, ri, k, rkStart)
937 || eR.checkPrunedPairs(tripleResidue2, rj, k, rkStart)) {
938 if (++rkStart >= nk) {
939 logger.warning("RJ is too large.");
940 }
941 }
942
943 EnergyExpansion eE = rotamerOptimization.getEnergyExpansion();
944 double lowEnergy =
945 eE.get3Body(residues, tripleResidue1, ri, tripleResidue2, rj, k, rkStart);
946 for (int rk = rkStart; rk < nk; rk++) {
947 if (!eR.checkPrunedSingles(k, rk)
948 && !eR.checkPrunedPairs(tripleResidue1, ri, k, rk)
949 && !eR.checkPrunedPairs(tripleResidue2, rj, k, rk)) {
950 double tripleEnergy =
951 eE.get3Body(residues, tripleResidue1, ri, tripleResidue2, rj, k, rk);
952 if (tripleEnergy < lowEnergy) {
953 lowEnergy = tripleEnergy;
954 }
955 }
956 }
957 currentEnergy +=
958 lowEnergy;
959 }
960 if (currentEnergy < minEnergyIJ) {
961 minEnergyIJ = currentEnergy;
962 bestRotI = ri;
963 bestRotJ = rj;
964 }
965 }
966 }
967
968 assertEquals(
969 format(
970 " %s Best three-body energy sum for residue %d is with rotamer %d at %10.4f.",
971 info, tripleResidue1, bestRotI, minEnergyIJ),
972 optimum[tripleResidue1],
973 bestRotI);
974
975 assertEquals(
976 format(
977 " %s Best three-body energy sum for residue %d is with rotamer %d at %10.4f.",
978 info, tripleResidue2, bestRotJ, minEnergyIJ),
979 optimum[tripleResidue2],
980 bestRotJ);
981
982
983 for (int k = 0; k < nRes; k++) {
984 if (k == tripleResidue1 || k == tripleResidue2) {
985 continue;
986 }
987 Residue resK = residueList.get(k);
988 Rotamer[] rotK = resK.getRotamers();
989 int nk = rotK.length;
990
991 int rotCounter = 0;
992 while (eR.checkPrunedPairs(tripleResidue1, bestRotI, k, rotCounter)
993 && eR.checkPrunedPairs(tripleResidue2, bestRotJ, k, rotCounter)
994 && rotCounter < nk) {
995 rotCounter++;
996 }
997
998 EnergyExpansion eE = rotamerOptimization.getEnergyExpansion();
999 double lowEnergy =
1000 eE.get3Body(
1001 residues, tripleResidue1, bestRotI, tripleResidue2, bestRotJ, k, rotCounter);
1002 int bestRotK = rotCounter;
1003 for (int rk = 1; rk < nk; rk++) {
1004 if (!eR.checkPrunedSingles(k, rk)
1005 && !eR.checkPrunedPairs(tripleResidue1, bestRotI, k, rk)
1006 && !eR.checkPrunedPairs(tripleResidue2, bestRotJ, k, rk)) {
1007 double tripleEnergy =
1008 eE.get3Body(residues, tripleResidue1, bestRotI, tripleResidue2, bestRotJ, k, rk);
1009 if (tripleEnergy < lowEnergy) {
1010 lowEnergy = tripleEnergy;
1011 bestRotK = rk;
1012 }
1013 }
1014 }
1015 assertEquals(
1016 format(
1017 " %s Triple-Energy of residue (%d,%d) and residue (%d,%d) with residue %d",
1018 info, tripleResidue1, bestRotI, tripleResidue2, bestRotJ, k),
1019 optimum[k],
1020 bestRotK);
1021 }
1022 }
1023 }
1024
1025
1026 private void load() {
1027 String structure = getResourcePath(filename);
1028 restartFile = getResourceFile(restartName);
1029 PotentialsUtils potentialUtils = new PotentialsUtils();
1030 molecularAssembly = potentialUtils.openQuietly(structure);
1031 forceFieldEnergy = molecularAssembly.getPotentialEnergy();
1032 }
1033 }