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