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.manybody;
39
40 import edu.rit.pj.IntegerForLoop;
41 import edu.rit.pj.ParallelRegion;
42 import edu.rit.pj.reduction.SharedDouble;
43 import ffx.algorithms.optimize.RotamerOptimization;
44 import ffx.potential.bonded.Residue;
45
46 import java.util.ArrayList;
47 import java.util.Arrays;
48 import java.util.logging.Level;
49 import java.util.logging.Logger;
50 import java.util.stream.IntStream;
51
52 import static java.lang.Double.isFinite;
53 import static java.lang.String.format;
54
55 public class GoldsteinPairRegion extends ParallelRegion {
56
57 private static final Logger logger = Logger.getLogger(GoldsteinPairRegion.class.getName());
58
59 private RotamerOptimization rotamerOptimization;
60 private Residue[] residues;
61 private int i, riA, rjC;
62 private int j, riB, rjD;
63 private int[] possK;
64 private int nK;
65 private final GoldsteinRotamerPairLoop[] goldsteinRotamerPairLoop;
66 private final SharedDouble sharedSumOverK = new SharedDouble();
67 private ArrayList<Residue> blockedResidues;
68
69 public GoldsteinPairRegion(int nThreads) {
70 goldsteinRotamerPairLoop = new GoldsteinRotamerPairLoop[nThreads];
71 }
72
73 public void finish() {
74 for (GoldsteinRotamerPairLoop rotamerPairLoop : goldsteinRotamerPairLoop) {
75 blockedResidues.addAll(rotamerPairLoop.blockedResidues);
76 }
77 }
78
79 public ArrayList<Residue> getMissedResidues() {
80 return blockedResidues;
81 }
82
83 public double getSumOverK() {
84 return sharedSumOverK.get();
85 }
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100 public void init(Residue[] residues, int i, int riA, int riB, int j, int rjC, int rjD,
101 int[][] bidiResNeighbors, RotamerOptimization rotamerOptimization) {
102 this.residues = residues;
103 this.i = i;
104 this.riA = riA;
105 this.riB = riB;
106 this.j = j;
107 this.rjC = rjC;
108 this.rjD = rjD;
109 this.rotamerOptimization = rotamerOptimization;
110 int[] nI = bidiResNeighbors[i];
111 int[] nJ = bidiResNeighbors[j];
112 IntStream kStream = IntStream.concat(Arrays.stream(nI), Arrays.stream(nJ));
113 possK = kStream.distinct().filter(k -> (k != i && k != j)).sorted().toArray();
114 nK = possK.length;
115 }
116
117 @Override
118 public void run() {
119 int threadID = getThreadIndex();
120 if (goldsteinRotamerPairLoop[threadID] == null) {
121 goldsteinRotamerPairLoop[threadID] = new GoldsteinRotamerPairLoop();
122 }
123 try {
124 execute(0, nK - 1, goldsteinRotamerPairLoop[threadID]);
125 } catch (Exception e) {
126 logger.log(Level.WARNING, " Exception in GoldsteinPairRegion.", e);
127 }
128 }
129
130 public void start() {
131 sharedSumOverK.set(0.0);
132 blockedResidues = new ArrayList<>();
133 }
134
135 private class GoldsteinRotamerPairLoop extends IntegerForLoop {
136
137 double sumOverK;
138 ArrayList<Residue> blockedResidues;
139
140 @Override
141 public void finish() {
142 sharedSumOverK.addAndGet(sumOverK);
143 }
144
145 @Override
146 public void run(int lb, int ub) {
147 if (blockedResidues.isEmpty()) {
148 double locSumOverK = rotamerOptimization.goldsteinPairSumOverK(residues, lb, ub, i, riA, riB,
149 j, rjC, rjD, blockedResidues, possK);
150
151 if (isFinite(locSumOverK) && blockedResidues.isEmpty()) {
152 sumOverK += locSumOverK;
153 } else {
154 sumOverK = 0;
155 }
156 } else {
157 rotamerOptimization.logIfRank0(
158 format(" Skipping %d to %d because we cannot eliminate", lb, ub), Level.FINE);
159 }
160 }
161
162 @Override
163 public void start() {
164 sumOverK = 0.0;
165 blockedResidues = new ArrayList<>();
166 }
167 }
168 }