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