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.parameters.AngleTorsionType;
41 import ffx.potential.parameters.AngleType;
42 import ffx.potential.parameters.AtomType;
43 import ffx.potential.parameters.BioType;
44 import ffx.potential.parameters.BondType;
45 import ffx.potential.parameters.ForceField;
46 import ffx.potential.parameters.MultipoleType;
47 import ffx.potential.parameters.OutOfPlaneBendType;
48 import ffx.potential.parameters.PiOrbitalTorsionType;
49 import ffx.potential.parameters.StretchBendType;
50 import ffx.potential.parameters.StretchTorsionType;
51 import ffx.potential.parameters.TorsionTorsionType;
52 import ffx.potential.parameters.TorsionType;
53 import ffx.potential.parameters.UreyBradleyType;
54 import ffx.potential.parameters.VDWType;
55 import org.w3c.dom.Document;
56 import org.w3c.dom.Element;
57
58 import javax.xml.parsers.DocumentBuilder;
59 import javax.xml.parsers.DocumentBuilderFactory;
60 import javax.xml.transform.OutputKeys;
61 import javax.xml.transform.Transformer;
62 import javax.xml.transform.TransformerException;
63 import javax.xml.transform.TransformerFactory;
64 import javax.xml.transform.dom.DOMSource;
65 import javax.xml.transform.stream.StreamResult;
66 import java.text.SimpleDateFormat;
67 import java.util.ArrayList;
68 import java.util.Date;
69 import java.util.HashMap;
70 import java.util.List;
71 import java.util.Map;
72 import java.util.logging.Logger;
73
74
75
76
77
78
79
80
81 public class OpenMMXmlFilter {
82
83
84
85
86 private static final Logger logger = Logger.getLogger(OpenMMXmlFilter.class.getName());
87
88
89
90
91 private final ForceField forceField;
92
93
94
95
96 private String outputName;
97
98
99
100
101
102
103 public OpenMMXmlFilter(ForceField forceField) {
104 this.forceField = forceField;
105 }
106
107
108
109
110
111
112
113 public OpenMMXmlFilter(ForceField forceField, String saveName) {
114 this.forceField = forceField;
115 this.outputName = saveName;
116 }
117
118
119
120
121
122
123 public void toXML() throws Exception {
124
125
126 DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
127 DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
128 Document doc = dBuilder.newDocument();
129
130
131 Element rootElement = doc.createElement("ForceField");
132 doc.appendChild(rootElement);
133
134
135 Element infoNode = doc.createElement("Info");
136 rootElement.appendChild(infoNode);
137
138
139 Element srcNode = doc.createElement("Source");
140 srcNode.setTextContent(forceField.getString("forcefield", "UNKNOWN"));
141 infoNode.appendChild(srcNode);
142
143
144 Element dateNode = doc.createElement("DateGenerated");
145 SimpleDateFormat ft = new SimpleDateFormat("yyyy-MM-dd");
146 String date = ft.format(new Date());
147 dateNode.setTextContent(date);
148 infoNode.appendChild(dateNode);
149
150
151 Element atomTypes = AtomType.getXMLAtomTypes(doc, forceField);
152 if (atomTypes != null) {
153 rootElement.appendChild(atomTypes);
154 } else {
155 throw new Exception(" The force field defines no atom types.");
156 }
157
158
159 Map<String, BioType> bioTypes = forceField.getBioTypeMap();
160 if (!bioTypes.values().isEmpty()) {
161 Map<String, ArrayList<BioType>> moleculeDict = new HashMap<>();
162 for (BioType bioType : bioTypes.values()) {
163 if (!moleculeDict.containsKey(bioType.moleculeName)) {
164 moleculeDict.put(bioType.moleculeName, new ArrayList<>());
165 }
166 ArrayList<BioType> moleculeBioTypes = moleculeDict.get(bioType.moleculeName);
167 moleculeBioTypes.add(bioType);
168 }
169 Element residuesNode = doc.createElement("Residues");
170 buildExtraResidues(moleculeDict, doc, residuesNode);
171 rootElement.appendChild(residuesNode);
172 } else {
173 logger.info("WARNING: No BioTypes defined for force field, therefore no OpenMM residues are created.");
174 }
175
176
177 Element bondForce = BondType.getXMLForce(doc, forceField);
178 if (bondForce != null) {
179 rootElement.appendChild(bondForce);
180 }
181
182
183 Element angleForce = AngleType.getXMLForce(doc, forceField);
184 if (angleForce != null) {
185 rootElement.appendChild(angleForce);
186 }
187
188
189 Element outOfPlaneBendForce = OutOfPlaneBendType.getXMLForce(doc, forceField);
190 if (outOfPlaneBendForce != null) {
191 rootElement.appendChild(outOfPlaneBendForce);
192 }
193
194
195 Element torsionForce = TorsionType.getXMLForce(doc, forceField);
196 if (torsionForce != null) {
197 rootElement.appendChild(torsionForce);
198 }
199
200
201 Element piOrbitalTorsionForce = PiOrbitalTorsionType.getXMLElement(doc, forceField);
202 if (piOrbitalTorsionForce != null) {
203 rootElement.appendChild(piOrbitalTorsionForce);
204 }
205
206
207 Element stretchTorsionForce = StretchTorsionType.getXMLForce(doc, forceField);
208 if (stretchTorsionForce != null) {
209 rootElement.appendChild(stretchTorsionForce);
210 }
211
212
213 Element angleTorsionForce = AngleTorsionType.getXMLForce(doc, forceField);
214 if (angleTorsionForce != null) {
215 rootElement.appendChild(angleTorsionForce);
216 }
217
218
219 Element stretchBendForce = StretchBendType.getXMLForce(doc, forceField);
220 if (stretchBendForce != null) {
221 rootElement.appendChild(stretchBendForce);
222 }
223
224
225 Element torsionTorsionForce = TorsionTorsionType.getXMLForce(doc, forceField);
226 if (torsionTorsionForce != null) {
227 rootElement.appendChild(torsionTorsionForce);
228 }
229
230
231 Element vdwForce = VDWType.getXMLForce(doc, forceField);
232 if (vdwForce != null) {
233 rootElement.appendChild(vdwForce);
234 }
235
236
237 Element multipoleForce = MultipoleType.getXMLForce(doc, forceField);
238 if (multipoleForce != null) {
239 rootElement.appendChild(multipoleForce);
240 }
241
242
243 Element ureyBradleyForce = UreyBradleyType.getXMLForce(doc, forceField);
244 if (ureyBradleyForce != null) {
245 rootElement.appendChild(ureyBradleyForce);
246 }
247
248
249 writeXML(doc);
250 }
251
252
253
254
255
256
257
258
259 private static void buildExtraResidues(Map<String, ArrayList<BioType>> moleculeDict, Document doc, Element residuesNode) {
260
261 for (String mol : moleculeDict.keySet()) {
262
263 Element resNode = doc.createElement("Residue");
264 resNode.setAttribute("name", mol);
265 residuesNode.appendChild(resNode);
266 List<String> order = new ArrayList<>();
267 List<String> froms = new ArrayList<>();
268 List<String> tos = new ArrayList<>();
269
270
271 int atomCount = 0;
272 int bondCount = 0;
273 for (BioType bioType : moleculeDict.get(mol)) {
274 String atom = bioType.atomName;
275 Element atomNode = doc.createElement("Atom");
276 atomNode.setAttribute("name", atom);
277 atomNode.setAttribute("type", String.valueOf(bioType.atomType));
278 resNode.appendChild(atomNode);
279 atomCount++;
280 String[] bonds = bioType.bonds;
281
282 for (String bond : bonds) {
283 BioType bondBioType = null;
284 for (BioType bioType2 : moleculeDict.get(mol)) {
285 if (bioType2.atomName.equals(bond)) {
286 bondBioType = bioType2;
287 break;
288 }
289 }
290
291
292 if (bioType.index < bondBioType.index) {
293 froms.add(atom);
294 tos.add(bond);
295 bondCount++;
296 }
297 }
298
299 order.add(atom);
300 }
301
302
303 for (int i = 0; i < froms.size(); i++) {
304 Element bondNode = doc.createElement("Bond");
305 bondNode.setAttribute("from", String.valueOf(order.indexOf(froms.get(i))));
306 bondNode.setAttribute("to", String.valueOf(order.indexOf(tos.get(i))));
307 resNode.appendChild(bondNode);
308 }
309 logger.info(" Added " + atomCount + " atoms and "
310 + bondCount + " bonds to residue " + mol + ".");
311 }
312 }
313
314
315
316
317
318
319
320 private void writeXML(Document doc) throws TransformerException {
321 String saveName;
322 if (outputName != null) {
323 saveName = outputName;
324 } else {
325 saveName = forceField.getString("forcefield", "UNKNOWN");
326 }
327
328 TransformerFactory tfFactory = TransformerFactory.newInstance();
329 Transformer transformer = tfFactory.newTransformer();
330
331 transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
332 transformer.setOutputProperty(OutputKeys.INDENT, "yes");
333
334 DOMSource src = new DOMSource(doc);
335 StreamResult result = new StreamResult(saveName + ".xml");
336 transformer.transform(src, result);
337 }
338 }