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.Double.parseDouble;
42 import static java.lang.Integer.parseInt;
43 import static java.lang.String.format;
44
45 import ffx.potential.parameters.ForceField.ForceFieldType;
46 import ffx.utilities.FFXProperty;
47
48 import java.util.Arrays;
49 import java.util.Comparator;
50 import java.util.logging.Level;
51 import java.util.logging.Logger;
52
53
54
55
56
57
58
59 @FFXProperty(name = "vdwpr", clazz = String.class, propertyGroup = PotentialFunctionParameter, description = """
60 [2 integers and 2 reals]
61 Provides the values for the vdw parameters for a single special heteroatomic pair of atoms.
62 The integer modifiers give the pair of atom class numbers for which special vdw parameters are to be defined.
63 The two real number modifiers give the values of the minimum energy contact distance in Angstroms and the well depth at the minimum distance in kcal/mole.
64 """)
65 public final class VDWPairType extends BaseType implements Comparator<String> {
66
67 private static final Logger logger = Logger.getLogger(VDWPairType.class.getName());
68
69
70
71 public final double radius;
72
73
74
75 public final double wellDepth;
76
77
78
79 public final int[] atomClasses;
80
81
82
83
84
85
86
87
88
89 public VDWPairType(int[] atomClasses, double radius, double wellDepth) {
90 super(ForceFieldType.VDWPR, sortKey(atomClasses));
91 this.atomClasses = atomClasses;
92 this.radius = radius;
93 this.wellDepth = wellDepth;
94 }
95
96
97
98
99
100
101
102
103
104 public static VDWPairType average(VDWPairType vdwType1, VDWPairType vdwType2, int[] atomClasses) {
105 if (vdwType1 == null || vdwType2 == null) {
106 return null;
107 }
108
109 double radius = (vdwType1.radius + vdwType2.radius) / 2.0;
110 double wellDepth = (vdwType1.wellDepth + vdwType2.wellDepth) / 2.0;
111
112 return new VDWPairType(atomClasses, radius, wellDepth);
113 }
114
115
116
117
118
119
120
121
122 public static VDWPairType parse(String input, String[] tokens) {
123 if (tokens.length < 5) {
124 logger.log(Level.WARNING, "Invalid VDWPR type:\n{0}", input);
125 } else {
126 try {
127 int atomClass1 = parseInt(tokens[1]);
128 int atomClass2 = parseInt(tokens[2]);
129 double radius = parseDouble(tokens[3]);
130 double wellDepth = parseDouble(tokens[4]);
131 return new VDWPairType(new int[]{atomClass1, atomClass2}, radius, wellDepth);
132 } catch (NumberFormatException e) {
133 String message = "Exception parsing VDWPR type:\n" + input + "\n";
134 logger.log(Level.SEVERE, message, e);
135 }
136 }
137 return null;
138 }
139
140
141
142
143 @Override
144 public int compare(String key1, String key2) {
145 String[] keys1 = key1.split(" ");
146 String[] keys2 = key2.split(" ");
147 int[] c1 = new int[2];
148 int[] c2 = new int[2];
149 for (int i = 0; i < 2; i++) {
150 c1[i] = Integer.parseInt(keys1[i]);
151 c2[i] = Integer.parseInt(keys2[i]);
152 }
153
154 if (c1[0] < c2[0]) {
155 return -1;
156 } else if (c1[0] > c2[0]) {
157 return 1;
158 } else if (c1[1] < c2[1]) {
159 return -1;
160 } else if (c1[1] > c2[1]) {
161 return 1;
162 }
163
164 return 0;
165 }
166
167
168
169
170 @Override
171 public boolean equals(Object o) {
172 if (this == o) {
173 return true;
174 }
175 if (o == null || getClass() != o.getClass()) {
176 return false;
177 }
178 VDWPairType vdwPairType = (VDWPairType) o;
179 return Arrays.equals(atomClasses, vdwPairType.atomClasses);
180 }
181
182
183
184
185 @Override
186 public int hashCode() {
187 return Arrays.hashCode(atomClasses);
188 }
189
190
191
192
193
194
195 @Override
196 public String toString() {
197 return format("vdwpr %5d %5d %11.9f %11.9f", atomClasses[0], atomClasses[1], radius,
198 wellDepth);
199 }
200
201
202
203
204
205
206
207 public static String sortKey(int[] c) {
208 if (c == null || c.length != 2) {
209 return null;
210 }
211
212 int temp;
213 if (c[1] <= c[0]) {
214 temp = c[1];
215 c[1] = c[0];
216 c[0] = temp;
217 }
218
219 return c[0] + " " + c[1];
220 }
221
222
223
224
225
226
227 public void incrementClasses(int increment) {
228 for (int i = 0; i < atomClasses.length; i++) {
229 atomClasses[i] += increment;
230 }
231 setKey(sortKey(atomClasses));
232 }
233
234 }