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 ffx.potential.MolecularAssembly;
41 import ffx.potential.Utilities.FileType;
42 import ffx.potential.bonded.Atom;
43 import ffx.potential.bonded.Bond;
44 import ffx.potential.parameters.ForceField;
45 import org.apache.commons.configuration2.CompositeConfiguration;
46
47 import java.io.File;
48 import java.util.ArrayList;
49 import java.util.HashSet;
50 import java.util.List;
51 import java.util.OptionalDouble;
52 import java.util.Set;
53 import java.util.Vector;
54 import java.util.logging.Level;
55 import java.util.logging.Logger;
56 import java.util.regex.Pattern;
57
58 import static ffx.utilities.StringUtils.parseAtomRange;
59 import static java.lang.String.format;
60
61
62
63
64
65
66
67 public abstract class SystemFilter {
68
69 protected static final Pattern lambdaPattern = Pattern.compile("Lambda: +([01]\\.\\d+)");
70 private static final Logger logger = Logger.getLogger(SystemFilter.class.getName());
71 private static Versioning vers = Versioning.TINKER;
72 private static int absoluteCounter = 0;
73
74
75
76 protected final boolean dieOnMissingAtom;
77
78
79
80 protected final boolean standardizeAtomNames;
81
82
83
84
85 protected final boolean vdwH;
86
87
88
89 protected List<Atom> atomList = null;
90
91
92
93 protected List<Bond> bondList = null;
94
95
96
97
98 protected List<MolecularAssembly> systems = new Vector<>();
99
100
101
102 protected List<File> files;
103
104
105
106 protected FileType fileType = FileType.UNK;
107
108
109
110 protected CompositeConfiguration properties;
111
112
113
114 protected ForceField forceField;
115
116
117
118 protected boolean fileRead = false;
119
120
121
122
123 MolecularAssembly activeMolecularAssembly;
124
125
126
127 File currentFile = null;
128
129
130
131
132
133
134
135 private SystemFilter(ForceField forceField, CompositeConfiguration properties) {
136 this.forceField = forceField;
137 this.properties = properties;
138 if (properties != null) {
139 vdwH = properties.getBoolean("vdwHydrogens", false);
140 dieOnMissingAtom = properties.getBoolean("trajectory-dieOnMissing", false);
141 standardizeAtomNames = properties.getBoolean("standardizeAtomNames", true);
142 } else {
143 vdwH = false;
144 dieOnMissingAtom = false;
145 standardizeAtomNames = true;
146 }
147 }
148
149
150
151
152
153
154
155
156
157
158 public SystemFilter(List<File> files, MolecularAssembly molecularAssembly, ForceField forceField,
159 CompositeConfiguration properties) {
160 this(forceField, properties);
161 this.files = files;
162 if (files != null) {
163 this.currentFile = files.get(0);
164 }
165 this.activeMolecularAssembly = molecularAssembly;
166 }
167
168
169
170
171
172
173
174
175
176
177 public SystemFilter(File file, MolecularAssembly molecularAssembly, ForceField forceField,
178 CompositeConfiguration properties) {
179 this(forceField, properties);
180 files = new ArrayList<>();
181 if (file != null) {
182 files.add(file);
183 }
184 this.currentFile = file;
185 this.activeMolecularAssembly = molecularAssembly;
186 }
187
188
189
190
191
192
193
194
195
196
197 public SystemFilter(File file, List<MolecularAssembly> molecularAssemblies, ForceField forceField,
198 CompositeConfiguration properties) {
199 this(forceField, properties);
200 files = new ArrayList<>();
201 if (file != null) {
202 files.add(file);
203 }
204 this.currentFile = file;
205 this.systems = new ArrayList<>(molecularAssemblies);
206 this.activeMolecularAssembly = systems.get(0);
207 }
208
209
210
211
212
213
214
215 public static File previousVersion(File file) {
216 if (file == null) {
217 return null;
218 }
219 String fileName = file.getAbsolutePath();
220 int dot = file.getAbsolutePath().lastIndexOf(".");
221 int under = file.getAbsolutePath().lastIndexOf("_");
222 File newFile = file;
223 if (under > dot) {
224 String name = fileName.substring(0, under);
225 newFile = new File(name);
226 }
227 File baseFile = newFile;
228 File previousFile = null;
229 int i = 1;
230 while (newFile.exists()) {
231 i = i + 1;
232 previousFile = newFile;
233 newFile = baseFile;
234 int thousand = i / 1000;
235 int hundred = (i - 1000 * thousand) / 100;
236 int tens = (i - 1000 * thousand - 100 * hundred) / 10;
237 int ones = i - 1000 * thousand - 100 * hundred - 10 * tens;
238 StringBuilder newFileString = new StringBuilder(baseFile.getAbsolutePath());
239 if (thousand != 0) {
240 newFileString.append('_').append(thousand).append(hundred).append(tens).append(ones);
241 } else if (hundred != 0) {
242 newFileString.append('_').append(hundred).append(tens).append(ones);
243 } else if (tens != 0) {
244 newFileString.append('_').append(tens).append(ones);
245 } else {
246 newFileString.append('_').append(ones);
247 }
248 newFile = new File(newFileString.toString());
249 }
250 return previousFile;
251 }
252
253
254
255
256
257
258 public static void setVersioning(Versioning vers) {
259 SystemFilter.vers = vers;
260 }
261
262
263
264
265
266
267
268 public static File version(File file) {
269 if (vers == Versioning.TINKER) {
270 return versionTinker(file);
271 } else {
272 if (vers == Versioning.PREFIX_ABSOLUTE || vers == Versioning.POSTFIX_ABSOLUTE) {
273 return versionAbsolute(file, (vers == Versioning.PREFIX_ABSOLUTE));
274 } else {
275 return version(file, (vers == Versioning.PREFIX));
276 }
277 }
278 }
279
280 private static File version(File file, boolean prefix) {
281 if (file == null || !(file.exists())) {
282 return file;
283 }
284 String fn = file.getAbsolutePath();
285 int dot = fn.lastIndexOf(".");
286 int under = fn.lastIndexOf("_");
287 if (dot < 0) {
288 fn += ".unk";
289 dot = fn.lastIndexOf(".");
290 }
291 if (under < 0) {
292 under = dot;
293 }
294 String name = (prefix) ? fn.substring(0, under) : fn.substring(0, dot);
295 String extension = (prefix) ? fn.substring(dot + 1) : fn.substring(dot + 1, under);
296 int number = 0;
297 String newFn = (prefix) ? format("%s_%d.%s", name, number, extension)
298 : format("%s.%s_%d", name, extension, number);
299 if (prefix && under < dot) {
300 try {
301 number = Integer.parseInt(fn.substring(under + 1, dot));
302 } catch (NumberFormatException ex) {
303
304 name = fn.substring(0, dot);
305 number++;
306 newFn = format("%s_%d.%s", name, number, extension);
307 }
308 } else if (!prefix && under > dot) {
309 try {
310 number = Integer.parseInt(fn.substring(under + 1));
311 number++;
312 } catch (NumberFormatException ex) {
313
314 }
315 }
316 File newFile = new File(newFn);
317 while (newFile.exists()) {
318 ++number;
319 newFn = (prefix) ? format("%s_%d.%s", name, number, extension)
320 : format("%s.%s_%d", name, extension, number);
321 newFile = new File(newFn);
322 }
323 return newFile;
324 }
325
326 private static synchronized File versionAbsolute(File file, boolean prefix) {
327 if (file == null || !(file.exists())) {
328 return file;
329 }
330 String fn = file.getAbsolutePath();
331 int dot = fn.lastIndexOf(".");
332 int under = fn.lastIndexOf("_");
333 if (dot < 0) {
334 fn += ".unk";
335 dot = fn.lastIndexOf(".");
336 }
337 if (under < 0) {
338 under = dot;
339 }
340 String name = (prefix) ? fn.substring(0, under) : fn.substring(0, dot);
341 String extension = (prefix) ? fn.substring(dot + 1) : fn.substring(dot + 1, under);
342 String newFn = (prefix) ? format("%s_%d.%s", name, absoluteCounter, extension)
343 : format("%s.%s_%d", name, extension, absoluteCounter);
344 File newFile = new File(newFn);
345 while (newFile.exists()) {
346 absoluteCounter++;
347 newFn = (prefix) ? format("%s_%d.%s", name, absoluteCounter, extension)
348 : format("%s.%s_%d", name, extension, absoluteCounter);
349 newFile = new File(newFn);
350 }
351 return newFile;
352 }
353
354
355
356
357
358
359
360 private static File versionTinker(File file) {
361 if (file == null) {
362 return null;
363 }
364 if (!file.exists()) {
365 return file;
366 }
367 String fileName = file.getAbsolutePath();
368 int dot = file.getAbsolutePath().lastIndexOf(".");
369 int under = file.getAbsolutePath().lastIndexOf("_");
370 File newFile = file;
371 if (under > dot) {
372 String name = fileName.substring(0, under);
373 newFile = new File(name);
374 }
375 File oldFile = newFile;
376 int i = 1;
377 while (newFile.exists()) {
378 i = i + 1;
379 String newFileString = format("%s_%d", oldFile.getAbsolutePath(), i);
380 newFile = new File(newFileString);
381 }
382 return newFile;
383 }
384
385
386
387
388
389
390
391
392 public static Set<Atom> atomListToSet(List<Integer> atomList, Atom[] atoms) {
393 Set<Atom> atomSet = new HashSet<>();
394 for (int i = 0; i < atomList.size(); i++) {
395 atomSet.add(atoms[atomList.get(i)]);
396 }
397 return atomSet;
398 }
399
400
401
402
403
404
405
406 public void applyAtomProperties() {
407
408
409
410
411
412 Atom[] atomArray = activeMolecularAssembly.getAtomArray();
413 int nAtoms = atomArray.length;
414 String[] nouseKeys = properties.getStringArray("nouse");
415 for (String nouseKey : nouseKeys) {
416 String[] toks = nouseKey.split("\\s+");
417 for (String tok : toks) {
418 try {
419 List<Integer> nouseRange = parseAtomRange("nouse", tok, nAtoms);
420 for (int j : nouseRange) {
421 atomArray[j].setUse(false);
422 }
423 } catch (IllegalArgumentException ex) {
424 boolean atomFound = false;
425 for (Atom atom : atomArray) {
426 if (atom.getName().equalsIgnoreCase(tok)) {
427 atomFound = true;
428 atom.setUse(false);
429 }
430 }
431 if (atomFound) {
432 logger.info(format(" Setting atoms with name %s to not be used", tok));
433 } else {
434 logger.log(Level.INFO, ex.getLocalizedMessage());
435 }
436 }
437 }
438 }
439
440 if (properties.containsKey("active")) {
441 for (Atom atom : atomArray) {
442 atom.setActive(false);
443 }
444 String[] activeKeys = properties.getStringArray("active");
445 for (String inactiveKey : activeKeys) {
446 try {
447 List<Integer> inactiveRange = parseAtomRange("inactive", inactiveKey, nAtoms);
448 for (int i : inactiveRange) {
449 atomArray[i].setActive(false);
450 }
451 } catch (IllegalArgumentException ex) {
452 logger.log(Level.INFO, ex.getLocalizedMessage());
453 }
454 }
455 } else if (properties.containsKey("inactive")) {
456 for (Atom atom : atomArray) {
457 atom.setActive(true);
458 }
459 String[] inactiveKeys = properties.getStringArray("inactive");
460 for (String inactiveKey : inactiveKeys) {
461 try {
462 List<Integer> inactiveRange = parseAtomRange("inactive", inactiveKey, nAtoms);
463 for (int i : inactiveRange) {
464 atomArray[i].setActive(false);
465 }
466 } catch (IllegalArgumentException ex) {
467 logger.log(Level.INFO, ex.getLocalizedMessage());
468 }
469 }
470 }
471
472 String[] noElStrings = properties.getStringArray("noElectro");
473 for (String noE : noElStrings) {
474 String[] toks = noE.split("\\s+");
475 for (String tok : toks) {
476 try {
477 List<Integer> noERange = parseAtomRange("noElectro", tok, nAtoms);
478 for (int i : noERange) {
479 atomArray[i].setElectrostatics(false);
480 }
481 } catch (IllegalArgumentException ex) {
482 boolean atomFound = false;
483 for (Atom atom : atomArray) {
484 if (atom.getName().equalsIgnoreCase(tok)) {
485 atomFound = true;
486 atom.setElectrostatics(false);
487 }
488 }
489 if (atomFound) {
490 logger.info(format(" Disabled electrostatics for atoms with name %s", tok));
491 } else {
492 logger.log(Level.INFO, format(" No electrostatics input %s could not be parsed as a numerical "
493 + "range or atom type present in assembly", tok));
494 }
495 }
496 }
497 }
498 }
499
500
501
502
503
504 public abstract void closeReader();
505
506 public int countNumModels() {
507 return -1;
508 }
509
510
511
512
513
514
515 public boolean fileRead() {
516 return fileRead;
517 }
518
519
520
521
522
523
524 public MolecularAssembly getActiveMolecularSystem() {
525 return activeMolecularAssembly;
526 }
527
528
529
530
531
532
533 public List<Atom> getAtomList() {
534 return atomList;
535 }
536
537
538
539
540
541
542 public File getFile() {
543 return currentFile;
544 }
545
546
547
548
549
550
551 public void setFile(File file) {
552 this.currentFile = file;
553 files = new ArrayList<>();
554 if (file != null) {
555 files.add(file);
556 }
557 }
558
559
560
561
562
563
564 public List<File> getFiles() {
565 return files;
566 }
567
568
569
570
571
572
573 public void setFiles(List<File> files) {
574 this.files = files;
575 if (files != null && !files.isEmpty()) {
576 this.currentFile = files.get(0);
577 } else {
578 this.currentFile = null;
579 }
580 }
581
582
583
584
585
586
587 public OptionalDouble getLastReadLambda() {
588 return OptionalDouble.empty();
589 }
590
591
592
593
594
595
596 public MolecularAssembly[] getMolecularAssemblyArray() {
597 if (!systems.isEmpty()) {
598 return systems.toArray(new MolecularAssembly[0]);
599 } else {
600 return new MolecularAssembly[]{activeMolecularAssembly};
601 }
602 }
603
604
605
606
607
608
609 public String[] getRemarkLines() {
610 return new String[0];
611 }
612
613
614
615
616
617
618 public int getSnapshot() {
619 return -1;
620 }
621
622
623
624
625
626
627 public FileType getType() {
628 return fileType;
629 }
630
631
632
633
634
635
636 public void setType(FileType fileType) {
637 this.fileType = fileType;
638 }
639
640
641
642
643
644
645 public abstract boolean readFile();
646
647
648
649
650
651
652 public abstract boolean readNext();
653
654
655
656
657
658
659
660 public abstract boolean readNext(boolean resetPosition);
661
662
663
664
665
666
667
668
669 public abstract boolean readNext(boolean resetPosition, boolean print);
670
671
672
673
674
675
676
677
678
679 public abstract boolean readNext(boolean resetPosition, boolean print, boolean parse);
680
681
682
683
684
685
686 public void setForceField(ForceField forceField) {
687 this.forceField = forceField;
688 }
689
690
691
692
693
694
695
696 public void setProperties(CompositeConfiguration properties) {
697 this.properties = properties;
698 }
699
700
701
702
703
704
705
706
707
708
709
710
711 public boolean writeFile(File saveFile, boolean append) {
712 return writeFile(saveFile, append, null);
713 }
714
715
716
717
718
719
720
721
722
723
724
725
726
727 public abstract boolean writeFile(File saveFile, boolean append, String[] extraLines);
728
729
730
731
732
733
734 protected void setFileRead(boolean fileRead) {
735 this.fileRead = fileRead;
736 }
737
738
739
740
741
742
743 void setMolecularSystem(MolecularAssembly molecularAssembly) {
744 activeMolecularAssembly = molecularAssembly;
745 }
746
747 public enum Versioning {
748 TINKER, PREFIX, POSTFIX, PREFIX_ABSOLUTE, POSTFIX_ABSOLUTE, NONE
749 }
750 }