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.potential.parsers;
39
40 import static java.lang.Double.parseDouble;
41 import static java.lang.String.format;
42 import static java.lang.System.arraycopy;
43
44 import ffx.numerics.math.RunningStatistics;
45 import java.io.BufferedReader;
46 import java.io.BufferedWriter;
47 import java.io.File;
48 import java.io.FileReader;
49 import java.io.FileWriter;
50 import java.io.IOException;
51 import java.util.Arrays;
52 import java.util.Collections;
53 import java.util.List;
54 import java.util.logging.Logger;
55
56
57
58
59
60
61
62 public class DistanceMatrixFilter {
63
64 private static final Logger logger = Logger.getLogger(DistanceMatrixFilter.class.getName());
65
66
67
68
69 public DistanceMatrixFilter() {
70 }
71
72 private int nRows = 0;
73 private int nColumns = 0;
74 private boolean fillDistanceMatrix = false;
75 private double[][] distanceMatrix = null;
76
77
78
79
80
81
82 public int getRestartRow() {
83 return nRows;
84 }
85
86
87
88
89
90
91 public int getRestartColumn() {
92 return nColumns;
93 }
94
95
96
97
98
99
100
101
102
103 public RunningStatistics readDistanceMatrix(String filename, List<double[]> distanceList) {
104 fillDistanceMatrix = true;
105 RunningStatistics runningStatistics = readDistanceMatrix(filename, -1, -1);
106 if (distanceMatrix != null) {
107 int size = distanceMatrix[0].length;
108 boolean square = true;
109 for (int i = 0; i < size; i++) {
110 if (distanceMatrix[i] == null || distanceMatrix[i].length != size) {
111 square = false;
112 break;
113 }
114 }
115
116 if (square) {
117
118 Collections.addAll(distanceList, distanceMatrix);
119 } else {
120
121 for (int i = 0; i < size; i++) {
122 double[] row = new double[size];
123
124 for (int j = 0; j < i; j++) {
125 double[] previousRow = distanceList.get(j);
126 row[j] = previousRow[i];
127 }
128
129 arraycopy(distanceMatrix[i], 0, row, i, size - i);
130 distanceList.add(row);
131 }
132 }
133 }
134
135
136 distanceMatrix = null;
137 fillDistanceMatrix = false;
138 return runningStatistics;
139 }
140
141
142
143
144
145
146
147
148
149 public RunningStatistics readDistanceMatrix(String filename, int expectedRows,
150 int expectedColumns) {
151
152 if (filename == null) {
153 return null;
154 }
155
156 File distanceMatrixFile = new File(filename);
157 if (!distanceMatrixFile.exists() || !distanceMatrixFile.canRead()) {
158 return null;
159 }
160
161
162 try (FileReader fr = new FileReader(distanceMatrixFile); BufferedReader br = new BufferedReader(
163 fr)) {
164
165 String data = br.readLine();
166
167
168 while (data != null && data.trim().isEmpty()) {
169 data = br.readLine();
170 }
171
172 if (data == null) {
173 logger.info(format("\n No data in RMSD file %s.", distanceMatrixFile));
174 return null;
175 }
176
177 String[] tokens = data.trim().split(" +");
178 nColumns = tokens.length;
179
180
181
182 if (expectedRows == -1) {
183 expectedRows = nColumns;
184 }
185 if (expectedColumns == -1) {
186 expectedColumns = nColumns;
187 }
188
189 if (nColumns != expectedColumns) {
190 logger.info(
191 format("\n Unexpected number of entries (%d) in the first row of the RMSD file %s.",
192 nColumns, distanceMatrixFile));
193 return null;
194 }
195
196 if (fillDistanceMatrix) {
197 distanceMatrix = new double[expectedRows][];
198 }
199
200 RunningStatistics runningStatistics = new RunningStatistics();
201
202
203 for (int i = 0; i < expectedRows; i++) {
204 double[] row = new double[nColumns];
205 for (int j = 0; j < nColumns; j++) {
206 row[j] = parseDouble(tokens[j]);
207 runningStatistics.addValue(row[j]);
208 }
209
210
211 if (distanceMatrix != null && distanceMatrix.length > i) {
212 distanceMatrix[i] = row;
213 }
214
215 nRows = i + 1;
216
217
218 data = br.readLine();
219 if (data != null) {
220 tokens = data.trim().split(" +");
221 } else {
222 break;
223 }
224
225 nColumns = tokens.length;
226 }
227 return runningStatistics;
228
229 } catch (IOException e) {
230 logger.info(format(" Exception reading %s:\n %s", distanceMatrixFile, e));
231 return null;
232 }
233 }
234
235
236
237
238
239
240
241 public static String toDistanceMatrixString(List<double[]> distanceMatrix) {
242
243 if (distanceMatrix == null) {
244 return null;
245 }
246
247 StringBuilder sb = new StringBuilder("\n Distance Matrix:\n");
248 for (double[] row : distanceMatrix) {
249 sb.append(" ");
250 for (int j = 0; j < row.length; j++) {
251 if (row[j] == -2.0) {
252 sb.append(format("%6.4f", Double.NaN));
253 } else {
254 sb.append(format("%6.4f", row[j]));
255 }
256 if (j == row.length - 1) {
257 sb.append("\n");
258 } else {
259 sb.append(" ");
260 }
261 }
262 }
263
264 return sb.toString();
265 }
266
267
268
269
270
271
272
273 public static String toDistanceMatrixString(double[][] distanceMatrix) {
274 return toDistanceMatrixString(Arrays.asList(distanceMatrix));
275 }
276
277
278
279
280
281
282
283
284 public static boolean writeDistanceMatrix(String filename, List<double[]> distanceMatrix) {
285
286 if (distanceMatrix == null) {
287 return false;
288 }
289
290 for (double[] row : distanceMatrix) {
291 boolean success = writeDistanceMatrixRow(filename, row, 0);
292 if (!success) {
293 return false;
294 }
295 }
296
297 return true;
298 }
299
300
301
302
303
304
305
306
307
308 public static boolean writeDistanceMatrixRow(String filename, double[] distanceMatrixRow,
309 int firstColumn) {
310
311 if (filename == null) {
312 return false;
313 }
314
315 File distanceMatrixFile = new File(filename);
316
317
318 if (distanceMatrixFile == null || distanceMatrixRow == null) {
319 return false;
320 }
321
322
323 try (FileWriter fw = new FileWriter(distanceMatrixFile,
324 true); BufferedWriter bw = new BufferedWriter(fw)) {
325 int nColumn = distanceMatrixRow.length;
326 for (int column = firstColumn; column < nColumn; column++) {
327 bw.write(format("%16.14f", distanceMatrixRow[column]));
328 if (column < nColumn - 1) {
329 bw.write(" ");
330 }
331 }
332 bw.write("\n");
333 } catch (Exception e) {
334 logger.info(format(" Exception writing to %s:\n %s", distanceMatrixFile, e));
335 return false;
336 }
337
338 return true;
339 }
340 }