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.IntegerSchedule;
42 import edu.rit.pj.ParallelRegion;
43 import ffx.algorithms.AlgorithmListener;
44 import ffx.crystal.Crystal;
45 import ffx.crystal.SymOp;
46 import ffx.potential.MolecularAssembly;
47 import ffx.potential.bonded.Residue;
48 import ffx.potential.bonded.Rotamer;
49 import ffx.potential.bonded.RotamerLibrary;
50 import java.util.logging.Level;
51 import java.util.logging.Logger;
52
53
54 public class DistanceRegion extends ParallelRegion {
55
56 private static final Logger logger = Logger.getLogger(DistanceRegion.class.getName());
57 private final DistanceLoop[] distanceLoops;
58 private final int nResidues;
59 private final Crystal crystal;
60 private final int nSymm;
61 private final int[][][] lists;
62 private final IntegerSchedule pairwiseSchedule;
63
64
65
66 protected AlgorithmListener algorithmListener;
67
68
69
70 private DistanceMatrix dM;
71
72
73
74 private MolecularAssembly molecularAssembly;
75
76
77
78
79 private Residue[] allResiduesArray;
80
81
82
83
84
85
86 private double[][][][] distanceMatrix;
87
88 public DistanceRegion(
89 int nt, int nResidues, Crystal crystal, int[][][] lists, IntegerSchedule schedule) {
90 distanceLoops = new DistanceLoop[nt];
91 this.nResidues = nResidues;
92 this.crystal = crystal;
93 this.nSymm = crystal.spaceGroup.getNumberOfSymOps();
94 this.lists = lists;
95 for (int i = 0; i < nt; i++) {
96 distanceLoops[i] = new DistanceLoop();
97 }
98 pairwiseSchedule = schedule;
99 }
100
101 public void init(
102 DistanceMatrix dM,
103 MolecularAssembly molecularAssembly,
104 Residue[] allResiduesArray,
105 AlgorithmListener algorithmListener,
106 double[][][][] distanceMatrix) {
107 this.dM = dM;
108 this.molecularAssembly = molecularAssembly;
109 this.allResiduesArray = allResiduesArray;
110 this.algorithmListener = algorithmListener;
111 this.distanceMatrix = distanceMatrix;
112 }
113
114 @Override
115 public void run() {
116 try {
117 int threadID = getThreadIndex();
118 execute(0, nResidues - 1, distanceLoops[threadID]);
119 } catch (Exception e) {
120 String message = " Exception computing residue-residue distances.";
121 logger.log(Level.SEVERE, message, e);
122 }
123 }
124
125
126
127
128
129
130
131
132
133 private double[][] getCoordinates(int i, Residue[] residues, Rotamer rotamer) {
134 synchronized (residues[i]) {
135 Residue residue = residues[i];
136 RotamerLibrary.applyRotamer(residue, rotamer);
137 return residue.storeCoordinateArray();
138 }
139 }
140
141 private class DistanceLoop extends IntegerForLoop {
142
143 @Override
144 public void run(int lb, int ub) {
145
146 for (int iSymOp = 0; iSymOp < nSymm; iSymOp++) {
147 SymOp symOp = crystal.spaceGroup.getSymOp(iSymOp);
148
149 for (int i = lb; i <= ub; i++) {
150 Residue residueI = allResiduesArray[i];
151 Rotamer[] rotamersI = residueI.getRotamers();
152 int lengthRi = rotamersI.length;
153 int[] list = lists[iSymOp][i];
154
155 for (int ri = 0; ri < lengthRi; ri++) {
156 double[][] xi = getCoordinates(i, allResiduesArray, rotamersI[ri]);
157
158 for (int j : list) {
159 if (i == j) {
160 continue;
161 }
162
163 Residue residueJ = allResiduesArray[j];
164 Rotamer[] rotamersJ = residueJ.getRotamers();
165 int lengthRj = rotamersJ.length;
166
167
168 for (int rj = 0; rj < lengthRj; rj++) {
169 double[][] xj = getCoordinates(j, allResiduesArray, rotamersJ[rj]);
170 if (getThreadIndex() == 0 && algorithmListener != null) {
171 algorithmListener.algorithmUpdate(molecularAssembly);
172 }
173 double r = dM.interResidueDistance(xi, xj, symOp);
174 if (i < j) {
175 if (r < distanceMatrix[i][ri][j][rj]) {
176 distanceMatrix[i][ri][j][rj] = r;
177 }
178 } else if (r < distanceMatrix[j][rj][i][ri]) {
179 distanceMatrix[j][rj][i][ri] = r;
180 }
181 }
182 }
183 }
184 }
185 }
186 }
187
188 @Override
189 public IntegerSchedule schedule() {
190 return pairwiseSchedule;
191 }
192 }
193 }