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