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.utils;
39
40 import ffx.potential.ForceFieldEnergy;
41 import ffx.potential.MolecularAssembly;
42 import ffx.potential.Utilities;
43 import ffx.potential.bonded.RotamerLibrary;
44 import ffx.potential.parameters.ForceField;
45 import ffx.potential.parsers.ARCFileFilter;
46 import ffx.potential.parsers.FileOpener;
47 import ffx.potential.parsers.ForceFieldFilter;
48 import ffx.potential.parsers.INTFileFilter;
49 import ffx.potential.parsers.INTFilter;
50 import ffx.potential.parsers.PDBFileFilter;
51 import ffx.potential.parsers.PDBFilter;
52 import ffx.potential.parsers.PDBFilter.Mutation;
53 import ffx.potential.parsers.SystemFilter;
54 import ffx.potential.parsers.XYZFileFilter;
55 import ffx.potential.parsers.XYZFilter;
56 import ffx.utilities.Keyword;
57 import org.apache.commons.configuration2.CompositeConfiguration;
58 import org.apache.commons.io.FilenameUtils;
59
60 import java.io.File;
61 import java.io.IOException;
62 import java.nio.file.Path;
63 import java.nio.file.Paths;
64 import java.util.ArrayList;
65 import java.util.List;
66 import java.util.logging.Level;
67 import java.util.logging.Logger;
68
69 import static java.lang.String.format;
70
71
72
73
74
75
76
77
78
79 public class PotentialsFileOpener implements FileOpener {
80
81 private static final Logger logger = Logger.getLogger(PotentialsFileOpener.class.getName());
82 private final File file;
83 private final Path filepath;
84 private final File[] allFiles;
85 private final Path[] allPaths;
86 private int nThreads = -1;
87 private final List<MolecularAssembly> assemblies;
88 private final List<CompositeConfiguration> propertyList;
89
90 private MolecularAssembly activeAssembly;
91 private CompositeConfiguration activeProperties;
92 private SystemFilter filter;
93 private List<Mutation> mutationsToApply;
94
95
96
97
98
99
100 public PotentialsFileOpener(File file) {
101 if (!file.exists() || !file.isFile()) {
102 throw new IllegalArgumentException(
103 String.format(" File %s either did not exist or was not a file.", file.getName()));
104 }
105 this.file = file;
106 Path pwdPath;
107 Path absPath;
108 try {
109 pwdPath = Paths.get(new File("").getCanonicalPath());
110 } catch (IOException ex) {
111 pwdPath = Paths.get(new File("").getAbsolutePath());
112 }
113 try {
114 absPath = Paths.get(file.getCanonicalPath());
115 } catch (IOException ex) {
116 absPath = Paths.get(file.getAbsolutePath());
117 }
118 filepath = pwdPath.relativize(absPath);
119 allFiles = new File[1];
120 allFiles[0] = this.file;
121 allPaths = new Path[1];
122 allPaths[0] = this.filepath;
123 assemblies = new ArrayList<>();
124 propertyList = new ArrayList<>();
125 }
126
127
128
129
130
131
132 PotentialsFileOpener(String filename) {
133 this(new File(filename));
134 }
135
136
137
138
139
140
141 PotentialsFileOpener(String[] filenames) {
142 if (filenames == null) {
143 throw new IllegalArgumentException(" Array of files to be opened was null.");
144 }
145 int numFiles = filenames.length;
146 if (numFiles == 0) {
147 throw new IllegalArgumentException(" Array of files to be opened was empty.");
148 }
149
150 List<File> fileList = new ArrayList<>();
151 List<Path> pathList = new ArrayList<>();
152 Path pwdPath;
153 try {
154 pwdPath = Paths.get(new File("").getCanonicalPath());
155 } catch (IOException ex) {
156 pwdPath = Paths.get(new File("").getAbsolutePath());
157 }
158 for (String filename : filenames) {
159 try {
160 File tryFile = new File(filename);
161 if (!(tryFile.exists() && tryFile.isFile())) {
162 continue;
163 }
164 Path absPath;
165 try {
166 absPath = Paths.get(tryFile.getCanonicalPath());
167 } catch (IOException ex) {
168 absPath = Paths.get(tryFile.getAbsolutePath());
169 }
170 Path thisPath = pwdPath.relativize(absPath);
171 fileList.add(tryFile);
172 pathList.add(thisPath);
173 } catch (Exception ex) {
174
175 }
176 }
177 int numAccepted = fileList.size();
178 if (numAccepted < 1) {
179 throw new IllegalArgumentException(" No valid files could be found to open.");
180 }
181 allFiles = fileList.toArray(new File[numAccepted]);
182 allPaths = pathList.toArray(new Path[numAccepted]);
183 this.file = allFiles[0];
184 this.filepath = allPaths[0];
185 assemblies = new ArrayList<>();
186 propertyList = new ArrayList<>();
187 }
188
189
190
191
192
193
194 @Override
195 public MolecularAssembly[] getAllAssemblies() {
196 return assemblies.toArray(new MolecularAssembly[0]);
197 }
198
199
200
201
202
203
204 @Override
205 public CompositeConfiguration[] getAllProperties() {
206 return propertyList.toArray(new CompositeConfiguration[0]);
207 }
208
209
210
211
212
213
214 @Override
215 public MolecularAssembly getAssembly() {
216 return activeAssembly;
217 }
218
219
220
221
222
223
224 public SystemFilter getFilter() {
225 return filter;
226 }
227
228
229
230
231
232
233 @Override
234 public CompositeConfiguration getProperties() {
235 return activeProperties;
236 }
237
238
239
240
241
242
243
244 @Override
245 public void run() {
246 int numFiles = allFiles.length;
247 for (int i = 0; i < numFiles; i++) {
248 File fileI = allFiles[i];
249 Path pathI = allPaths[i];
250 MolecularAssembly assembly = new MolecularAssembly(pathI.toString());
251 assembly.setFile(fileI);
252 CompositeConfiguration properties = Keyword.loadProperties(fileI);
253 ForceFieldFilter forceFieldFilter = new ForceFieldFilter(properties);
254 ForceField forceField = forceFieldFilter.parse();
255 String[] patches = properties.getStringArray("patch");
256 for (String patch : patches) {
257 logger.info(" Attempting to read force field patch from " + patch + ".");
258 CompositeConfiguration patchConfiguration = new CompositeConfiguration();
259 try {
260 patchConfiguration.addProperty("propertyFile", fileI.getCanonicalPath());
261 } catch (IOException e) {
262 logger.log(Level.INFO, " Error loading {0}.", patch);
263 }
264 patchConfiguration.addProperty("parameters", patch);
265 forceFieldFilter = new ForceFieldFilter(patchConfiguration);
266 ForceField patchForceField = forceFieldFilter.parse();
267 forceField.append(patchForceField);
268 if (RotamerLibrary.addRotPatch(patch)) {
269 logger.info(format(" Loaded rotamer definitions from patch %s.", patch));
270 }
271 }
272 assembly.setForceField(forceField);
273 if (new PDBFileFilter().acceptDeep(fileI)) {
274 filter = new PDBFilter(fileI, assembly, forceField, properties);
275 } else if (new XYZFileFilter().acceptDeep(fileI)) {
276 filter = new XYZFilter(fileI, assembly, forceField, properties);
277 } else if (new INTFileFilter().acceptDeep(fileI) || new ARCFileFilter().accept(fileI)) {
278 filter = new INTFilter(fileI, assembly, forceField, properties);
279 } else {
280 throw new IllegalArgumentException(
281 format(" File %s could not be recognized as a valid PDB, XYZ, INT, or ARC file.",
282 pathI));
283 }
284
285
286 if (mutationsToApply != null && !mutationsToApply.isEmpty()) {
287 if (!(filter instanceof PDBFilter)) {
288 throw new UnsupportedOperationException(
289 "Applying mutations during open only supported by PDB filter atm.");
290 }
291 ((PDBFilter) filter).mutate(mutationsToApply);
292 }
293
294 if (filter.readFile()) {
295 if (!(filter instanceof PDBFilter)) {
296 Utilities.biochemistry(assembly, filter.getAtomList());
297 }
298 filter.applyAtomProperties();
299 assembly.finalize(true, forceField);
300 ForceFieldEnergy energy;
301 if (nThreads > 0) {
302 energy = ForceFieldEnergy.energyFactory(assembly, nThreads);
303 } else {
304 energy = ForceFieldEnergy.energyFactory(assembly);
305 }
306 assembly.setPotential(energy);
307 assemblies.add(assembly);
308 propertyList.add(properties);
309
310 if (filter instanceof PDBFilter pdbFilter) {
311 List<Character> altLocs = pdbFilter.getAltLocs();
312 if (altLocs.size() > 1 || altLocs.get(0) != ' ') {
313 StringBuilder altLocString = new StringBuilder("\n Alternate locations found [ ");
314 for (Character c : altLocs) {
315
316 if (c == ' ') {
317 continue;
318 }
319 altLocString.append(format("(%s) ", c));
320 }
321 altLocString.append("]\n");
322 logger.info(altLocString.toString());
323 }
324
325
326
327
328
329 for (Character c : altLocs) {
330 if (c.equals(' ') || c.equals('A')) {
331 continue;
332 }
333 MolecularAssembly newAssembly = new MolecularAssembly(pathI.toString());
334 newAssembly.setFile(fileI);
335 newAssembly.setForceField(assembly.getForceField());
336 pdbFilter.setAltID(newAssembly, c);
337 pdbFilter.clearSegIDs();
338 if (pdbFilter.readFile()) {
339 String fileName = assembly.getFile().getAbsolutePath();
340 newAssembly.setName(FilenameUtils.getBaseName(fileName) + " " + c);
341 filter.applyAtomProperties();
342 newAssembly.finalize(true, assembly.getForceField());
343 if (nThreads > 0) {
344 energy = ForceFieldEnergy.energyFactory(assembly, nThreads);
345 } else {
346 energy = ForceFieldEnergy.energyFactory(assembly);
347 }
348 newAssembly.setPotential(energy);
349 assemblies.add(newAssembly);
350 }
351 }
352 }
353 } else {
354 logger.warning(String.format(" Failed to read file %s", fileI));
355 }
356 }
357 activeAssembly = assemblies.get(0);
358 activeProperties = propertyList.get(0);
359 }
360
361
362
363
364
365
366 void setMutations(List<Mutation> mutations) {
367 mutationsToApply = mutations;
368 }
369
370
371
372
373
374
375 void setNThreads(int nThreads) {
376 this.nThreads = nThreads;
377 }
378 }