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.parameters;
39
40 import static ffx.utilities.PropertyGroup.PotentialFunctionParameter;
41 import static java.lang.String.format;
42
43 import ffx.utilities.FFXProperty;
44
45 import java.net.URL;
46 import java.util.ArrayList;
47 import java.util.Arrays;
48 import java.util.Collection;
49 import java.util.EnumMap;
50 import java.util.HashMap;
51 import java.util.List;
52 import java.util.Map;
53 import java.util.TreeMap;
54 import java.util.logging.Level;
55 import java.util.logging.Logger;
56
57 import org.apache.commons.configuration2.CompositeConfiguration;
58
59
60
61
62
63
64
65 @FFXProperty(name = "forcefield", clazz = String.class, propertyGroup = PotentialFunctionParameter, description = """
66 [name]
67 Provides a name for the force field to be used in the current calculation.
68 Its value is usually set in the master force field parameter file for the calculation
69 (see the PARAMETERS keyword) instead of in the property file.
70 """)
71 public class ForceField {
72
73 private static final Logger logger = Logger.getLogger(ForceField.class.getName());
74
75
76
77 private static final Map<ForceFieldName, URL> forceFields = new EnumMap<>(ForceFieldName.class);
78
79 static {
80 ClassLoader cl = ForceField.class.getClassLoader();
81 String prefix = "ffx/potential/parameters/ff/";
82 for (ForceFieldName ff : ForceFieldName.values()) {
83 forceFields.put(ff, cl.getResource(prefix + ff));
84 }
85 }
86
87
88
89
90 private final CompositeConfiguration properties;
91 private final Map<String, AngleType> angleTypes;
92 private final Map<String, AngleType> anglepTypes;
93 private final Map<String, AtomType> atomTypes;
94 private final Map<String, BioType> bioTypes;
95 private final Map<String, BondType> bondTypes;
96 private final Map<String, ChargeType> chargeTypes;
97 private final Map<String, MultipoleType> multipoleTypes;
98 private final Map<String, OutOfPlaneBendType> outOfPlaneBendTypes;
99 private final Map<String, PolarizeType> polarizeTypes;
100 private final Map<String, StretchBendType> stretchBendTypes;
101 private final Map<String, StretchTorsionType> stretchTorsionTypes;
102 private final Map<String, AngleTorsionType> angleTorsionTypes;
103 private final Map<String, PiOrbitalTorsionType> piOrbitalTorsionTypes;
104 private final Map<String, TorsionType> torsionTypes;
105 private final Map<String, TorsionType> improperTypes;
106 private final Map<String, ImproperTorsionType> imptorsTypes;
107 private final Map<String, SoluteType> soluteTypes;
108 private final Map<String, TorsionTorsionType> torsionTorsionTypes;
109 private final Map<String, UreyBradleyType> ureyBradleyTypes;
110 private final Map<String, VDWType> vanderWaalsTypes;
111 private final Map<String, VDWType> vanderWaals14Types;
112 private final Map<String, VDWPairType> vanderWaalsPairTypes;
113 private final Map<String, RelativeSolvationType> relativeSolvationTypes;
114 private final Map<ForceFieldType, Map<String, ? extends BaseType>> forceFieldTypes;
115
116
117
118 public URL forceFieldURL;
119
120
121
122
123
124
125
126 public ForceField(CompositeConfiguration properties) {
127 this.properties = properties;
128
129
130
131
132
133
134 angleTypes = new TreeMap<>(new AngleType(new int[3], 0, new double[1], null));
135 anglepTypes = new TreeMap<>(new AngleType(new int[3], 0, new double[1], null, null));
136 atomTypes = new TreeMap<>(new AtomType(0, 0, null, null, 0, 0, 0));
137 bioTypes = new TreeMap<>(new BioType(0, null, null, 0, null));
138 bondTypes = new TreeMap<>(new BondType(new int[2], 0, 0, null));
139 chargeTypes = new TreeMap<>(new ChargeType(0, 0));
140 soluteTypes = new TreeMap<>(new SoluteType(0, 0.0, 0.0, 0.0));
141 multipoleTypes = new TreeMap<>(new MultipoleType(new double[10], null, null, false));
142 outOfPlaneBendTypes = new TreeMap<>(new OutOfPlaneBendType(new int[4], 0));
143 piOrbitalTorsionTypes = new TreeMap<>(new PiOrbitalTorsionType(new int[2], 0));
144 polarizeTypes = new TreeMap<>(new PolarizeType(0, 0, 0, 0, new int[1]));
145 stretchBendTypes = new TreeMap<>(new StretchBendType(new int[3], new double[1]));
146 stretchTorsionTypes = new TreeMap<>(new StretchTorsionType(new int[4], new double[1]));
147 angleTorsionTypes = new TreeMap<>(new AngleTorsionType(new int[4], new double[1]));
148 torsionTorsionTypes = new TreeMap<>();
149 torsionTypes = new TreeMap<>(
150 new TorsionType(new int[4], new double[1], new double[1], new int[1]));
151 improperTypes = new TreeMap<>(
152 new TorsionType(new int[4], new double[1], new double[1], new int[1]));
153 imptorsTypes = new TreeMap<>(new ImproperTorsionType(new int[4], 0.0, 0.0, 2));
154 ureyBradleyTypes = new TreeMap<>(new UreyBradleyType(new int[3], 0, 0));
155 vanderWaalsTypes = new TreeMap<>(new VDWType(0, 0, 0, 0));
156 vanderWaals14Types = new TreeMap<>(new VDWType(0, 0, 0, 0));
157 vanderWaalsPairTypes = new TreeMap<>(new VDWPairType(new int[2], 0, 0));
158 relativeSolvationTypes = new TreeMap<>(new RelativeSolvationType("", 0.0));
159
160 forceFieldTypes = new EnumMap<>(ForceFieldType.class);
161 forceFieldTypes.put(ForceFieldType.ANGLE, angleTypes);
162 forceFieldTypes.put(ForceFieldType.ANGLEP, anglepTypes);
163 forceFieldTypes.put(ForceFieldType.ATOM, atomTypes);
164 forceFieldTypes.put(ForceFieldType.BOND, bondTypes);
165 forceFieldTypes.put(ForceFieldType.BIOTYPE, bioTypes);
166 forceFieldTypes.put(ForceFieldType.CHARGE, chargeTypes);
167 forceFieldTypes.put(ForceFieldType.SOLUTE, soluteTypes);
168 forceFieldTypes.put(ForceFieldType.OPBEND, outOfPlaneBendTypes);
169 forceFieldTypes.put(ForceFieldType.MULTIPOLE, multipoleTypes);
170 forceFieldTypes.put(ForceFieldType.PITORS, piOrbitalTorsionTypes);
171 forceFieldTypes.put(ForceFieldType.POLARIZE, polarizeTypes);
172 forceFieldTypes.put(ForceFieldType.STRBND, stretchBendTypes);
173 forceFieldTypes.put(ForceFieldType.STRTORS, stretchTorsionTypes);
174 forceFieldTypes.put(ForceFieldType.ANGTORS, angleTorsionTypes);
175 forceFieldTypes.put(ForceFieldType.TORSION, torsionTypes);
176 forceFieldTypes.put(ForceFieldType.IMPROPER, improperTypes);
177 forceFieldTypes.put(ForceFieldType.IMPTORS, imptorsTypes);
178 forceFieldTypes.put(ForceFieldType.TORTORS, torsionTorsionTypes);
179 forceFieldTypes.put(ForceFieldType.UREYBRAD, ureyBradleyTypes);
180 forceFieldTypes.put(ForceFieldType.VDW, vanderWaalsTypes);
181 forceFieldTypes.put(ForceFieldType.VDW14, vanderWaals14Types);
182 forceFieldTypes.put(ForceFieldType.VDWPR, vanderWaalsPairTypes);
183 forceFieldTypes.put(ForceFieldType.RELATIVESOLV, relativeSolvationTypes);
184
185 trueImpliedBoolean("ELEC_LAMBDATERM", "GK_LAMBDATERM");
186 trueImpliedBoolean("LAMBDATERM", "VDW_LAMBDATERM", "ELEC_LAMBDATERM", "GK_LAMBDATERM");
187 }
188
189
190
191
192
193
194
195 public static URL getForceFieldURL(ForceFieldName forceField) {
196 if (forceField == null) {
197 return null;
198 }
199 return forceFields.get(forceField);
200 }
201
202
203
204
205
206
207
208 public static boolean isForceFieldType(String keyword) {
209 keyword = toEnumForm(keyword);
210 try {
211 ForceFieldType.valueOf(keyword);
212 return true;
213 } catch (Exception e) {
214
215 }
216 return false;
217 }
218
219
220
221
222
223
224
225 public static String toEnumForm(String key) {
226 if (key == null) {
227 return null;
228 }
229 return key.toUpperCase().replace("-", "_");
230 }
231
232
233
234
235
236
237
238 public static String toPropertyForm(String s) {
239 if (s == null) {
240 return null;
241 }
242 return s.toLowerCase().replace("_", "-");
243 }
244
245
246
247
248
249
250
251
252 @SuppressWarnings("unchecked")
253 public <T extends BaseType> void addForceFieldType(T type) {
254 if (type == null) {
255 logger.info(" Null force field type ignored.");
256 return;
257 }
258
259 Map<String, T> treeMap = (Map<String, T>) forceFieldTypes.get(type.forceFieldType);
260 if (treeMap == null) {
261 logger.log(Level.INFO, " Unrecognized force field type ignored {0}", type.forceFieldType);
262 type.print();
263 return;
264 }
265 if (treeMap.containsKey(type.key)) {
266 if (treeMap.get(type.key).toString().equalsIgnoreCase(type.toString())) {
267
268 return;
269 }
270 logger.log(Level.WARNING,
271 " A force field entry of type {0} already exists with the key: {1}\n The (discarded) old entry: {2}\n The new entry : {3}",
272 new Object[]{type.forceFieldType, type.key, treeMap.get(type.key).toString(),
273 type.toString()});
274 }
275 treeMap.put(type.key, type);
276 }
277
278
279
280
281
282
283
284 public void addProperty(String property, String value) {
285 if (property == null) {
286 return;
287 }
288 String key = toPropertyForm(property);
289
290
291
292
293
294
295
296
297
298
299
300
301 properties.addProperty(key, value);
302 }
303
304
305
306
307
308
309 public void clearProperty(String property) {
310 properties.clearProperty(property);
311 }
312
313
314
315
316
317
318
319 public void append(ForceField patch) {
320
321 boolean renumber = patch.getBoolean("renumberPatch", true);
322 logger.info(format(" Renumbering Patch: %B", renumber));
323
324 if (renumber) {
325
326 int classOffset = maxClass();
327 int typeOffset = maxType();
328 int bioTypeOffset = maxBioType();
329
330 int minClass = patch.minClass();
331 int minType = patch.minType();
332 int minBioType = patch.minBioType();
333
334 classOffset -= (minClass - 1);
335 typeOffset -= (minType - 1);
336 bioTypeOffset -= (minBioType - 1);
337
338 patch.renumberForceField(classOffset, typeOffset, bioTypeOffset);
339 }
340
341 for (AngleType angleType : patch.angleTypes.values()) {
342 angleTypes.put(angleType.getKey(), angleType);
343 }
344
345 for (AngleType angleType : patch.anglepTypes.values()) {
346 angleTypes.put(angleType.getKey(), angleType);
347 }
348
349 for (AtomType atomType : patch.atomTypes.values()) {
350 atomTypes.put(atomType.getKey(), atomType);
351 }
352
353 for (BioType bioType : patch.bioTypes.values()) {
354 bioTypes.put(bioType.getKey(), bioType);
355 }
356
357 for (BondType bondType : patch.bondTypes.values()) {
358 bondTypes.put(bondType.getKey(), bondType);
359 }
360
361 for (MultipoleType multipoleType : patch.multipoleTypes.values()) {
362 multipoleTypes.put(multipoleType.getKey(), multipoleType);
363 }
364
365 for (OutOfPlaneBendType outOfPlaneBendType : patch.outOfPlaneBendTypes.values()) {
366 outOfPlaneBendTypes.put(outOfPlaneBendType.getKey(), outOfPlaneBendType);
367 }
368
369 for (PiOrbitalTorsionType piOrbitalTorsionType : patch.piOrbitalTorsionTypes.values()) {
370 piOrbitalTorsionTypes.put(piOrbitalTorsionType.getKey(), piOrbitalTorsionType);
371 }
372
373 for (PolarizeType polarizeType : patch.polarizeTypes.values()) {
374 polarizeTypes.put(polarizeType.getKey(), polarizeType);
375 }
376
377 for (StretchBendType stretchBendType : patch.stretchBendTypes.values()) {
378 stretchBendTypes.put(stretchBendType.getKey(), stretchBendType);
379 }
380
381 for (StretchTorsionType stretchTorsionType : patch.stretchTorsionTypes.values()) {
382 stretchTorsionTypes.put(stretchTorsionType.getKey(), stretchTorsionType);
383 }
384
385 for (AngleTorsionType angleTorsionType : patch.angleTorsionTypes.values()) {
386 angleTorsionTypes.put(angleTorsionType.getKey(), angleTorsionType);
387 }
388
389 for (TorsionTorsionType torsionTorsionType : patch.torsionTorsionTypes.values()) {
390 torsionTorsionTypes.put(torsionTorsionType.getKey(), torsionTorsionType);
391 }
392
393 for (TorsionType torsionType : patch.torsionTypes.values()) {
394 torsionTypes.put(torsionType.getKey(), torsionType);
395 }
396
397 for (TorsionType torsionType : patch.improperTypes.values()) {
398 torsionTypes.put(torsionType.getKey(), torsionType);
399 }
400
401 for (ImproperTorsionType improperTorsionType : patch.imptorsTypes.values()) {
402 imptorsTypes.put(improperTorsionType.getKey(), improperTorsionType);
403 }
404
405 for (UreyBradleyType ureyBradleyType : patch.ureyBradleyTypes.values()) {
406 ureyBradleyTypes.put(ureyBradleyType.getKey(), ureyBradleyType);
407 }
408
409 for (VDWType vdwType : patch.vanderWaalsTypes.values()) {
410 vanderWaalsTypes.put(vdwType.getKey(), vdwType);
411 }
412
413 for (VDWType vdwType : patch.vanderWaals14Types.values()) {
414 vanderWaals14Types.put(vdwType.getKey(), vdwType);
415 }
416
417 for (VDWPairType vdwPairType : patch.vanderWaalsPairTypes.values()) {
418 vanderWaalsPairTypes.put(vdwPairType.getKey(), vdwPairType);
419 }
420
421 for (SoluteType soluteType : patch.soluteTypes.values()) {
422 soluteTypes.put(soluteType.getKey(), soluteType);
423 }
424
425 for (RelativeSolvationType rsType : patch.relativeSolvationTypes.values()) {
426 relativeSolvationTypes.put(rsType.getKey(), rsType);
427 }
428
429
430 String modres = patch.getString("MODRES", "false");
431 if (!modres.equalsIgnoreCase("false")) {
432 logger.info(" Adding modified residue patch.");
433 modifiedResidue(modres);
434 }
435 }
436
437
438
439
440
441
442
443 public AngleTorsionType getAngleTorsionType(String key) {
444 AngleTorsionType angleTorsionType = angleTorsionTypes.get(key);
445 if (angleTorsionType != null) {
446 angleTorsionType.angtorunit = getDouble("ANGTORUNIT", AngleTorsionType.DEFAULT_ANGTOR_UNIT);
447 }
448 return angleTorsionType;
449 }
450
451
452
453
454
455
456
457 public AngleType getAngleType(String key) {
458 AngleType angleType = angleTypes.get(key);
459 if (angleType == null) {
460 angleType = anglepTypes.get(key);
461 }
462 if (angleType != null) {
463 angleType.angleUnit = getDouble("ANGLEUNIT", AngleType.DEFAULT_ANGLE_UNIT);
464 angleType.cubic = getDouble("ANGLE-CUBIC", AngleType.DEFAULT_ANGLE_CUBIC);
465 angleType.quartic = getDouble("ANGLE-QUARTIC", AngleType.DEFAULT_ANGLE_QUARTIC);
466 angleType.pentic = getDouble("ANGLE-PENTIC", AngleType.DEFAULT_ANGLE_PENTIC);
467 angleType.sextic = getDouble("ANGLE-SEXTIC", AngleType.DEFAULT_ANGLE_SEXTIC);
468 }
469 return angleType;
470 }
471
472
473
474
475
476
477
478
479
480 public AngleType getAngleType(AtomType a1, AtomType a2, AtomType a3) {
481 int[] c = {a1.atomClass, a2.atomClass, a3.atomClass};
482 String key = AngleType.sortKey(c);
483 return getAngleType(key);
484 }
485
486
487
488
489
490
491
492 public AtomType getAtomType(String key) {
493 return atomTypes.get(key);
494 }
495
496
497
498
499
500
501
502
503 public AtomType getAtomType(String moleculeName, String atomName) {
504 for (BioType bioType : bioTypes.values()) {
505 if (bioType.moleculeName.equalsIgnoreCase(moleculeName) && bioType.atomName.equalsIgnoreCase(
506 atomName)) {
507 String key = Integer.toString(bioType.atomType);
508 return atomTypes.get(key);
509 }
510 }
511 return null;
512 }
513
514
515
516
517
518
519
520 public List<AtomType> getSimilarAtomTypes(AtomType atomType) {
521 List<AtomType> types = new ArrayList<>();
522 for (AtomType type : atomTypes.values()) {
523 if (type.atomicNumber == atomType.atomicNumber && type.valence == atomType.valence) {
524 types.add(type);
525 }
526 }
527 return types;
528 }
529
530
531
532
533
534
535
536 public HashMap<String, AtomType> getAtomTypes(String moleculeName) {
537 HashMap<String, AtomType> types = new HashMap<>();
538 for (BioType bioType : bioTypes.values()) {
539 if (bioType.moleculeName.equalsIgnoreCase(moleculeName)) {
540 String key = Integer.toString(bioType.atomType);
541 AtomType type = atomTypes.get(key);
542 types.put(bioType.atomName.toUpperCase(), type);
543 }
544 }
545 return types;
546 }
547
548
549
550
551
552
553
554
555 public BioType getBioType(String moleculeName, String atomName) {
556 for (BioType bioType : bioTypes.values()) {
557 if (bioType.moleculeName.equalsIgnoreCase(moleculeName) && bioType.atomName.equalsIgnoreCase(
558 atomName)) {
559 return bioType;
560 }
561 }
562 return null;
563 }
564
565
566
567
568
569
570
571 public BioType getBioType(String key) {
572 return bioTypes.get(key);
573 }
574
575
576
577
578
579
580 public Map<String, BioType> getBioTypeMap() {
581 return bioTypes;
582 }
583
584
585
586
587
588
589
590 public BondType getBondType(String key) {
591 BondType bondType = bondTypes.get(key);
592 if (bondType != null) {
593 bondType.bondUnit = getDouble("BONDUNIT", BondType.DEFAULT_BOND_UNIT);
594 bondType.cubic = getDouble("BOND_CUBIC", BondType.DEFAULT_BOND_CUBIC);
595 bondType.quartic = getDouble("BOND_QUARTIC", BondType.DEFAULT_BOND_QUARTIC);
596 }
597 return bondType;
598 }
599
600
601
602
603
604
605
606
607 public BondType getBondType(AtomType a1, AtomType a2) {
608 int[] c = {a1.atomClass, a2.atomClass};
609 String key = BondType.sortKey(c);
610 return getBondType(key);
611 }
612
613
614
615
616
617
618
619
620 public String[] getBonds(String moleculeName, String atomName) {
621 for (BioType bioType : bioTypes.values()) {
622 if (bioType.moleculeName.equalsIgnoreCase(moleculeName) && bioType.atomName.equalsIgnoreCase(
623 atomName)) {
624 return bioType.bonds;
625 }
626 }
627 return null;
628 }
629
630
631
632
633
634
635
636
637 public boolean getBoolean(String property) throws Exception {
638 if (property == null) {
639 throw new Exception("NULL property");
640 }
641 String key = toPropertyForm(property);
642 if (!properties.containsKey(key)) {
643 throw new Exception("Undefined property: " + key);
644 }
645 return properties.getBoolean(key);
646 }
647
648
649
650
651
652
653
654
655 public boolean getBoolean(String property, boolean defaultBoolean) {
656 try {
657 return getBoolean(property);
658 } catch (Exception e) {
659 return defaultBoolean;
660 }
661 }
662
663
664
665
666
667
668
669
670 public double getDouble(String property) throws Exception {
671 if (property == null) {
672 throw new Exception("NULL property");
673 }
674 String key = toPropertyForm(property);
675 if (!properties.containsKey(key)) {
676 throw new Exception("Undefined property: " + key);
677 }
678 return properties.getDouble(key);
679 }
680
681
682
683
684
685
686
687
688 public double getDouble(String property, Double defaultDouble) {
689 try {
690 return getDouble(property);
691 } catch (Exception e) {
692 return defaultDouble;
693 }
694 }
695
696
697
698
699
700
701
702 @SuppressWarnings("unchecked")
703 public int getForceFieldTypeCount(ForceFieldType type) {
704 TreeMap<String, BaseType> treeMap = (TreeMap<String, BaseType>) forceFieldTypes.get(type);
705 if (treeMap == null) {
706 logger.log(Level.WARNING, "Unrecognized Force Field Type: {0}", type);
707 return 0;
708 }
709 return treeMap.size();
710 }
711
712
713
714
715
716
717
718 public ImproperTorsionType getImproperType(String key) {
719 ImproperTorsionType improperTorsionType = imptorsTypes.get(key);
720 if (improperTorsionType != null) {
721 double units = getDouble("IMPTORUNIT", ImproperTorsionType.DEFAULT_IMPTOR_UNIT);
722 improperTorsionType.impTorUnit = getDouble("IMPTORSUNIT", units);
723 }
724 return improperTorsionType;
725 }
726
727
728
729
730
731
732 public Collection<ImproperTorsionType> getImproperTypes() {
733 double units = getDouble("IMPTORUNIT", ImproperTorsionType.DEFAULT_IMPTOR_UNIT);
734 units = getDouble("IMPTORSUNIT", units);
735 for (ImproperTorsionType improperTorsionType : imptorsTypes.values()) {
736 improperTorsionType.impTorUnit = units;
737 }
738 return imptorsTypes.values();
739 }
740
741
742
743
744
745
746
747
748 public int getInteger(String property) throws Exception {
749 if (property == null) {
750 throw new Exception("NULL property");
751 }
752 String key = toPropertyForm(property);
753 if (!properties.containsKey(key)) {
754 throw new Exception("Undefined property: " + key);
755 }
756 return properties.getInt(key);
757 }
758
759
760
761
762
763
764
765
766 public int getInteger(String property, Integer defaultInteger) {
767 try {
768 return getInteger(property);
769 } catch (Exception e) {
770 return defaultInteger;
771 }
772 }
773
774
775
776
777
778
779
780 public MultipoleType getMultipoleType(String key) {
781 return multipoleTypes.get(key);
782 }
783
784
785
786
787
788
789
790
791 public MultipoleType getMultipoleTypeBeginsWith(String key) {
792 int count = 0;
793 MultipoleType multipoleType = null;
794 for (String s : multipoleTypes.keySet()) {
795 if (s.startsWith(key + " ")) {
796 count++;
797 multipoleType = multipoleTypes.get(s);
798 }
799 }
800
801 if (count == 1) {
802 return multipoleType;
803 }
804
805 return null;
806 }
807
808
809
810
811
812
813
814 public List<MultipoleType> getMultipoleTypes(String key) {
815 List<MultipoleType> list = new ArrayList<>();
816 for (String s : multipoleTypes.keySet()) {
817 if (s.startsWith(key + " ")) {
818 list.add(multipoleTypes.get(s));
819 }
820 }
821
822 return list;
823 }
824
825
826
827
828
829
830
831 public Map<String, ? extends BaseType> getTypes(ForceFieldType type) {
832 return forceFieldTypes.get(type);
833 }
834
835
836
837
838
839
840 public void clearForceFieldType(ForceFieldType type) {
841 Map<String, ? extends BaseType> map = forceFieldTypes.get(type);
842 map.clear();
843 }
844
845
846
847
848
849
850
851 public OutOfPlaneBendType getOutOfPlaneBendType(String key) {
852 OutOfPlaneBendType outOfPlaneBendType = outOfPlaneBendTypes.get(key);
853 if (outOfPlaneBendType != null) {
854 outOfPlaneBendType.opBendUnit = getDouble("OPBENDUNIT",
855 OutOfPlaneBendType.DEFAULT_OPBEND_UNIT);
856 outOfPlaneBendType.cubic = getDouble("OPBEND-CUBIC", OutOfPlaneBendType.DEFAULT_OPBEND_CUBIC);
857 outOfPlaneBendType.quartic = getDouble("OPBEND-QUARTIC",
858 OutOfPlaneBendType.DEFAULT_OPBEND_QUARTIC);
859 outOfPlaneBendType.pentic = getDouble("OPBEND-PENTIC",
860 OutOfPlaneBendType.DEFAULT_OPBEND_PENTIC);
861 outOfPlaneBendType.sextic = getDouble("OPBEND-SEXTIC",
862 OutOfPlaneBendType.DEFAULT_OPBEND_SEXTIC);
863 }
864 return outOfPlaneBendType;
865 }
866
867
868
869
870
871
872
873
874
875
876 public OutOfPlaneBendType getOutOfPlaneBendType(AtomType a4, AtomType a0, AtomType a1,
877 AtomType a2) {
878 int class4 = a4.atomClass;
879 int class0 = a0.atomClass;
880 int class1 = a1.atomClass;
881 int class2 = a2.atomClass;
882
883
884 String key = OutOfPlaneBendType.sortKey(new int[]{class4, class1, class0, class2});
885 OutOfPlaneBendType outOfPlaneBendType = getOutOfPlaneBendType(key);
886 if (outOfPlaneBendType == null) {
887 key = OutOfPlaneBendType.sortKey(new int[]{class4, class1, class2, class0});
888 outOfPlaneBendType = getOutOfPlaneBendType(key);
889 }
890
891
892 if (outOfPlaneBendType == null) {
893 key = OutOfPlaneBendType.sortKey(new int[]{class4, class1, 0, 0});
894 outOfPlaneBendType = getOutOfPlaneBendType(key);
895 }
896
897 return outOfPlaneBendType;
898 }
899
900
901
902
903
904
905
906 public PiOrbitalTorsionType getPiOrbitalTorsionType(String key) {
907 PiOrbitalTorsionType piOrbitalTorsionType = piOrbitalTorsionTypes.get(key);
908 if (piOrbitalTorsionType != null) {
909 piOrbitalTorsionType.piTorsUnit = getDouble("PITORSUNIT",
910 PiOrbitalTorsionType.DEFAULT_PITORS_UNIT);
911 }
912 return piOrbitalTorsionType;
913 }
914
915
916
917
918
919
920
921
922 public PiOrbitalTorsionType getPiOrbitalTorsionType(AtomType a1, AtomType a2) {
923 int[] c = new int[2];
924 c[0] = a1.atomClass;
925 c[1] = a2.atomClass;
926 String key = PiOrbitalTorsionType.sortKey(c);
927 return getPiOrbitalTorsionType(key);
928 }
929
930
931
932
933
934
935
936 public PolarizeType getPolarizeType(String key) {
937 return polarizeTypes.get(key);
938 }
939
940
941
942
943
944
945 public CompositeConfiguration getProperties() {
946 return properties;
947 }
948
949
950
951
952
953
954 public HashMap<String, RelativeSolvationType> getRelativeSolvationTypes() {
955 HashMap<String, RelativeSolvationType> types = new HashMap<>();
956 for (String key : relativeSolvationTypes.keySet()) {
957 types.put(key, relativeSolvationTypes.get(key));
958 }
959 return types;
960 }
961
962
963
964
965
966
967
968 public SoluteType getSoluteType(String key) {
969 return soluteTypes.get(key);
970 }
971
972 public Map<String, SoluteType> getSoluteTypes() {
973 return soluteTypes;
974 }
975
976
977
978
979
980
981
982 public StretchBendType getStretchBendType(String key) {
983 StretchBendType stretchBendType = stretchBendTypes.get(key);
984 if (stretchBendType != null) {
985 stretchBendType.strbndunit = getDouble("STRBNDUNIT", StretchBendType.DEFAULT_STRBND_UNIT);
986 }
987 return stretchBendType;
988 }
989
990
991
992
993
994
995
996
997
998 public StretchBendType getStretchBendType(AtomType a1, AtomType a2, AtomType a3) {
999 int[] c = {a1.atomClass, a2.atomClass, a3.atomClass};
1000 String key = AngleType.sortKey(c);
1001 return getStretchBendType(key);
1002 }
1003
1004
1005
1006
1007
1008
1009
1010 public StretchTorsionType getStretchTorsionType(String key) {
1011 StretchTorsionType stretchTorsionType = stretchTorsionTypes.get(key);
1012 if (stretchTorsionType != null) {
1013 stretchTorsionType.strTorUnit = getDouble("STRTORUNIT",
1014 StretchTorsionType.DEFAULT_STRTOR_UNIT);
1015 }
1016 return stretchTorsionType;
1017 }
1018
1019
1020
1021
1022
1023
1024
1025
1026 public String getString(String property) throws Exception {
1027 if (property == null) {
1028 throw new Exception("NULL property");
1029 }
1030 String key = toPropertyForm(property);
1031 if (!properties.containsKey(key)) {
1032 throw new Exception("Undefined property: " + key);
1033 }
1034 return properties.getString(key);
1035 }
1036
1037
1038
1039
1040
1041
1042
1043
1044 public String getString(String property, String defaultString) {
1045 try {
1046 return getString(property);
1047 } catch (Exception e) {
1048 return defaultString;
1049 }
1050 }
1051
1052
1053
1054
1055
1056
1057
1058 public TorsionTorsionType getTorsionTorsionType(String key) {
1059 TorsionTorsionType torsionTorsionType = torsionTorsionTypes.get(key);
1060 if (torsionTorsionType != null) {
1061 torsionTorsionType.torTorUnit = getDouble("TORTORUNIT",
1062 TorsionTorsionType.DEFAULT_TORTOR_UNIT);
1063 }
1064 return torsionTorsionType;
1065 }
1066
1067
1068
1069
1070
1071
1072
1073 public TorsionType getTorsionType(String key) {
1074 TorsionType torsionType = torsionTypes.get(key);
1075 if (torsionType != null) {
1076 torsionType.torsionUnit = getDouble("TORSIONUNIT", TorsionType.DEFAULT_TORSION_UNIT);
1077 }
1078 return torsionType;
1079 }
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090 private TorsionType getTorsionType(int c0, int c1, int c2, int c3) {
1091 int[] c = {c0, c1, c2, c3};
1092 String key = TorsionType.sortKey(c);
1093 return getTorsionType(key);
1094 }
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105 public TorsionType getTorsionType(AtomType a0, AtomType a1, AtomType a2, AtomType a3) {
1106 int c0 = a0.atomClass;
1107 int c1 = a1.atomClass;
1108 int c2 = a2.atomClass;
1109 int c3 = a3.atomClass;
1110
1111 TorsionType torsionType = getTorsionType(c0, c1, c2, c3);
1112
1113
1114 if (torsionType == null) {
1115 if (c0 > c3) {
1116 torsionType = getTorsionType(c0, c1, c2, 0);
1117 if (torsionType == null) {
1118 torsionType = getTorsionType(0, c1, c2, c3);
1119 }
1120 } else {
1121 torsionType = getTorsionType(0, c1, c2, c3);
1122 if (torsionType == null) {
1123 torsionType = getTorsionType(c0, c1, c2, 0);
1124 }
1125 }
1126 }
1127
1128
1129 if (torsionType == null) {
1130 torsionType = getTorsionType(0, c1, c2, 0);
1131 }
1132
1133 return torsionType;
1134 }
1135
1136
1137
1138
1139
1140
1141
1142 public UreyBradleyType getUreyBradleyType(String key) {
1143 UreyBradleyType ureyBradleyType = ureyBradleyTypes.get(key);
1144 if (ureyBradleyType != null) {
1145 ureyBradleyType.ureyUnit = getDouble("UREYUNIT", UreyBradleyType.DEFAULT_UREY_UNIT);
1146 ureyBradleyType.cubic = getDouble("UREY_CUBIC", UreyBradleyType.DEFAULT_UREY_CUBIC);
1147 ureyBradleyType.quartic = getDouble("UREY_QUARTIC", UreyBradleyType.DEFAULT_UREY_QUARTIC);
1148 }
1149 return ureyBradleyType;
1150 }
1151
1152
1153
1154
1155
1156
1157
1158 public VDWType getVDW14Type(String key) {
1159 return vanderWaals14Types.get(key);
1160 }
1161
1162
1163
1164
1165
1166
1167 public Map<String, VDWType> getVDW14Types() {
1168 return vanderWaals14Types;
1169 }
1170
1171
1172
1173
1174
1175
1176
1177 public VDWType getVDWType(String key) {
1178 return vanderWaalsTypes.get(key);
1179 }
1180
1181
1182
1183
1184
1185
1186
1187 public VDWPairType getVDWPairType(String key) {
1188 return vanderWaalsPairTypes.get(key);
1189 }
1190
1191
1192
1193
1194
1195
1196 public Map<String, VDWType> getVDWTypes() {
1197 return vanderWaalsTypes;
1198 }
1199
1200
1201
1202
1203
1204
1205 public Map<String, VDWPairType> getVDWPairTypes() {
1206 return vanderWaalsPairTypes;
1207 }
1208
1209
1210
1211
1212
1213
1214
1215 public boolean hasProperty(String property) {
1216 if (property == null) {
1217 return false;
1218 }
1219 String key = toPropertyForm(property);
1220 return properties.containsKey(key);
1221 }
1222
1223
1224
1225
1226 public void log() {
1227 for (ForceFieldType s : forceFieldTypes.keySet()) {
1228 log(s.toString());
1229 }
1230 }
1231
1232
1233
1234
1235
1236
1237 public void log(String key) {
1238 ForceFieldType type = ForceFieldType.valueOf(key);
1239 logger.info(toString(type));
1240 }
1241
1242
1243
1244
1245 public void print() {
1246 for (ForceFieldType s : forceFieldTypes.keySet()) {
1247 print(s.toString());
1248 }
1249 }
1250
1251
1252
1253
1254
1255
1256 public void print(String key) {
1257 ForceFieldType type = ForceFieldType.valueOf(key);
1258 logger.info(toString(type));
1259 }
1260
1261
1262
1263
1264
1265
1266
1267
1268 public void renumberForceField(int classOffset, int typeOffset, int bioTypeOffset) {
1269 for (AngleType angleType : angleTypes.values()) {
1270 angleType.incrementClasses(classOffset);
1271 }
1272
1273 for (AngleType angleType : anglepTypes.values()) {
1274 angleType.incrementClasses(classOffset);
1275 }
1276
1277 for (AtomType atomType : atomTypes.values()) {
1278 atomType.incrementClassAndType(classOffset, typeOffset);
1279 }
1280
1281 for (BioType bioType : bioTypes.values()) {
1282 bioType.incrementIndexAndType(bioTypeOffset, typeOffset);
1283 }
1284
1285 for (BondType bondType : bondTypes.values()) {
1286 bondType.incrementClasses(classOffset);
1287 }
1288
1289 for (MultipoleType multipoleType : multipoleTypes.values()) {
1290 multipoleType.incrementType(typeOffset);
1291 }
1292
1293 for (OutOfPlaneBendType outOfPlaneBendType : outOfPlaneBendTypes.values()) {
1294 outOfPlaneBendType.incrementClasses(classOffset);
1295 }
1296
1297 for (PiOrbitalTorsionType piOrbitalTorsionType : piOrbitalTorsionTypes.values()) {
1298 piOrbitalTorsionType.incrementClasses(classOffset);
1299 }
1300
1301 for (PolarizeType polarizeType : polarizeTypes.values()) {
1302 polarizeType.incrementType(typeOffset);
1303 }
1304
1305 for (StretchBendType stretchBendType : stretchBendTypes.values()) {
1306 stretchBendType.incrementClasses(classOffset);
1307 }
1308
1309 for (StretchTorsionType stretchTorsionType : stretchTorsionTypes.values()) {
1310 stretchTorsionType.incrementClasses(classOffset);
1311 }
1312
1313 for (AngleTorsionType angleTorsionType : angleTorsionTypes.values()) {
1314 angleTorsionType.incrementClasses(classOffset);
1315 }
1316
1317 for (TorsionTorsionType torsionTorsionType : torsionTorsionTypes.values()) {
1318 torsionTorsionType.incrementClasses(classOffset);
1319 }
1320
1321 for (TorsionType torsionType : torsionTypes.values()) {
1322 torsionType.incrementClasses(classOffset);
1323 }
1324
1325 for (TorsionType torsionType : improperTypes.values()) {
1326 torsionType.incrementClasses(classOffset);
1327 }
1328
1329 for (ImproperTorsionType improperTorsionType : imptorsTypes.values()) {
1330 improperTorsionType.incrementClasses(classOffset);
1331 }
1332
1333 for (UreyBradleyType ureyBradleyType : ureyBradleyTypes.values()) {
1334 ureyBradleyType.incrementClasses(classOffset);
1335 }
1336
1337 for (VDWType vanderWaalsType : vanderWaalsTypes.values()) {
1338 vanderWaalsType.incrementClass(classOffset);
1339 }
1340
1341 for (VDWType vanderWaals14Type : vanderWaals14Types.values()) {
1342 vanderWaals14Type.incrementClass(classOffset);
1343 }
1344
1345 for (VDWPairType vanderWaalsPairType : vanderWaalsPairTypes.values()) {
1346 vanderWaalsPairType.incrementClasses(classOffset);
1347 }
1348
1349 for (SoluteType soluteType : soluteTypes.values()) {
1350 soluteType.incrementType(typeOffset);
1351 }
1352 }
1353
1354
1355
1356
1357
1358
1359 public void setAngleFunction(AngleType.AngleFunction angleFunction) {
1360 for (AngleType angleType : anglepTypes.values()) {
1361 angleType.setAngleFunction(angleFunction);
1362 }
1363 for (AngleType angleType : angleTypes.values()) {
1364 angleType.setAngleFunction(angleFunction);
1365 }
1366 }
1367
1368
1369
1370
1371
1372
1373 public void setBondFunction(BondType.BondFunction bondFunction) {
1374 for (BondType bondType : bondTypes.values()) {
1375 bondType.setBondFunction(bondFunction);
1376 }
1377 }
1378
1379
1380
1381
1382
1383
1384
1385 public String toString(ForceFieldType type) {
1386 StringBuilder sb = new StringBuilder("\n");
1387 Map<String, ? extends BaseType> t = forceFieldTypes.get(type);
1388
1389 if (t.isEmpty()) {
1390 return "";
1391 }
1392
1393 for (Object o : t.values()) {
1394 sb.append(o.toString()).append("\n");
1395 }
1396 return sb.toString();
1397 }
1398
1399
1400
1401
1402 @Override
1403 public String toString() {
1404 String forceFieldName;
1405 try {
1406 forceFieldName = getString("FORCEFIELD");
1407 } catch (Exception ex) {
1408 forceFieldName = "Unknown";
1409 }
1410 return forceFieldName;
1411 }
1412
1413
1414
1415
1416
1417
1418
1419 public String toString(String key) {
1420 if (key == null) {
1421 return null;
1422 }
1423
1424 key = toPropertyForm(key);
1425
1426 if (properties.containsKey(key)) {
1427 List<Object> l = properties.getList(key);
1428 return key + " " + Arrays.toString(l.toArray());
1429 } else {
1430 return key + " is not defined.";
1431 }
1432 }
1433
1434
1435
1436
1437
1438
1439 public StringBuffer toStringBuffer() {
1440 StringBuffer sb = new StringBuffer();
1441 for (ForceFieldType s : forceFieldTypes.keySet()) {
1442 ForceFieldType type = ForceFieldType.valueOf(s.toString());
1443 sb.append(toString(type));
1444 }
1445 return sb;
1446 }
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457 private AtomType updateBioType(String molecule, String atom, int newType) {
1458 int oldType = 0;
1459 for (BioType bioType : bioTypes.values()) {
1460 if (bioType.moleculeName.equalsIgnoreCase(molecule)) {
1461 if (atom.length() <= bioType.atomName.length()) {
1462 if (bioType.atomName.toUpperCase().startsWith(atom.toUpperCase())) {
1463 oldType = bioType.atomType;
1464 bioType.atomType = newType;
1465 }
1466 }
1467 }
1468 }
1469 return getAtomType(Integer.toString(oldType));
1470 }
1471
1472
1473
1474
1475
1476
1477
1478
1479 private void patchClassesAndTypes(HashMap<AtomType, AtomType> typeMap,
1480 HashMap<String, AtomType> patchTypes) {
1481
1482 for (BondType bondType : bondTypes.values().toArray(new BondType[0])) {
1483 BondType newType = bondType.patchClasses(typeMap);
1484 if (newType != null) {
1485 logger.info(" " + newType);
1486 addForceFieldType(newType);
1487 }
1488 }
1489
1490 for (AngleType angleType : angleTypes.values().toArray(new AngleType[0])) {
1491 AngleType newType = angleType.patchClasses(typeMap);
1492 if (newType != null) {
1493 logger.info(" " + newType);
1494 addForceFieldType(newType);
1495 }
1496 }
1497
1498 for (OutOfPlaneBendType outOfPlaneBendType : outOfPlaneBendTypes.values()
1499 .toArray(new OutOfPlaneBendType[0])) {
1500 OutOfPlaneBendType newType = outOfPlaneBendType.patchClasses(typeMap);
1501 if (newType != null) {
1502 logger.info(" " + newType);
1503 addForceFieldType(newType);
1504 }
1505 }
1506
1507 for (PiOrbitalTorsionType piOrbitalTorsionType : piOrbitalTorsionTypes.values()
1508 .toArray(new PiOrbitalTorsionType[0])) {
1509 PiOrbitalTorsionType newType = piOrbitalTorsionType.patchClasses(typeMap);
1510 if (newType != null) {
1511 logger.info(" " + newType);
1512 addForceFieldType(newType);
1513 }
1514 }
1515
1516 for (StretchBendType stretchBendType : stretchBendTypes.values()
1517 .toArray(new StretchBendType[0])) {
1518 StretchBendType newType = stretchBendType.patchClasses(typeMap);
1519 if (newType != null) {
1520 logger.info(" " + newType);
1521 addForceFieldType(newType);
1522 }
1523 }
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534 for (TorsionType torsionType : torsionTypes.values().toArray(new TorsionType[0])) {
1535 TorsionType newType = torsionType.patchClasses(typeMap);
1536 if (newType != null) {
1537 logger.info(" " + newType);
1538 addForceFieldType(newType);
1539 }
1540 }
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561 for (MultipoleType multipoleType : multipoleTypes.values().toArray(new MultipoleType[0])) {
1562 MultipoleType newType = multipoleType.patchTypes(typeMap);
1563 if (newType != null) {
1564 logger.info(" " + newType);
1565 addForceFieldType(newType);
1566 }
1567 }
1568
1569 try {
1570 for (AtomType atomType : patchTypes.values()) {
1571 PolarizeType polarizeType = getPolarizeType(atomType.key);
1572 if (polarizeType != null && polarizeType.patchTypes(typeMap)) {
1573 logger.info(" " + polarizeType);
1574 }
1575 }
1576 } catch (Exception e) {
1577
1578 }
1579 }
1580
1581
1582
1583
1584
1585
1586 private int minClass() {
1587 int minClass = maxClass();
1588 for (AtomType type : atomTypes.values()) {
1589 if (type.atomClass < minClass) {
1590 minClass = type.atomClass;
1591 }
1592 }
1593 return minClass;
1594 }
1595
1596
1597
1598
1599
1600
1601 private int minType() {
1602 int minType = maxType();
1603 for (String key : atomTypes.keySet()) {
1604 int type = Integer.parseInt(key);
1605 if (type < minType) {
1606 minType = type;
1607 }
1608 }
1609 return minType;
1610 }
1611
1612
1613
1614
1615
1616
1617 private int minBioType() {
1618 int minBioType = maxBioType();
1619 for (String key : bioTypes.keySet()) {
1620 int type = Integer.parseInt(key);
1621 if (type < minBioType) {
1622 minBioType = type;
1623 }
1624 }
1625 return minBioType;
1626 }
1627
1628
1629
1630
1631
1632
1633 private int maxClass() {
1634 int maxClass = 0;
1635 for (AtomType type : atomTypes.values()) {
1636 if (type.atomClass > maxClass) {
1637 maxClass = type.atomClass;
1638 }
1639 }
1640 return maxClass;
1641 }
1642
1643
1644
1645
1646
1647
1648 private int maxType() {
1649 int maxType = 0;
1650 for (String key : atomTypes.keySet()) {
1651 int type = Integer.parseInt(key);
1652 if (type > maxType) {
1653 maxType = type;
1654 }
1655 }
1656 return maxType;
1657 }
1658
1659
1660
1661
1662
1663
1664 private int maxBioType() {
1665 int maxBioType = 0;
1666 for (String key : bioTypes.keySet()) {
1667 int type = Integer.parseInt(key);
1668 if (type > maxBioType) {
1669 maxBioType = type;
1670 }
1671 }
1672 return maxBioType;
1673 }
1674
1675 private void modifiedResidue(String modres) {
1676 String[] tokens = modres.trim().split(" +");
1677 String modResname = tokens[0].toUpperCase();
1678 String stdName = tokens[1].toUpperCase();
1679 HashMap<String, AtomType> patchAtomTypes = getAtomTypes(modResname);
1680 HashMap<String, AtomType> stdAtomTypes = getAtomTypes(stdName);
1681
1682 HashMap<String, AtomType> patchTypes = new HashMap<>();
1683 int len = tokens.length;
1684 for (int i = 2; i < len; i++) {
1685 String atomName = tokens[i].toUpperCase();
1686 if (!patchTypes.containsKey(atomName) && patchAtomTypes.containsKey(atomName)) {
1687 AtomType type = patchAtomTypes.get(atomName);
1688 patchTypes.put(atomName, type);
1689 }
1690 }
1691
1692 HashMap<AtomType, AtomType> typeMap = new HashMap<>();
1693 for (String atomName : stdAtomTypes.keySet()) {
1694 boolean found = false;
1695 for (int i = 2; i < len; i++) {
1696 if (atomName.equalsIgnoreCase(tokens[i])) {
1697 found = true;
1698 break;
1699 }
1700 }
1701 if (!found) {
1702 AtomType stdType = stdAtomTypes.get(atomName);
1703
1704 AtomType patchType = updateBioType(modResname, atomName, stdType.type);
1705 if (patchType != null) {
1706 typeMap.put(patchType, stdType);
1707 logger.info(" " + patchType + " -> " + stdType);
1708 }
1709 }
1710 }
1711
1712 patchClassesAndTypes(typeMap, patchTypes);
1713 }
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725 private void trueImpliedBoolean(String toSet, String... otherBooleans) {
1726
1727 if (getBoolean(toSet, false)) {
1728 return;
1729 }
1730
1731 for (String otherBool : otherBooleans) {
1732 if (getBoolean(otherBool, false)) {
1733 addProperty(toSet, "true");
1734 logger.info(format(" Setting implied boolean %s true due to boolean %s", toSet, otherBool));
1735 }
1736 }
1737 }
1738
1739
1740
1741
1742 private void checkPolarizationTypes() {
1743 boolean change = false;
1744 for (String key : polarizeTypes.keySet()) {
1745 PolarizeType polarizeType = polarizeTypes.get(key);
1746 int orig = Integer.parseInt(key);
1747 int[] types = polarizeType.polarizationGroup;
1748 if (types == null) {
1749 continue;
1750 }
1751
1752 for (int type : types) {
1753 String key2 = Integer.toString(type);
1754 PolarizeType polarizeType2 = polarizeTypes.get(key2);
1755 if (polarizeType2 == null) {
1756 logger.severe(
1757 format("Polarize type %s references nonexistant polarize type %s.", key, key2));
1758 continue;
1759 }
1760 int[] types2 = polarizeType2.polarizationGroup;
1761 if (types2 == null) {
1762 polarizeType2.add(orig);
1763 change = true;
1764 continue;
1765 }
1766 boolean found = false;
1767 for (int type2 : types2) {
1768 for (int type3 : types) {
1769 if (type2 == type3) {
1770 found = true;
1771 break;
1772 }
1773 }
1774 if (!found) {
1775 polarizeType.add(type2);
1776 change = true;
1777 }
1778 }
1779 }
1780 }
1781 if (change) {
1782 checkPolarizationTypes();
1783 }
1784 }
1785
1786 public enum ELEC_FORM {
1787 PAM, FIXED_CHARGE
1788 }
1789
1790
1791
1792
1793 public enum ForceFieldName {
1794 AMBER_1994, AMBER_1996, AMBER_1998, AMBER_1999, AMBER_1999_SB, AMOEBA_2004, AMOEBA_2009, AMOEBA_BIO_2009, AMOEBA_BIO_2018, AMOEBA_BIO_2018_CPHMD, AMOEBA_NUC_2017, AMOEBA_PROTEIN_2004, AMOEBA_PROTEIN_2013, AMOEBA_WATER_2003, AMOEBA_WATER_2014, CHARMM_22, CHARMM_22_CMAP, IAMOEBA_WATER, OPLS_AA, OPLS_AAL
1795 }
1796
1797 public enum ForceFieldType {
1798 KEYWORD, ANGLE, ANGLEP, ANGTORS, ATOM, BIOTYPE, BOND, CHARGE, IMPROPER, IMPTORS, MULTIPOLE, OPBEND, PITORS, POLARIZE, SOLUTE, STRBND, STRTORS, TORSION, TORTORS, UREYBRAD, VDW, VDW14, VDWPR, VDWPAIR, RELATIVESOLV
1799 }
1800
1801 }