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