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 private DistanceMatrix.NeighborDistances[][] distanceMatrix;
85
86 public DistanceRegion(
87 int nt, int nResidues, Crystal crystal, int[][][] lists, IntegerSchedule schedule) {
88 distanceLoops = new DistanceLoop[nt];
89 this.nResidues = nResidues;
90 this.crystal = crystal;
91 this.nSymm = crystal.spaceGroup.getNumberOfSymOps();
92 this.lists = lists;
93 for (int i = 0; i < nt; i++) {
94 distanceLoops[i] = new DistanceLoop();
95 }
96 pairwiseSchedule = schedule;
97 }
98
99 public void init(
100 DistanceMatrix dM,
101 MolecularAssembly molecularAssembly,
102 Residue[] allResiduesArray,
103 AlgorithmListener algorithmListener,
104 DistanceMatrix.NeighborDistances[][] distanceMatrix) {
105 this.dM = dM;
106 this.molecularAssembly = molecularAssembly;
107 this.allResiduesArray = allResiduesArray;
108 this.algorithmListener = algorithmListener;
109 this.distanceMatrix = distanceMatrix;
110 }
111
112 @Override
113 public void run() {
114 try {
115 int threadID = getThreadIndex();
116 execute(0, nResidues - 1, distanceLoops[threadID]);
117 } catch (Exception e) {
118 String message = " Exception computing residue-residue distances.";
119 logger.log(Level.SEVERE, message, e);
120 }
121 }
122
123
124
125
126
127
128
129
130
131 private double[][] getCoordinates(int i, Residue[] residues, Rotamer rotamer) {
132 synchronized (residues[i]) {
133 Residue residue = residues[i];
134 RotamerLibrary.applyRotamer(residue, rotamer);
135 return residue.storeCoordinateArray();
136 }
137 }
138
139 private class DistanceLoop extends IntegerForLoop {
140
141 @Override
142 public void run(int lb, int ub) {
143
144 for (int iSymOp = 0; iSymOp < nSymm; iSymOp++) {
145 SymOp symOp = crystal.spaceGroup.getSymOp(iSymOp);
146
147 for (int i = lb; i <= ub; i++) {
148 Residue residueI = allResiduesArray[i];
149 Rotamer[] rotamersI = residueI.getRotamers();
150 int lengthRi = rotamersI.length;
151 int[] list = lists[iSymOp][i];
152
153 for (int ri = 0; ri < lengthRi; ri++) {
154 double[][] xi = getCoordinates(i, allResiduesArray, rotamersI[ri]);
155
156 for (int j : list) {
157 if (i == j) {
158 continue;
159 }
160 Residue residueJ = allResiduesArray[j];
161 Rotamer[] rotamersJ = residueJ.getRotamers();
162 int lengthRj = rotamersJ.length;
163
164 for (int rj = 0; rj < lengthRj; rj++) {
165 double[][] xj = getCoordinates(j, allResiduesArray, rotamersJ[rj]);
166 if (getThreadIndex() == 0 && algorithmListener != null) {
167 algorithmListener.algorithmUpdate(molecularAssembly);
168 }
169 double r = dM.interResidueDistance(xi, xj, symOp);
170 if (i < j) {
171 distanceMatrix[i][ri].storeDistance(j, rj, r);
172 } else {
173 distanceMatrix[j][rj].storeDistance(i, ri, r);
174 }
175 }
176 }
177 }
178 }
179 }
180 }
181
182 @Override
183 public IntegerSchedule schedule() {
184 return pairwiseSchedule;
185 }
186 }
187 }