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