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 static ffx.potential.parameters.AngleType.AngleFunction;
41 import static ffx.potential.parameters.BondType.BondFunction;
42 import static java.lang.String.format;
43
44 import ffx.potential.parameters.AngleTorsionType;
45 import ffx.potential.parameters.AngleType;
46 import ffx.potential.parameters.AtomType;
47 import ffx.potential.parameters.BaseType;
48 import ffx.potential.parameters.BioType;
49 import ffx.potential.parameters.BondType;
50 import ffx.potential.parameters.ForceField;
51 import ffx.potential.parameters.ForceField.ForceFieldName;
52 import ffx.potential.parameters.ForceField.ForceFieldType;
53 import ffx.potential.parameters.ImproperTorsionType;
54 import ffx.potential.parameters.MultipoleType;
55 import ffx.potential.parameters.OutOfPlaneBendType;
56 import ffx.potential.parameters.PiOrbitalTorsionType;
57 import ffx.potential.parameters.PolarizeType;
58 import ffx.potential.parameters.RelativeSolvationType;
59 import ffx.potential.parameters.SoluteType;
60 import ffx.potential.parameters.StretchBendType;
61 import ffx.potential.parameters.StretchTorsionType;
62 import ffx.potential.parameters.TorsionTorsionType;
63 import ffx.potential.parameters.TorsionType;
64 import ffx.potential.parameters.UreyBradleyType;
65 import ffx.potential.parameters.VDWPairType;
66 import ffx.potential.parameters.VDWType;
67 import ffx.utilities.Keyword;
68 import java.io.BufferedReader;
69 import java.io.File;
70 import java.io.FileInputStream;
71 import java.io.FileNotFoundException;
72 import java.io.IOException;
73 import java.io.InputStream;
74 import java.io.InputStreamReader;
75 import java.net.URL;
76 import java.util.Iterator;
77 import java.util.logging.Level;
78 import java.util.logging.Logger;
79 import org.apache.commons.configuration2.CompositeConfiguration;
80 import org.apache.commons.configuration2.Configuration;
81 import org.apache.commons.configuration2.PropertiesConfiguration;
82 import org.apache.commons.configuration2.builder.FileBasedConfigurationBuilder;
83 import org.apache.commons.configuration2.builder.fluent.Parameters;
84 import org.apache.commons.configuration2.ex.ConfigurationException;
85
86
87
88
89
90
91
92
93
94
95 public class ForceFieldFilter {
96
97 private static final Logger logger = Logger.getLogger(ForceFieldFilter.class.getName());
98
99
100 private static final ForceFieldName DEFAULT_FORCE_FIELD = ForceFieldName.AMOEBA_BIO_2018;
101
102 private final File forceFieldFile;
103
104 private final CompositeConfiguration properties;
105
106 private final ForceField forceField;
107
108
109
110
111
112
113
114 public ForceFieldFilter(CompositeConfiguration properties) {
115 this.properties = properties;
116 if (properties.containsKey("parameters")) {
117 String fileName = properties.getString("parameters");
118 if (properties.containsKey("propertyFile")) {
119 String propertyName = properties.getString("propertyFile");
120 logger.info(" Property File: " + propertyName);
121 File propertyFile = new File(propertyName);
122 forceFieldFile = parseParameterLocation(fileName, propertyFile);
123 } else {
124 forceFieldFile = parseParameterLocation(fileName, null);
125 }
126 } else {
127 forceFieldFile = null;
128 }
129 forceField = new ForceField(properties);
130 }
131
132
133
134
135
136
137 public static void main(String[] args) {
138 if (args == null || args.length < 1) {
139 System.out.println("Usage: ForceFieldFilter <file.prm>");
140 System.exit(-1);
141 }
142 CompositeConfiguration properties = Keyword.loadProperties(null);
143 properties.setProperty("parameters", args[0]);
144 ForceFieldFilter forceFieldFilter = new ForceFieldFilter(properties);
145 ForceField forceField = forceFieldFilter.parse();
146 if (forceField != null) {
147 forceField.print();
148 }
149 }
150
151
152
153
154
155
156
157
158 private static File parseParameterLocation(String parameterLocation, File keyFile) {
159 File parameterFile = null;
160 if (parameterLocation != null && !parameterLocation.equalsIgnoreCase("NONE")) {
161
162 parameterLocation = parameterLocation.replaceAll("\"", "");
163
164 parameterFile = new File(parameterLocation);
165
166
167 if (!parameterFile.exists() && keyFile != null) {
168 parameterFile = new File(keyFile.getParent() + File.separator + parameterLocation);
169 }
170 }
171 return parameterFile;
172 }
173
174
175
176
177
178
179 public ForceField parse() {
180 try {
181
182 if (forceFieldFile != null) {
183 File fileToOpen = forceFieldFile;
184 if (!fileToOpen.exists()) {
185 fileToOpen = new File(forceFieldFile.getAbsolutePath() + ".prm");
186 if (!fileToOpen.exists()) {
187 logger.log(Level.INFO, " {0} does not exist.", forceFieldFile);
188 return null;
189 }
190 }
191 if (!fileToOpen.canRead()) {
192 logger.log(Level.INFO, " {0} can not be read.", fileToOpen);
193 return null;
194 }
195 parse(new FileInputStream(fileToOpen));
196 } else {
197
198 String defaultFFstring = DEFAULT_FORCE_FIELD.toString().toUpperCase().replaceAll("_", "-");
199 String forceFieldString = properties.getString("forcefield", defaultFFstring);
200 ForceFieldName ff;
201 try {
202 ff = ForceField.ForceFieldName.valueOf(forceFieldString.toUpperCase().replace('-', '_'));
203 } catch (Exception e) {
204 logger.info(format(" The forcefield property %s was not recognized.\n", forceFieldString));
205 ff = DEFAULT_FORCE_FIELD;
206 }
207 URL url = ForceField.getForceFieldURL(ff);
208 if (url != null) {
209 forceField.forceFieldURL = url;
210 try {
211 FileBasedConfigurationBuilder<PropertiesConfiguration> builder = new FileBasedConfigurationBuilder<>(
212 PropertiesConfiguration.class).configure(
213 new Parameters().properties().setURL(url).setThrowExceptionOnMissing(true)
214
215 .setIncludesAllowed(false));
216 PropertiesConfiguration forceFieldConfiguration = builder.getConfiguration();
217 String name = ForceField.toPropertyForm(ff.toString());
218 forceFieldConfiguration.setHeader("Internal force field (" + name + ").");
219 properties.addConfiguration(forceFieldConfiguration);
220 } catch (ConfigurationException e) {
221 logger.warning(e.toString());
222 }
223 }
224 }
225
226
227 if (properties != null) {
228 parse(properties);
229 }
230 } catch (FileNotFoundException e) {
231 String message = "Exception parsing force field.";
232 logger.log(Level.WARNING, message, e);
233 }
234
235 String forceFieldName = forceField.getString("forcefield", "none");
236 if (forceFieldName != null) {
237 forceFieldName = forceFieldName.toUpperCase();
238 if (forceFieldName.contains("AMBER") || forceFieldName.contains("OPLS")
239 || forceFieldName.contains("CHARMM")) {
240 forceField.setBondFunction(BondFunction.HARMONIC);
241 forceField.setAngleFunction(AngleFunction.HARMONIC);
242 }
243 }
244
245 return forceField;
246 }
247
248 private void parse(CompositeConfiguration properties) {
249 try {
250 int numConfigs = properties.getNumberOfConfigurations();
251
252
253
254
255
256 for (int n = numConfigs - 1; n >= 0; n--) {
257 Configuration config = properties.getConfiguration(n);
258 if (config instanceof PropertiesConfiguration propertiesConfiguration) {
259 if (propertiesConfiguration.getHeader() != null) {
260 logger.info(" Parsing: " + propertiesConfiguration.getHeader());
261 }
262 }else{
263 if(logger.isLoggable(Level.FINER)) {
264 logger.finer(" Configuration was not an instance of PropertiesConfiguration.");
265 }
266 }
267
268 Iterator<String> i = config.getKeys();
269 while (i.hasNext()) {
270 String key = i.next();
271
272
273 if (!ForceField.isForceFieldType(key)) {
274 if(logger.isLoggable(Level.FINER)){
275 logger.finer(" Key value (" + key + ") is not a valid force field type.");
276 }
277 continue;
278 }
279
280 String[] list = config.getStringArray(key);
281 for (String s : list) {
282
283 s = key + " " + s;
284
285
286 String input = s.split("#+")[0];
287 String[] tokens = input.trim().split(" +");
288
289
290 ForceFieldType type;
291 try {
292 type = ForceFieldType.valueOf(key.toUpperCase());
293 } catch (Exception e) {
294 break;
295 }
296
297 BaseType baseType = switch (type) {
298 case ATOM -> AtomType.parse(input, tokens);
299 case ANGTORS -> AngleTorsionType.parse(input, tokens);
300 case ANGLE -> AngleType.parse(input, tokens);
301 case ANGLEP -> AngleType.parseInPlane(input, tokens);
302 case BIOTYPE -> BioType.parse(input, tokens);
303 case BOND -> BondType.parse(input, tokens);
304 case CHARGE -> MultipoleType.parseChargeType(input, tokens);
305 case MULTIPOLE -> MultipoleType.parse(input, tokens);
306 case OPBEND -> OutOfPlaneBendType.parse(input, tokens);
307 case STRBND -> StretchBendType.parse(input, tokens);
308 case PITORS -> PiOrbitalTorsionType.parse(input, tokens);
309 case IMPTORS -> ImproperTorsionType.parse(input, tokens);
310 case TORSION -> TorsionType.parse(input, tokens);
311 case IMPROPER -> TorsionType.parseImproper(input, tokens);
312 case STRTORS -> StretchTorsionType.parse(input, tokens);
313 case TORTORS -> TorsionTorsionType.parse(input, tokens);
314 case UREYBRAD -> UreyBradleyType.parse(input, tokens);
315 case VDW -> VDWType.parse(input, tokens);
316 case VDW14 -> VDWType.parseVDW14(input, tokens);
317 case VDWPR, VDWPAIR -> VDWPairType.parse(input, tokens);
318 case POLARIZE -> PolarizeType.parse(input, tokens);
319 case RELATIVESOLV -> RelativeSolvationType.parse(input, tokens);
320 case SOLUTE -> SoluteType.parse(input, tokens);
321 default -> {
322 logger.log(Level.WARNING, "ForceField type recognized, but not stored:{0}", type);
323 yield null;
324 }
325 };
326 if (baseType != null) {
327 forceField.addForceFieldType(baseType);
328 }
329 }
330 }
331 }
332 } catch (Exception e) {
333 String message = "Exception parsing force field.";
334 logger.log(Level.WARNING, message, e);
335 }
336 logger.info("");
337 }
338
339 private void parse(InputStream stream) {
340 try (BufferedReader br = new BufferedReader(new InputStreamReader(stream))) {
341 while (br.ready()) {
342 String input = br.readLine();
343 parse(input, br);
344 }
345 } catch (IOException e) {
346 String message = "Error parsing force field parameters.\n";
347 logger.log(Level.SEVERE, message, e);
348 }
349 }
350
351 private void parse(String input, BufferedReader br) {
352
353
354 String originalInput = input;
355 String[] inputs = input.split("#");
356 if (inputs.length < 1) {
357 return;
358 }
359
360 input = inputs[0].split("#")[0];
361
362 String[] tokens = input.trim().split(" +");
363 if (tokens[0].equalsIgnoreCase("")) {
364 return;
365 }
366
367 try {
368 ForceFieldType type = ForceFieldType.valueOf(tokens[0].toUpperCase());
369 BaseType baseType = switch (type) {
370 case ATOM -> AtomType.parse(input, tokens);
371 case ANGLE -> AngleType.parse(input, tokens);
372 case ANGLEP -> AngleType.parseInPlane(input, tokens);
373 case ANGTORS -> AngleTorsionType.parse(input, tokens);
374 case BIOTYPE -> BioType.parse(input, tokens);
375 case BOND -> BondType.parse(input, tokens);
376 case CHARGE -> MultipoleType.parseChargeType(input, tokens);
377 case MULTIPOLE -> MultipoleType.parse(input, tokens, br);
378 case OPBEND -> OutOfPlaneBendType.parse(input, tokens);
379 case STRBND -> StretchBendType.parse(input, tokens);
380 case PITORS -> PiOrbitalTorsionType.parse(input, tokens);
381 case IMPTORS -> ImproperTorsionType.parse(input, tokens);
382 case STRTORS -> StretchTorsionType.parse(input, tokens);
383 case TORSION -> TorsionType.parse(input, tokens);
384 case IMPROPER -> TorsionType.parseImproper(input, tokens);
385 case TORTORS -> TorsionTorsionType.parse(input, tokens, br);
386 case UREYBRAD -> UreyBradleyType.parse(input, tokens);
387 case VDW -> VDWType.parse(input, tokens);
388 case VDW14 -> VDWType.parseVDW14(input, tokens);
389 case VDWPR, VDWPAIR -> VDWPairType.parse(input, tokens);
390 case POLARIZE -> PolarizeType.parse(input, tokens);
391 case RELATIVESOLV -> RelativeSolvationType.parse(input, tokens);
392 case SOLUTE ->
393
394 SoluteType.parse(originalInput, originalInput.trim().split(" +"));
395 default -> {
396 logger.log(Level.WARNING, "ForceField type recognized, but not stored:{0}", type);
397 yield null;
398 }
399 };
400 if (baseType != null) {
401 forceField.addForceFieldType(baseType);
402 }
403 return;
404 } catch (Exception e) {
405
406
407
408
409 }
410
411
412 try {
413 String key = tokens[0];
414 String value = input.replaceFirst(tokens[0], "").trim();
415 forceField.addProperty(key, value);
416 } catch (Exception e) {
417 logger.info(" Ignored line: " + input);
418 }
419 }
420 }