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.bonded;
39
40 import static ffx.numerics.math.DoubleMath.dist;
41 import static ffx.potential.bonded.BondedUtils.buildBond;
42 import static ffx.potential.bonded.BondedUtils.buildHeavy;
43 import static ffx.potential.bonded.BondedUtils.buildH;
44 import static ffx.potential.bonded.BondedUtils.intxyz;
45 import static ffx.potential.bonded.AminoAcidUtils.ResiduePosition.FIRST_RESIDUE;
46 import static ffx.potential.bonded.AminoAcidUtils.ResiduePosition.LAST_RESIDUE;
47 import static ffx.potential.bonded.AminoAcidUtils.ResiduePosition.MIDDLE_RESIDUE;
48 import static java.lang.String.format;
49 import static org.apache.commons.math3.util.FastMath.toDegrees;
50
51 import ffx.numerics.math.DoubleMath;
52 import ffx.potential.bonded.BondedUtils.MissingAtomTypeException;
53 import ffx.potential.bonded.BondedUtils.MissingHeavyAtomException;
54 import ffx.potential.bonded.AminoAcidUtils.ResiduePosition;
55 import ffx.potential.parameters.AtomType;
56 import ffx.potential.parameters.ForceField;
57 import java.util.Arrays;
58 import java.util.HashMap;
59 import java.util.List;
60 import java.util.Map;
61 import java.util.logging.Level;
62 import java.util.logging.Logger;
63
64
65
66
67
68
69
70 public class NucleicAcidUtils {
71
72 private static final Logger logger = Logger.getLogger(NucleicAcidUtils.class.getName());
73
74
75
76
77 public enum NA {
78 ADENINE, CYTOSINE, GUANINE, URACIL, DEOXYADENINE, DEOXYCYTOSINE, DEOXYGUANINE, THYMINE, MONOPHOSPHATE, DIPHOSPHATE, TRIPHOSPHATE
79 }
80
81 public enum NucleicAcid1 {
82 A, G, C, U, D, B, I, T, O, W, H, X
83 }
84
85
86
87
88
89 public enum NucleicAcid3 {
90 ADE, GUA, CYT, URI, DAD, DGU, DCY, DTY, THY, MP1, DP2, TP3, UNK, M2MG, H2U, M2G, OMC, OMG, PSU, M5MC, M7MG, M5MU, M1MA, YYG;
91
92
93
94
95
96
97
98
99 public static NucleicAcid3 parse(String name) throws IllegalArgumentException {
100
101 return switch (name.toUpperCase()) {
102 case "ADE", "A" -> NucleicAcid3.ADE;
103 case "CYT", "C" -> NucleicAcid3.CYT;
104 case "GUA", "G" -> NucleicAcid3.GUA;
105 case "URI", "U" -> NucleicAcid3.URI;
106 case "DAD", "DA" -> NucleicAcid3.DAD;
107 case "DCY", "DC" -> NucleicAcid3.DCY;
108 case "DGU", "DG" -> NucleicAcid3.DGU;
109 case "DTY", "THY", "DT" -> NucleicAcid3.DTY;
110 case "MPO" -> NucleicAcid3.MP1;
111 case "DPO" -> NucleicAcid3.DP2;
112 case "TPO" -> NucleicAcid3.TP3;
113 case "DU" -> throw new IllegalArgumentException(" No NA3 value exists for deoxy-uracil!");
114 default -> NucleicAcid3.UNK;
115 };
116 }
117 }
118
119
120
121
122
123 public static final int[] NA_O5 = {1001, 1031, 1062, 1090, 1117, 1146, 1176, 1203, 0, 0, 0, 0,
124 1300, 1334, 1363, 1400, 1431, 1465, 1492, 1523, 1559, 1589, 1624};
125
126 public static final int[] NA_C5 = {1002, 1032, 1063, 1091, 1118, 1147, 1177, 1204, 0, 0, 0, 0,
127 1301, 1335, 1364, 1401, 1432, 1466, 1493, 1524, 1560, 1590, 1625};
128
129 public static final int[] NA_H51 = {1003, 1033, 1064, 1092, 1119, 1148, 1178, 1205, 0, 0, 0, 0,
130 1302, 1336, 1365, 1402, 1433, 1467, 1494, 1525, 1561, 1591, 1626};
131
132 public static final int[] NA_H52 = {1004, 1034, 1065, 1093, 1120, 1149, 1179, 1206, 0, 0, 0, 0,
133 1303, 1337, 1366, 1403, 1434, 1468, 1495, 1526, 1562, 1592, 1627};
134
135 public static final int[] NA_C4 = {1005, 1035, 1066, 1094, 1121, 1150, 1180, 1207, 0, 0, 0, 0,
136 1304, 1338, 1367, 1404, 1435, 1469, 1496, 1527, 1563, 1593, 1628};
137
138 public static final int[] NA_H4 = {1006, 1036, 1067, 1095, 1122, 1151, 1181, 1208, 0, 0, 0, 0,
139 1305, 1339, 1368, 1405, 1436, 1470, 1497, 1528, 1564, 1594, 1629};
140
141 public static final int[] NA_O4 = {1007, 1037, 1068, 1096, 1123, 1152, 1182, 1209, 0, 0, 0, 0,
142 1306, 1340, 1369, 1406, 1437, 1471, 1498, 1529, 1565, 1595, 1630};
143
144 public static final int[] NA_C1 = {1008, 1038, 1069, 1097, 1124, 1153, 1183, 1210, 0, 0, 0, 0,
145 1307, 1341, 1370, 1407, 1438, 1472, 1499, 1530, 1566, 1596, 1631};
146
147 public static final int[] NA_H1 = {1009, 1039, 1070, 1098, 1125, 1154, 1184, 1211, 0, 0, 0, 0,
148 1308, 1342, 1371, 1408, 1439, 1473, 1500, 1531, 1567, 1597, 1632};
149
150 public static final int[] NA_C3 = {1010, 1040, 1071, 1099, 1126, 1155, 1185, 1212, 0, 0, 0, 0,
151 1309, 1343, 1372, 1409, 1440, 1474, 1501, 1532, 1568, 1598, 1633};
152
153 public static final int[] NA_H3 = {1011, 1041, 1072, 1100, 1127, 1156, 1186, 1213, 0, 0, 0, 0,
154 1310, 1344, 1373, 1410, 1441, 1475, 1502, 1533, 1569, 1599, 1634};
155
156 public static final int[] NA_C2 = {1012, 1042, 1073, 1101, 1128, 1157, 1187, 1214, 0, 0, 0, 0,
157 1311, 1345, 1374, 1411, 1442, 1476, 1503, 1534, 1570, 1600, 1635};
158
159 public static final int[] NA_H21 = {1013, 1043, 1074, 1102, 1129, 1158, 1188, 1215, 0, 0, 0, 0,
160 1312, 1346, 1375, 1412, 1443, 1477, 1504, 1535, 1571, 1601, 1636};
161
162 public static final int[] NA_O2 = {1014, 1044, 1075, 1103, 0, 0, 0, 0, 0, 0, 0, 0, 1313, 1347,
163 1376, 1413, 1444, 1478, 1505, 1536, 1572, 1602, 1637};
164
165 public static final int[] NA_H22 = {1015, 1045, 1076, 1104, 1130, 1159, 1189, 1216, 0, 0, 0, 0,
166 1314, 1348, 1377, 0, 0, 1479, 1506, 1537, 1573, 1603, 1638};
167
168 public static final int[] NA_O3 = {1016, 1046, 1077, 1105, 1131, 1160, 1190, 1217, 0, 0, 0, 0,
169 1315, 1349, 1378, 1414, 1445, 1480, 1507, 1538, 1574, 1604, 1639};
170
171 public static final int[] NA_P = {1230, 1230, 1230, 1230, 1242, 1242, 1242, 1242, 0, 0, 0, 0, 1230,
172 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230};
173
174 public static final int[] NA_OP = {1231, 1231, 1231, 1231, 1243, 1243, 1243, 1243, 0, 0, 0, 0,
175 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231};
176
177
178
179
180
181 public static final int[] NA_HO5T = {1233, 1233, 1233, 1233, 1245, 1245, 1245, 1245, 0, 0, 0, 0,
182 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233};
183
184
185
186
187
188 public static final int[] NA_HO3T = {1238, 1238, 1238, 1238, 1250, 1250, 1250, 1250, 0, 0, 0, 0,
189 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238};
190
191
192 public static final List<NucleicAcid3> nucleicAcidList = Arrays.asList(NucleicAcid3.values());
193
194
195 public static final HashMap<NucleicAcid1, NucleicAcid3> NA1toNA3 = new HashMap<>();
196
197
198 private static final Map<String, String> newNucleicAcidAtomNames;
199
200
201 public static final int[] NAPATTERN = {8, 6, 6, 6, 8};
202
203 static {
204 newNucleicAcidAtomNames = Map.of("HO'", "HO2'", "H3T", "HO3'", "H5'1", "H5'", "H5'2", "H5''",
205 "H5T", "HO5'", "H2'1", "H2'", "H2'2", "H2''");
206
207 NucleicAcid1[] na1 = NucleicAcid1.values();
208 NucleicAcid3[] na3 = NucleicAcid3.values();
209 for (int i = 0; i < NucleicAcid1.values().length; i++) {
210 NA1toNA3.put(na1[i], na3[i]);
211 }
212 }
213
214
215
216
217
218
219
220
221
222
223 public static void assignNucleicAcidAtomTypes(List<Residue> residues, ForceField forceField,
224 List<Bond> bondList) throws MissingHeavyAtomException, MissingAtomTypeException {
225
226
227 Atom pSugarO3 = null;
228
229
230 int numberOfResidues = residues.size();
231 for (int residueNumber = 0; residueNumber < numberOfResidues; residueNumber++) {
232
233
234 Residue residue = residues.get(residueNumber);
235 String residueName = residue.getName().toUpperCase();
236 NucleicAcid3 nucleicAcid = null;
237 int naNumber = -1;
238 for (NucleicAcid3 nucleic : nucleicAcidList) {
239 naNumber++;
240 String nuc3 = nucleic.toString();
241 nuc3 = nuc3.substring(nuc3.length() - 3);
242 if (nuc3.equalsIgnoreCase(residueName)) {
243 nucleicAcid = nucleic;
244 break;
245 }
246 }
247
248
249 List<Atom> resAtoms = residue.getAtomList();
250 int nAtoms = resAtoms.size();
251 for (Atom atom : resAtoms) {
252 String name = atom.getName();
253 name = name.replace('*', '\'');
254 name = newNucleicAcidAtomNames.getOrDefault(name, name);
255 atom.setName(name);
256 }
257
258
259 ResiduePosition position = MIDDLE_RESIDUE;
260 boolean lastRes = false;
261 if (residueNumber == 0) {
262 position = FIRST_RESIDUE;
263 }
264
265 if (residueNumber == numberOfResidues - 1) {
266 lastRes = true;
267 if (position != FIRST_RESIDUE) {
268 position = LAST_RESIDUE;
269 }
270 }
271
272
273 boolean threePrimeCap = isThreePrimeCap(nAtoms, resAtoms);
274
275
276 boolean isDNA = false;
277 Residue resToCheck = threePrimeCap ? residues.get(residueNumber - 1) : residue;
278 Atom sugarO2 = (Atom) resToCheck.getAtomNode("O2'");
279
280 if (sugarO2 == null) {
281
282 isDNA = true;
283 if (!residueName.startsWith("D")) {
284 switch (nucleicAcid) {
285 case ADE -> {
286 nucleicAcid = NucleicAcid3.DAD;
287 residueName = "DAD";
288 residue.setName(residueName);
289 }
290 case CYT -> {
291 nucleicAcid = NucleicAcid3.DCY;
292 residueName = "DCY";
293 residue.setName(residueName);
294 }
295 case GUA -> {
296 nucleicAcid = NucleicAcid3.DGU;
297 residueName = "DGU";
298 residue.setName(residueName);
299 }
300 case THY -> {
301 nucleicAcid = NucleicAcid3.DTY;
302 residueName = "DTY";
303 residue.setName(residueName);
304 }
305 default -> {
306 }
307 }
308 }
309 } else {
310
311 if (residueName.startsWith("D")) {
312 switch (nucleicAcid) {
313 case DAD -> {
314 nucleicAcid = NucleicAcid3.ADE;
315 residueName = "ADE";
316 residue.setName(residueName);
317 }
318 case DCY -> {
319 nucleicAcid = NucleicAcid3.CYT;
320 residueName = "CYT";
321 residue.setName(residueName);
322 }
323 case DGU -> {
324 nucleicAcid = NucleicAcid3.GUA;
325 residueName = "GUA";
326 residue.setName(residueName);
327 }
328 case DTY -> {
329 nucleicAcid = NucleicAcid3.THY;
330 residueName = "THY";
331 residue.setName(residueName);
332 }
333 default -> {
334 }
335 }
336 }
337 }
338
339
340 Atom phosphate = null;
341 Atom sugarO5 = null;
342 Atom sugarO3 = null;
343
344 if (threePrimeCap) {
345 if (logger.isLoggable(Level.FINE)) {
346 logger.fine(format(" EXPERIMENTAL: Adding 3'-terminal phosphate cap %s", residue));
347 }
348 Residue priorResidue = residues.get(residueNumber - 1);
349 int phosType = isDNA ? 1252 : 1240;
350 int oxygenType = isDNA ? 1253 : 1241;
351
352 phosphate = buildHeavy(residue, "P", pSugarO3, phosType, forceField, bondList);
353 buildHeavy(residue, "OP1", phosphate, oxygenType, forceField, bondList);
354 buildHeavy(residue, "OP2", phosphate, oxygenType, forceField, bondList);
355 switch (nAtoms) {
356 case 3 ->
357 buildOP3(residue, phosphate, oxygenType, forceField, bondList, priorResidue, false);
358 case 4 -> {
359 MSNode bogusO5s = residue.getAtomNode("O5'");
360 if (bogusO5s != null) {
361 bogusO5s.setName("OP3");
362 }
363 buildHeavy(residue, "OP3", phosphate, oxygenType, forceField, bondList);
364 }
365 case 5, 6 -> logger.severe(" Currently, FFX does not support partially-protonated "
366 + "3'-terminal phosphate caps from PDB files!");
367 }
368 } else {
369 if (position == FIRST_RESIDUE) {
370
371
372
373
374
375
376 phosphate = (Atom) residue.getAtomNode("P");
377 if (phosphate != null) {
378 Residue nextRes = lastRes ? null : residues.get(residueNumber + 1);
379 if (isDNA) {
380 phosphate = buildHeavy(residue, "P", null, 1247, forceField, bondList);
381 buildHeavy(residue, "OP1", phosphate, 1248, forceField, bondList);
382 buildHeavy(residue, "OP2", phosphate, 1248, forceField, bondList);
383 buildOP3(residue, phosphate, 1248, forceField, bondList, nextRes, true);
384 sugarO5 = buildHeavy(residue, "O5'", phosphate, 1246, forceField, bondList);
385 } else {
386 phosphate = buildHeavy(residue, "P", null, 1235, forceField, bondList);
387 buildHeavy(residue, "OP1", phosphate, 1236, forceField, bondList);
388 buildHeavy(residue, "OP2", phosphate, 1236, forceField, bondList);
389 buildOP3(residue, phosphate, 1236, forceField, bondList, nextRes, true);
390 sugarO5 = buildHeavy(residue, "O5'", phosphate, 1234, forceField, bondList);
391 }
392 } else if (isDNA) {
393 Atom O5 = residue.getAtomByName("O5'", true);
394 if (O5 == null) {
395 sugarO5 = buildSugarO5(residue, 1244, forceField);
396 } else {
397 sugarO5 = buildHeavy(residue, "O5'", null, 1244, forceField, bondList);
398 }
399 } else {
400 Atom O5 = residue.getAtomByName("O5'", true);
401 if (O5 == null) {
402 sugarO5 = buildSugarO5(residue, 1232, forceField);
403 } else {
404 sugarO5 = buildHeavy(residue, "O5'", null, 1232, forceField, bondList);
405 }
406 }
407 } else {
408 phosphate = buildHeavy(residue, "P", pSugarO3, NA_P[naNumber], forceField, bondList);
409 buildHeavy(residue, "OP1", phosphate, NA_OP[naNumber], forceField, bondList);
410 buildHeavy(residue, "OP2", phosphate, NA_OP[naNumber], forceField, bondList);
411 sugarO5 = buildHeavy(residue, "O5'", phosphate, NA_O5[naNumber], forceField, bondList);
412 }
413
414
415 Atom sugarC5 = buildHeavy(residue, "C5'", sugarO5, NA_C5[naNumber], forceField, bondList);
416 Atom sugarC4 = buildHeavy(residue, "C4'", sugarC5, NA_C4[naNumber], forceField, bondList);
417 Atom sugarO4 = buildHeavy(residue, "O4'", sugarC4, NA_O4[naNumber], forceField, bondList);
418 Atom sugarC1 = buildHeavy(residue, "C1'", sugarO4, NA_C1[naNumber], forceField, bondList);
419 Atom sugarC3 = buildHeavy(residue, "C3'", sugarC4, NA_C3[naNumber], forceField, bondList);
420 Atom sugarC2 = buildHeavy(residue, "C2'", sugarC3, NA_C2[naNumber], forceField, bondList);
421 buildBond(sugarC2, sugarC1, forceField, bondList);
422 if (position == LAST_RESIDUE || numberOfResidues == 1) {
423 if (isDNA) {
424 sugarO3 = buildHeavy(residue, "O3'", sugarC3, 1249, forceField, bondList);
425 } else {
426 sugarO3 = buildHeavy(residue, "O3'", sugarC3, 1237, forceField, bondList);
427 }
428 } else {
429 boolean nextResIsCap = (residues.get(residueNumber + 1).getAtomList().size() < 7);
430 int o3Type = NA_O3[naNumber];
431 if (nextResIsCap) {
432 logger.fine(" Applying a 3'-terminal-phos-cap O3' atom type to residue " + residue);
433 o3Type = isDNA ? 1251 : 1239;
434 }
435 sugarO3 = buildHeavy(residue, "O3'", sugarC3, o3Type, forceField, bondList);
436 }
437 if (!isDNA) {
438 sugarO2 = buildHeavy(residue, "O2'", sugarC2, NA_O2[naNumber], forceField, bondList);
439 }
440
441
442 if (position == FIRST_RESIDUE && phosphate == null) {
443 buildH(residue, "HO5'", sugarO5, 1.00e0, sugarC5, 109.5e0, sugarC4, 180.0e0, 0,
444 NA_HO5T[naNumber], forceField, bondList);
445 }
446 buildH(residue, "H5'", sugarC5, 1.09e0, sugarO5, 109.5e0, sugarC4, 109.5e0, 1,
447 NA_H51[naNumber], forceField, bondList);
448 buildH(residue, "H5''", sugarC5, 1.09e0, sugarO5, 109.5e0, sugarC4, 109.5e0, -1,
449 NA_H52[naNumber], forceField, bondList);
450 buildH(residue, "H4'", sugarC4, 1.09e0, sugarC5, 109.5e0, sugarC3, 109.5e0, -1,
451 NA_H4[naNumber], forceField, bondList);
452 buildH(residue, "H3'", sugarC3, 1.09e0, sugarC4, 109.5e0, sugarC2, 109.5e0, -1,
453 NA_H3[naNumber], forceField, bondList);
454 if (isDNA) {
455 buildH(residue, "H2'", sugarC2, 1.09e0, sugarC3, 109.5e0, sugarC1, 109.5e0, -1,
456 NA_H21[naNumber], forceField, bondList);
457 buildH(residue, "H2''", sugarC2, 1.09e0, sugarC3, 109.5e0, sugarC1, 109.5e0, 1,
458 NA_H22[naNumber], forceField, bondList);
459 } else {
460 buildH(residue, "H2'", sugarC2, 1.09e0, sugarC3, 109.5e0, sugarC1, 109.5e0, -1,
461 NA_H21[naNumber], forceField, bondList);
462
463
464 if (nucleicAcid == NucleicAcid3.OMC || nucleicAcid == NucleicAcid3.OMG) {
465 Atom CM2 = buildHeavy(residue, "CM2", sugarO2, 1427, forceField, bondList);
466 Atom HM21 = buildH(residue, "HM21", CM2, 1.08e0, sugarO2, 109.5e0, sugarC2, 0.0e0, 0,
467 1428, forceField, bondList);
468 buildH(residue, "HM22", CM2, 1.08e0, sugarO2, 109.5e0, HM21, 109.5e0, 1, 1429,
469 forceField, bondList);
470 buildH(residue, "HM23", CM2, 1.08e0, sugarO2, 109.5e0, HM21, 109.5e0, -1, 1430,
471 forceField, bondList);
472 } else {
473 buildH(residue, "HO2'", sugarO2, 1.00e0, sugarC2, 109.5e0, sugarC3, 180.0e0, 0,
474 NA_H22[naNumber], forceField, bondList);
475 }
476 }
477 buildH(residue, "H1'", sugarC1, 1.09e0, sugarO4, 109.5e0, sugarC2, 109.5e0, -1,
478 NA_H1[naNumber], forceField, bondList);
479 if (position == LAST_RESIDUE || numberOfResidues == 1) {
480 buildH(residue, "HO3'", sugarO3, 1.00e0, sugarC3, 109.5e0, sugarC4, 180.0e0, 0,
481 NA_HO3T[naNumber], forceField, bondList);
482
483
484 }
485
486
487 assignNucleicAcidBaseAtomTypes(nucleicAcid, residue, sugarC1, sugarO4, sugarC2, forceField,
488 bondList);
489 }
490
491
492 resAtoms = residue.getAtomList();
493 for (Atom atom : resAtoms) {
494 AtomType atomType = atom.getAtomType();
495 if (atomType == null) {
496 throw new MissingAtomTypeException(residue, atom);
497 }
498 int numberOfBonds = atom.getNumBonds();
499 if (numberOfBonds != atomType.valence) {
500 if (atom == sugarO3 && numberOfBonds == atomType.valence - 1 && position != LAST_RESIDUE
501 && numberOfResidues != 1) {
502 continue;
503 }
504 logger.warning(
505 format(" An atom for residue %s has the wrong number of bonds:\n %s", residueName,
506 atom));
507 logger.info(format(" Expected: %d Actual: %d.", atomType.valence, numberOfBonds));
508 for (Bond bond : atom.getBonds()) {
509 logger.info(" " + bond.toString());
510 }
511 }
512 }
513
514
515 pSugarO3 = sugarO3;
516 }
517 }
518
519 private static boolean isThreePrimeCap(int nAtoms, List<Atom> resAtoms) {
520 boolean threePrimeCap = false;
521 if (nAtoms < 7) {
522 boolean unrecognized = false;
523 for (Atom atom : resAtoms) {
524 String atomName = atom.getName();
525
526 if (!(atomName.equals("P") || atomName.matches("[HD]?OP[1-3]") || atomName.matches(
527 "O5'"))) {
528 unrecognized = true;
529 break;
530 }
531 }
532 threePrimeCap = !unrecognized;
533 }
534 return threePrimeCap;
535 }
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550 private static void assignNucleicAcidBaseAtomTypes(NucleicAcid3 nucleicAcid, Residue residue,
551 Atom C1s, Atom O4s, Atom C2s, ForceField forceField, List<Bond> bondList)
552 throws MissingHeavyAtomException, MissingAtomTypeException {
553 double glyco = 0.0;
554
555
556 Atom o4p = residue.getAtomByName("O4'", true);
557 Atom c1p = residue.getAtomByName("C1'", true);
558 Atom baseN = null;
559 Atom baseC = null;
560 if (nucleicAcid == NucleicAcid3.DAD || nucleicAcid == NucleicAcid3.DGU) {
561 baseN = residue.getAtomByName("N9", true);
562 baseC = residue.getAtomByName("C4", true);
563 } else if (nucleicAcid == NucleicAcid3.DCY || nucleicAcid == NucleicAcid3.DTY) {
564 baseN = residue.getAtomByName("N1", true);
565 baseC = residue.getAtomByName("C2", true);
566 }
567
568 if (o4p != null && c1p != null && baseN != null && baseC != null) {
569 double angle = DoubleMath.dihedralAngle(o4p.getXYZ(null), c1p.getXYZ(null), baseN.getXYZ(null), baseC.getXYZ(null));
570 glyco = toDegrees(angle);
571 }
572
573 switch (nucleicAcid) {
574 case ADE -> buildADE(residue, C1s, O4s, C2s, glyco, forceField, bondList);
575 case M1MA -> buildM1MA(residue, C1s, forceField, bondList);
576 case CYT -> buildCYT(residue, C1s, O4s, C2s, glyco, forceField, bondList);
577 case OMC -> buildOMC(residue, C1s, O4s, C2s, glyco, forceField, bondList);
578 case M5MC -> buildM5MC(residue, C1s, forceField, bondList);
579 case GUA -> buildGUA(residue, C1s, O4s, C2s, glyco, forceField, bondList);
580 case OMG -> buildOMG(residue, C1s, O4s, C2s, glyco, forceField, bondList);
581 case YYG -> buildYYG(residue, C1s, forceField, bondList);
582 case M2MG -> buildM2MG(residue, C1s, forceField, bondList);
583 case M2G -> buildM2G(residue, C1s, forceField, bondList);
584 case M7MG -> buildM7MG(residue, C1s, forceField, bondList);
585 case URI -> buildURI(residue, C1s, O4s, C2s, glyco, forceField, bondList);
586 case PSU -> buildPSU(residue, C1s, forceField, bondList);
587 case H2U -> buildH2U(residue, C1s, forceField, bondList);
588 case M5MU -> buildM5MU(residue, C1s, forceField, bondList);
589 case DAD -> buildDAD(residue, C1s, O4s, C2s, glyco, forceField, bondList);
590 case DCY -> buildDCY(residue, C1s, O4s, C2s, glyco, forceField, bondList);
591 case DGU -> buildDGU(residue, C1s, O4s, C2s, glyco, forceField, bondList);
592 case DTY -> buildDTY(residue, C1s, O4s, C2s, glyco, forceField, bondList);
593 }
594 }
595
596
597
598
599
600
601
602
603
604
605
606
607
608 private static Residue buildADE(Residue residue, Atom C1s, Atom O4s, Atom C2s, double glyco,
609 ForceField forceField, List<Bond> bondList) {
610 Atom N9 = buildHeavy(residue, "N9", C1s, 1.48, O4s, 108.1, C2s, 113.7, 1, 1017, forceField,
611 bondList);
612 Atom C8 = buildHeavy(residue, "C8", N9, 1.37, C1s, 128.4, O4s, glyco + 180.0, 0, 1021,
613 forceField, bondList);
614 Atom N7 = buildHeavy(residue, "N7", C8, 1.30, N9, 113.8, C1s, 180.0, 0, 1020, forceField,
615 bondList);
616 Atom C5 = buildHeavy(residue, "C5", N7, 1.39, C8, 104.0, N9, 0.0, 0, 1019, forceField, bondList);
617 Atom C6 = buildHeavy(residue, "C6", C5, 1.40, N7, 132.4, C8, 180.0, 0, 1025, forceField,
618 bondList);
619 Atom N6 = buildHeavy(residue, "N6", C6, 1.34, C5, 123.5, N7, 0.0, 0, 1027, forceField, bondList);
620 Atom N1 = buildHeavy(residue, "N1", C6, 1.35, C5, 117.4, N7, 180.0, 0, 1024, forceField,
621 bondList);
622 Atom C2 = buildHeavy(residue, "C2", N1, 1.33, C6, 118.8, C5, 0.0, 0, 1023, forceField, bondList);
623 Atom N3 = buildHeavy(residue, "N3", C2, 1.32, N1, 129.2, C6, 0.0, 0, 1022, forceField, bondList);
624 Atom C4 = buildHeavy(residue, "C4", N3, 1.35, C2, 110.9, N1, 0.0, 0, 1018, forceField, bondList);
625 buildBond(C4, C5, forceField, bondList);
626 buildBond(C4, N9, forceField, bondList);
627 buildH(residue, "H8", C8, 1.08e0, N7, 123.1e0, C5, 180.0e0, 0, 1030, forceField, bondList);
628 buildH(residue, "H61", N6, 1.00e0, C6, 120.0e0, N7, 180.0e0, 0, 1028, forceField, bondList);
629 buildH(residue, "H62", N6, 1.00e0, C6, 120.0e0, N7, 0.0e0, 0, 1029, forceField, bondList);
630 buildH(residue, "H2", C2, 1.08e0, N3, 115.4e0, C4, 180.0e0, 0, 1026, forceField, bondList);
631 return residue;
632 }
633
634
635
636
637
638
639
640
641
642
643
644
645
646 private static Residue buildCYT(Residue residue, Atom C1s, Atom O4s, Atom C2s, double glyco,
647 ForceField forceField, List<Bond> bondList) {
648 Atom N1 = buildHeavy(residue, "N1", C1s, 1.48, O4s, 108.1, C2s, 113.7, 1, 1078, forceField,
649 bondList);
650 Atom C2 = buildHeavy(residue, "C2", N1, 1.37, C1s, 117.8, O4s, glyco + 180, 0, 1079, forceField,
651 bondList);
652 Atom O2 = buildHeavy(residue, "O2", C2, 1.24, N1, 118.9, C1s, 0.0, 0, 1084, forceField,
653 bondList);
654 Atom N3 = buildHeavy(residue, "N3", C2, 1.38, N1, 118.7, C1s, 180.0, 0, 1080, forceField,
655 bondList);
656 Atom C4 = buildHeavy(residue, "C4", N3, 1.34, C2, 120.6, N1, 0.0, 0, 1081, forceField, bondList);
657 Atom N4 = buildHeavy(residue, "N4", C4, 1.32, N3, 118.3, O2, 180.0, 0, 1085, forceField,
658 bondList);
659 Atom C5 = buildHeavy(residue, "C5", C4, 1.43, N3, 121.6, C2, 0.0, 0, 1082, forceField, bondList);
660 Atom C6 = buildHeavy(residue, "C6", C5, 1.36, C4, 116.9, N3, 0.0, 0, 1083, forceField, bondList);
661 buildBond(C6, N1, forceField, bondList);
662 buildH(residue, "H41", N4, 1.00e0, C4, 120.0e0, N3, 0.0e0, 0, 1086, forceField, bondList);
663 buildH(residue, "H42", N4, 1.00e0, C4, 120.0e0, N3, 180.0e0, 0, 1087, forceField, bondList);
664 buildH(residue, "H5", C5, 1.08e0, C4, 121.6e0, N3, 180.0e0, 0, 1088, forceField, bondList);
665 buildH(residue, "H6", C6, 1.08e0, C5, 119.4e0, C4, 180.0e0, 0, 1089, forceField, bondList);
666 return residue;
667 }
668
669
670
671
672
673
674
675
676
677
678
679
680
681 private static Residue buildDAD(Residue residue, Atom C1s, Atom O4s, Atom C2s, double glyco,
682 ForceField forceField, List<Bond> bondList) {
683
684 Atom N9 = buildHeavy(residue, "N9", C1s, 1.48, O4s, 108.1, C2s, 113.7, 1, 1132, forceField,
685 bondList);
686 Atom C8 = buildHeavy(residue, "C8", N9, 1.37, C1s, 128.4, O4s, glyco + 180, 0, 1136, forceField,
687 bondList);
688 Atom N7 = buildHeavy(residue, "N7", C8, 1.30, N9, 113.8, C1s, 180.0, 0, 1135, forceField,
689 bondList);
690 Atom C5 = buildHeavy(residue, "C5", N7, 1.39, C8, 104.0, N9, 0.0, 0, 1134, forceField, bondList);
691 Atom C6 = buildHeavy(residue, "C6", C5, 1.40, N7, 132.4, C8, 180.0, 0, 1140, forceField,
692 bondList);
693 Atom N6 = buildHeavy(residue, "N6", C6, 1.34, C5, 123.5, N7, 0.0, 0, 1142, forceField, bondList);
694 Atom N1 = buildHeavy(residue, "N1", C6, 1.35, C5, 117.4, N7, 180.0, 0, 1139, forceField,
695 bondList);
696 Atom C2 = buildHeavy(residue, "C2", N1, 1.33, C6, 118.8, C5, 0.0, 0, 1138, forceField, bondList);
697 Atom N3 = buildHeavy(residue, "N3", C2, 1.32, N1, 129.2, C6, 0.0, 0, 1137, forceField, bondList);
698 Atom C4 = buildHeavy(residue, "C4", N3, 1.35, C2, 110.9, N1, 0.0, 0, 1133, forceField, bondList);
699 buildBond(C4, C5, forceField, bondList);
700 buildBond(C4, N9, forceField, bondList);
701 buildH(residue, "H8", C8, 1.08e0, N7, 123.1e0, C5, 180.0e0, 0, 1145, forceField, bondList);
702 buildH(residue, "H61", N6, 1.00e0, C6, 120.0e0, N7, 180.0e0, 0, 1143, forceField, bondList);
703 buildH(residue, "H62", N6, 1.00e0, C6, 120.0e0, N7, 0.0e0, 0, 1144, forceField, bondList);
704 buildH(residue, "H2", C2, 1.08e0, N3, 115.4e0, C4, 180.0e0, 0, 1141, forceField, bondList);
705 return residue;
706 }
707
708
709
710
711
712
713
714
715
716
717
718
719
720 private static Residue buildDCY(Residue residue, Atom C1s, Atom O4s, Atom C2s, double glyco,
721 ForceField forceField, List<Bond> bondList) {
722
723 Atom N1 = buildHeavy(residue, "N1", C1s, 1.48, O4s, 108.1, C2s, 113.7, 1, 1191, forceField,
724 bondList);
725 Atom C2 = buildHeavy(residue, "C2", N1, 1.37, C1s, 117.8, O4s, glyco, 0, 1192, forceField,
726 bondList);
727 Atom O2 = buildHeavy(residue, "O2", C2, 1.24, N1, 118.9, C1s, 0.0, 0, 1197, forceField,
728 bondList);
729 Atom N3 = buildHeavy(residue, "N3", C2, 1.38, N1, 118.7, C1s, 180, 0, 1193, forceField,
730 bondList);
731 Atom C4 = buildHeavy(residue, "C4", N3, 1.34, C2, 120.6, N1, 0.0, 0, 1194, forceField, bondList);
732 Atom N4 = buildHeavy(residue, "N4", C4, 1.32, N3, 118.3, C2, 180.0, 0, 1198, forceField,
733 bondList);
734 Atom C5 = buildHeavy(residue, "C5", C4, 1.43, N3, 121.6, C2, 0.0, 0, 1195, forceField, bondList);
735 Atom C6 = buildHeavy(residue, "C6", C5, 1.36, C4, 116.9, N3, 0.0, 0, 1196, forceField, bondList);
736 buildBond(C6, N1, forceField, bondList);
737 buildH(residue, "H41", N4, 1.00e0, C4, 120.0e0, N3, 0.0e0, 0, 1199, forceField, bondList);
738 buildH(residue, "H42", N4, 1.00e0, C4, 120.0e0, N3, 180.0e0, 0, 1200, forceField, bondList);
739 buildH(residue, "H5", C5, 1.08e0, C4, 121.6e0, N3, 180.0e0, 0, 1201, forceField, bondList);
740 buildH(residue, "H6", C6, 1.08e0, C5, 119.4e0, C4, 180.0e0, 0, 1202, forceField, bondList);
741 return residue;
742 }
743
744
745
746
747
748
749
750
751
752
753
754
755
756 private static Residue buildDGU(Residue residue, Atom C1s, Atom O4s, Atom C2s, double glyco,
757 ForceField forceField, List<Bond> bondList) {
758
759 Atom N9 = buildHeavy(residue, "N9", C1s, 1.48, O4s, 108.1, C2s, 113.7, 1, 1161, forceField,
760 bondList);
761 Atom C8 = buildHeavy(residue, "C8", N9, 1.38, C1s, 128.4, O4s, glyco + 180, 0, 1165, forceField,
762 bondList);
763 Atom N7 = buildHeavy(residue, "N7", C8, 1.31, N9, 114.0, C1s, 180.0, 0, 1164, forceField,
764 bondList);
765 Atom C5 = buildHeavy(residue, "C5", N7, 1.39, C8, 103.8, N9, 0.0, 0, 1163, forceField, bondList);
766 Atom C6 = buildHeavy(residue, "C6", C5, 1.40, N7, 130.1, C8, 180.0, 0, 1169, forceField,
767 bondList);
768 Atom O6 = buildHeavy(residue, "O6", C6, 1.23, C5, 128.8, N7, 0.0, 0, 1174, forceField, bondList);
769 Atom N1 = buildHeavy(residue, "N1", C6, 1.40, C5, 111.4, N7, 180.0, 0, 1168, forceField,
770 bondList);
771 Atom C2 = buildHeavy(residue, "C2", N1, 1.38, C6, 125.2, C5, 0.0, 0, 1167, forceField, bondList);
772 Atom N2 = buildHeavy(residue, "N2", C2, 1.34, N1, 116.1, C6, 180.0, 0, 1171, forceField,
773 bondList);
774 Atom N3 = buildHeavy(residue, "N3", C2, 1.33, N1, 123.3, O6, 0.0, 0, 1166, forceField, bondList);
775 Atom C4 = buildHeavy(residue, "C4", N3, 1.36, C2, 112.3, N1, 0.0, 0, 1162, forceField, bondList);
776 buildBond(C4, C5, forceField, bondList);
777 buildBond(C4, N9, forceField, bondList);
778 buildH(residue, "H8", C8, 1.08e0, N7, 123.0e0, C5, 180.0e0, 0, 1175, forceField, bondList);
779 buildH(residue, "H1", N1, 1.00e0, C6, 117.4e0, C5, 180.0e0, 0, 1170, forceField, bondList);
780 buildH(residue, "H21", N2, 1.00e0, C2, 120.0e0, N1, 0.0e0, 0, 1172, forceField, bondList);
781 buildH(residue, "H22", N2, 1.00e0, C2, 120.0e0, N1, 180.0e0, 0, 1173, forceField, bondList);
782 return residue;
783 }
784
785
786
787
788
789
790
791
792
793
794
795
796
797 private static Residue buildDTY(Residue residue, Atom C1s, Atom O4s, Atom C2s, double glyco,
798 ForceField forceField, List<Bond> bondList) {
799 Atom N1 = buildHeavy(residue, "N1", C1s, 1.48, O4s, 108.1, C2s, 113.7, 1, 1218, forceField,
800 bondList);
801 Atom C2 = buildHeavy(residue, "C2", N1, 1.37, C1s, 117.1, O4s, glyco, 0, 1219, forceField,
802 bondList);
803 Atom O2 = buildHeavy(residue, "O2", C2, 1.22, N1, 122.9, C1s, 0.0, 0, 1224, forceField,
804 bondList);
805 Atom N3 = buildHeavy(residue, "N3", C2, 1.38, N1, 115.4, C1s, 180.0, 0, 1220, forceField,
806 bondList);
807 Atom C4 = buildHeavy(residue, "C4", N3, 1.38, C2, 126.4, N1, 0.0, 0, 1221, forceField, bondList);
808 Atom O4 = buildHeavy(residue, "O4", C4, 1.23, N3, 120.5, C2, 180.0, 0, 1226, forceField,
809 bondList);
810 Atom C5 = buildHeavy(residue, "C5", C4, 1.44, N3, 114.1, C2, 0.0, 0, 1222, forceField, bondList);
811 Atom C7 = buildHeavy(residue, "C7", C5, 1.50, C4, 117.5, N3, 180.0, 0, 1227, forceField,
812 bondList);
813 Atom C6 = buildHeavy(residue, "C6", C5, 1.34, C4, 120.8, N3, 0.0, 0, 1223, forceField, bondList);
814 buildBond(C6, N1, forceField, bondList);
815 buildH(residue, "H3", N3, 1.00e0, C2, 116.8e0, N1, 180.0e0, 0, 1225, forceField, bondList);
816 Atom H = buildH(residue, "H71", C7, 1.09e0, C5, 109.5e0, C4, 0.0e0, 0, 1228, forceField,
817 bondList);
818 buildH(residue, "H72", C7, 1.09e0, C5, 109.5e0, H, 109.5e0, 1, 1228, forceField, bondList);
819 buildH(residue, "H73", C7, 1.09e0, C5, 109.5e0, H, 109.5e0, -1, 1228, forceField, bondList);
820 buildH(residue, "H6", C6, 1.08e0, C5, 119.4e0, C4, 180.0e0, 0, 1229, forceField, bondList);
821 return residue;
822 }
823
824
825
826
827
828
829
830
831
832
833
834
835
836 private static Residue buildGUA(Residue residue, Atom C1s, Atom O4s, Atom C2s, double glyco,
837 ForceField forceField, List<Bond> bondList) {
838 Atom N9 = buildHeavy(residue, "N9", C1s, 1.48, O4s, 108.1, C2s, 113.7, 1, 1047, forceField,
839 bondList);
840 Atom C8 = buildHeavy(residue, "C8", N9, 1.38, C1s, 128.4, O4s, glyco + 180, 0, 1051, forceField,
841 bondList);
842 Atom N7 = buildHeavy(residue, "N7", C8, 1.31, N9, 114.0, C1s, 180.0, 0, 1050, forceField,
843 bondList);
844 Atom C5 = buildHeavy(residue, "C5", N7, 1.39, C8, 103.8, N9, 0.0, 0, 1049, forceField, bondList);
845 Atom C6 = buildHeavy(residue, "C6", C5, 1.40, N7, 130.1, C8, 180.0, 0, 1055, forceField,
846 bondList);
847 Atom O6 = buildHeavy(residue, "O6", C6, 1.23, C5, 128.8, N7, 0.0, 0, 1060, forceField, bondList);
848 Atom N1 = buildHeavy(residue, "N1", C6, 1.40, C5, 111.4, N7, 180.0, 0, 1054, forceField,
849 bondList);
850 Atom C2 = buildHeavy(residue, "C2", N1, 1.38, C6, 125.2, C5, 0.0, 0, 1053, forceField, bondList);
851 Atom N2 = buildHeavy(residue, "N2", C2, 1.34, N1, 116.1, C6, 180.0, 0, 1057, forceField,
852 bondList);
853 Atom N3 = buildHeavy(residue, "N3", C2, 1.33, N1, 123.3, O6, 0.0, 0, 1052, forceField, bondList);
854 Atom C4 = buildHeavy(residue, "C4", N3, 1.36, C2, 112.3, N1, 0.0, 0, 1048, forceField, bondList);
855 buildBond(C4, C5, forceField, bondList);
856 buildBond(C4, N9, forceField, bondList);
857 buildH(residue, "H8", C8, 1.08e0, N7, 123.0e0, C5, 180.0e0, 0, 1061, forceField, bondList);
858 buildH(residue, "H1", N1, 1.00e0, C6, 117.4e0, C5, 180.0e0, 0, 1056, forceField, bondList);
859 buildH(residue, "H21", N2, 1.00e0, C2, 120.0e0, N1, 0.0e0, 0, 1058, forceField, bondList);
860 buildH(residue, "H22", N2, 1.00e0, C2, 120.0e0, N1, 180.0e0, 0, 1059, forceField, bondList);
861 return residue;
862 }
863
864
865
866
867
868
869
870
871
872
873
874 private static Residue buildH2U(Residue residue, Atom C1s, ForceField forceField,
875 List<Bond> bondList) throws MissingHeavyAtomException, MissingAtomTypeException {
876
877 Atom N1 = buildHeavy(residue, "N1", C1s, 1350, forceField, bondList);
878 Atom C2 = buildHeavy(residue, "C2", N1, 1351, forceField, bondList);
879 Atom O2 = buildHeavy(residue, "O2", C2, 1356, forceField, bondList);
880 Atom N3 = buildHeavy(residue, "N3", C2, 1352, forceField, bondList);
881 Atom C4 = buildHeavy(residue, "C4", N3, 1353, forceField, bondList);
882 Atom O4 = buildHeavy(residue, "O4", C4, 1358, forceField, bondList);
883 Atom C5 = buildHeavy(residue, "C5", C4, 1354, forceField, bondList);
884 Atom C6 = buildHeavy(residue, "C6", C5, 1355, forceField, bondList);
885 buildBond(C6, N1, forceField, bondList);
886 buildH(residue, "H3", N3, 1.00e0, C2, 116.5e0, N1, 180.0e0, 0, 1357, forceField, bondList);
887 buildH(residue, "H51", C5, 1.08e0, C4, 109.5e0, C6, 109.5e0, 1, 1359, forceField, bondList);
888 buildH(residue, "H52", C5, 1.08e0, C4, 109.5e0, C6, 109.5e0, -1, 1360, forceField, bondList);
889 buildH(residue, "H61", C6, 1.08e0, C5, 109.5e0, N1, 109.5e0, 1, 1361, forceField, bondList);
890 buildH(residue, "H62", C6, 1.08e0, C5, 109.5e0, N1, 109.5e0, -1, 1362, forceField, bondList);
891 return residue;
892 }
893
894
895
896
897
898
899
900
901
902
903
904 private static Residue buildM1MA(Residue residue, Atom C1s, ForceField forceField,
905 List<Bond> bondList) throws MissingHeavyAtomException, MissingAtomTypeException {
906 Atom N9 = buildHeavy(residue, "N9", C1s, 1605, forceField, bondList);
907 Atom C8 = buildHeavy(residue, "C8", N9, 1609, forceField, bondList);
908 Atom N7 = buildHeavy(residue, "N7", C8, 1608, forceField, bondList);
909 Atom C5 = buildHeavy(residue, "C5", N7, 1607, forceField, bondList);
910 Atom C6 = buildHeavy(residue, "C6", C5, 1613, forceField, bondList);
911 Atom N6 = buildHeavy(residue, "N6", C6, 1615, forceField, bondList);
912 Atom N1 = buildHeavy(residue, "N1", C6, 1612, forceField, bondList);
913 Atom C2 = buildHeavy(residue, "C2", N1, 1611, forceField, bondList);
914 Atom N3 = buildHeavy(residue, "N3", C2, 1610, forceField, bondList);
915 Atom C4 = buildHeavy(residue, "C4", N3, 1606, forceField, bondList);
916 Atom CM1 = buildHeavy(residue, "CM1", N1, 1619, forceField, bondList);
917 buildBond(C4, C5, forceField, bondList);
918 buildBond(C4, N9, forceField, bondList);
919 buildH(residue, "H2", C2, 1.08e0, N3, 115.4e0, C4, 180.0e0, 0, 1614, forceField, bondList);
920 buildH(residue, "H6", C6, 1.08e0, C5, 109.5e0, C4, 180.0e0, 0, 1623, forceField, bondList);
921 buildH(residue, "H8", C8, 1.08e0, N7, 123.1e0, C5, 180.0e0, 0, 1618, forceField, bondList);
922 buildH(residue, "HN61", N6, 1.00e0, C6, 109.5e0, C5, 0.0e0, 0, 1616, forceField, bondList);
923 buildH(residue, "HN62", N6, 1.00e0, C6, 109.5e0, C5, 109.5e0, 0, 1617, forceField, bondList);
924 Atom HM11 = buildH(residue, "HM11", CM1, 1.08e0, N1, 109.5e0, C2, 0.0e0, 0, 1620, forceField,
925 bondList);
926 buildH(residue, "HM12", CM1, 1.08e0, N1, 109.5e0, HM11, 109.5e0, 1, 1621, forceField, bondList);
927 buildH(residue, "HM13", CM1, 1.08e0, N1, 109.5e0, HM11, 109.5e0, -1, 1622, forceField, bondList);
928 return residue;
929 }
930
931
932
933
934
935
936
937
938
939
940
941 private static Residue buildM2G(Residue residue, Atom C1s, ForceField forceField,
942 List<Bond> bondList) throws MissingHeavyAtomException, MissingAtomTypeException {
943 Atom N9 = buildHeavy(residue, "N9", C1s, 1379, forceField, bondList);
944 Atom C8 = buildHeavy(residue, "C8", N9, 1383, forceField, bondList);
945 Atom N7 = buildHeavy(residue, "N7", C8, 1382, forceField, bondList);
946 Atom C5 = buildHeavy(residue, "C5", N7, 1381, forceField, bondList);
947 Atom C6 = buildHeavy(residue, "C6", C5, 1387, forceField, bondList);
948 Atom O6 = buildHeavy(residue, "O6", C6, 1390, forceField, bondList);
949 Atom N1 = buildHeavy(residue, "N1", C6, 1386, forceField, bondList);
950 Atom C2 = buildHeavy(residue, "C2", N1, 1385, forceField, bondList);
951 Atom N2 = buildHeavy(residue, "N2", C2, 1389, forceField, bondList);
952 Atom N3 = buildHeavy(residue, "N3", C2, 1384, forceField, bondList);
953 Atom C4 = buildHeavy(residue, "C4", N3, 1380, forceField, bondList);
954 Atom CM1 = buildHeavy(residue, "CM1", N2, 1392, forceField, bondList);
955 Atom CM2 = buildHeavy(residue, "CM2", N2, 1396, forceField, bondList);
956 buildBond(C4, C5, forceField, bondList);
957 buildBond(C4, N9, forceField, bondList);
958 buildH(residue, "H8", C8, 1.08e0, N7, 123.0e0, C5, 180.0e0, 0, 1391, forceField, bondList);
959 buildH(residue, "H1", N1, 1.00e0, C6, 117.4e0, C5, 180.0e0, 0, 1388, forceField, bondList);
960 Atom HM11 = buildH(residue, "HM11", CM1, 1.08e0, N2, 109.5e0, C2, 0.0e0, 0, 1393, forceField,
961 bondList);
962 buildH(residue, "HM12", CM1, 1.08e0, N2, 109.5e0, HM11, 109.5e0, 1, 1394, forceField, bondList);
963 buildH(residue, "HM13", CM1, 1.08e0, N2, 109.5e0, HM11, 109.5e0, -1, 1395, forceField, bondList);
964 Atom HM21 = buildH(residue, "HM21", CM2, 1.08e0, N2, 109.5e0, C2, 0.0e0, 0, 1397, forceField,
965 bondList);
966 buildH(residue, "HM22", CM2, 1.08e0, N2, 109.5e0, HM21, 109.5e0, 1, 1398, forceField, bondList);
967 buildH(residue, "HM23", CM2, 1.08e0, N2, 109.5e0, HM21, 109.5e0, -1, 1399, forceField, bondList);
968 return residue;
969 }
970
971
972
973
974
975
976
977
978
979
980
981 private static Residue buildM2MG(Residue residue, Atom C1s, ForceField forceField,
982 List<Bond> bondList) throws MissingHeavyAtomException, MissingAtomTypeException {
983 Atom N9 = buildHeavy(residue, "N9", C1s, 1316, forceField, bondList);
984 Atom C8 = buildHeavy(residue, "C8", N9, 1320, forceField, bondList);
985 Atom N7 = buildHeavy(residue, "N7", C8, 1319, forceField, bondList);
986 Atom C5 = buildHeavy(residue, "C5", N7, 1318, forceField, bondList);
987 Atom C6 = buildHeavy(residue, "C6", C5, 1324, forceField, bondList);
988 Atom O6 = buildHeavy(residue, "O6", C6, 1328, forceField, bondList);
989 Atom N1 = buildHeavy(residue, "N1", C6, 1323, forceField, bondList);
990 Atom C2 = buildHeavy(residue, "C2", N1, 1322, forceField, bondList);
991 Atom N2 = buildHeavy(residue, "N2", C2, 1326, forceField, bondList);
992 Atom N3 = buildHeavy(residue, "N3", C2, 1321, forceField, bondList);
993 Atom C4 = buildHeavy(residue, "C4", N3, 1317, forceField, bondList);
994 Atom CM2 = buildHeavy(residue, "CM2", N2, 1330, forceField, bondList);
995 buildBond(C4, C5, forceField, bondList);
996 buildBond(C4, N9, forceField, bondList);
997 buildH(residue, "H8", C8, 1.08e0, N7, 123.0e0, C5, 180.0e0, 0, 1329, forceField, bondList);
998 buildH(residue, "H1", N1, 1.00e0, C6, 117.4e0, C5, 180.0e0, 0, 1325, forceField, bondList);
999 buildH(residue, "H2", N2, 1.00e0, C2, 120.0e0, N1, 0.0e0, 0, 1327, forceField, bondList);
1000 Atom HM21 = buildH(residue, "HM21", CM2, 1.08e0, N2, 109.5e0, C2, 0.0e0, 0, 1331, forceField,
1001 bondList);
1002 buildH(residue, "HM22", CM2, 1.08e0, N2, 109.5e0, HM21, 109.5e0, 1, 1332, forceField, bondList);
1003 buildH(residue, "HM23", CM2, 1.08e0, N2, 109.5e0, HM21, 109.5e0, -1, 1333, forceField, bondList);
1004 return residue;
1005 }
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017 private static Residue buildM5MC(Residue residue, Atom C1s, ForceField forceField,
1018 List<Bond> bondList) throws MissingHeavyAtomException, MissingAtomTypeException {
1019 Atom N1 = buildHeavy(residue, "N1", C1s, 1508, forceField, bondList);
1020 Atom C2 = buildHeavy(residue, "C2", N1, 1509, forceField, bondList);
1021 Atom O2 = buildHeavy(residue, "O2", C2, 1514, forceField, bondList);
1022 Atom N3 = buildHeavy(residue, "N3", C2, 1510, forceField, bondList);
1023 Atom C4 = buildHeavy(residue, "C4", N3, 1511, forceField, bondList);
1024 Atom N4 = buildHeavy(residue, "N4", C4, 1515, forceField, bondList);
1025 Atom C5 = buildHeavy(residue, "C5", C4, 1512, forceField, bondList);
1026 Atom C6 = buildHeavy(residue, "C6", C5, 1513, forceField, bondList);
1027 Atom CM5 = buildHeavy(residue, "CM5", C5, 1519, forceField, bondList);
1028 buildBond(C6, N1, forceField, bondList);
1029 buildH(residue, "H41", N4, 1.00e0, C4, 120.0e0, N3, 0.0e0, 0, 1516, forceField, bondList);
1030 buildH(residue, "H42", N4, 1.00e0, C4, 120.0e0, C5, 0.0e0, 0, 1517, forceField, bondList);
1031 buildH(residue, "H6", C6, 1.08e0, C5, 119.4e0, C4, 180.0e0, 0, 1518, forceField, bondList);
1032 Atom HM51 = buildH(residue, "HM51", CM5, 1.08e0, C5, 109.5e0, C4, 0.0e0, 0, 1520, forceField,
1033 bondList);
1034 buildH(residue, "HM52", CM5, 1.08e0, C5, 109.5e0, HM51, 109.5e0, 1, 1521, forceField, bondList);
1035 buildH(residue, "HM53", CM5, 1.08e0, C5, 109.5e0, HM51, 109.5e0, -1, 1522, forceField, bondList);
1036 return residue;
1037 }
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049 private static Residue buildM5MU(Residue residue, Atom C1s, ForceField forceField,
1050 List<Bond> bondList) throws MissingHeavyAtomException, MissingAtomTypeException {
1051
1052 Atom N1 = buildHeavy(residue, "N1", C1s, 1575, forceField, bondList);
1053 Atom C2 = buildHeavy(residue, "C2", N1, 1576, forceField, bondList);
1054 Atom O2 = buildHeavy(residue, "O2", C2, 1581, forceField, bondList);
1055 Atom N3 = buildHeavy(residue, "N3", C2, 1577, forceField, bondList);
1056 Atom C4 = buildHeavy(residue, "C4", N3, 1578, forceField, bondList);
1057 Atom O4 = buildHeavy(residue, "O4", C4, 1583, forceField, bondList);
1058 Atom C5 = buildHeavy(residue, "C5", C4, 1579, forceField, bondList);
1059 Atom C6 = buildHeavy(residue, "C6", C5, 1580, forceField, bondList);
1060 Atom C5M = buildHeavy(residue, "C5M", C5, 1585, forceField, bondList);
1061 buildBond(C6, N1, forceField, bondList);
1062 buildH(residue, "H3", N3, 1.00e0, C2, 116.5e0, N1, 180.0e0, 0, 1582, forceField, bondList);
1063 buildH(residue, "H6", C6, 1.08e0, C5, 118.6e0, C4, 180.0e0, 0, 1584, forceField, bondList);
1064 Atom H5M1 = buildH(residue, "H5M1", C5M, 1.08e0, C5, 109.5e0, C6, 0.0e0, 0, 1586, forceField,
1065 bondList);
1066 buildH(residue, "H5M2", C5M, 1.08e0, C5, 109.5e0, H5M1, 109.5e0, 1, 1587, forceField, bondList);
1067 buildH(residue, "H5M3", C5M, 1.08e0, C5, 109.5e0, H5M1, 109.5e0, -1, 1588, forceField, bondList);
1068 return residue;
1069 }
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081 private static Residue buildM7MG(Residue residue, Atom C1s, ForceField forceField,
1082 List<Bond> bondList) throws MissingHeavyAtomException, MissingAtomTypeException {
1083 Atom N9 = buildHeavy(residue, "N9", C1s, 1539, forceField, bondList);
1084 Atom C8 = buildHeavy(residue, "C8", N9, 1543, forceField, bondList);
1085 Atom N7 = buildHeavy(residue, "N7", C8, 1542, forceField, bondList);
1086 Atom C5 = buildHeavy(residue, "C5", N7, 1541, forceField, bondList);
1087 Atom C6 = buildHeavy(residue, "C6", C5, 1547, forceField, bondList);
1088 Atom O6 = buildHeavy(residue, "O6", C6, 1552, forceField, bondList);
1089 Atom N1 = buildHeavy(residue, "N1", C6, 1546, forceField, bondList);
1090 Atom C2 = buildHeavy(residue, "C2", N1, 1545, forceField, bondList);
1091 Atom N2 = buildHeavy(residue, "N2", C2, 1549, forceField, bondList);
1092 Atom N3 = buildHeavy(residue, "N3", C2, 1544, forceField, bondList);
1093 Atom C4 = buildHeavy(residue, "C4", N3, 1540, forceField, bondList);
1094 Atom CM7 = buildHeavy(residue, "CM7", N7, 1555, forceField, bondList);
1095 buildBond(C4, C5, forceField, bondList);
1096 buildBond(C4, N9, forceField, bondList);
1097 buildH(residue, "H81", C8, 1.08e0, N7, 109.5e0, N9, 109.5e0, 1, 1553, forceField, bondList);
1098 buildH(residue, "H82", C8, 1.08e0, N7, 109.5e0, N9, 109.5e0, -1, 1554, forceField, bondList);
1099 buildH(residue, "H1", N1, 1.00e0, C6, 117.4e0, C5, 180.0e0, 0, 1548, forceField, bondList);
1100 buildH(residue, "H21", N2, 1.00e0, C2, 120.0e0, N1, 0.0e0, 0, 1550, forceField, bondList);
1101 buildH(residue, "H22", N2, 1.00e0, C2, 120.0e0, N3, 0.0e0, 0, 1551, forceField, bondList);
1102 Atom HM71 = buildH(residue, "HM71", CM7, 1.08e0, N7, 109.5e0, C8, 0.0e0, 0, 1556, forceField,
1103 bondList);
1104 buildH(residue, "HM72", CM7, 1.08e0, N7, 109.5e0, HM71, 109.5e0, 1, 1557, forceField, bondList);
1105 buildH(residue, "HM73", CM7, 1.08e0, N7, 109.5e0, HM71, 109.5e0, -1, 1558, forceField, bondList);
1106 return residue;
1107 }
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121 private static Residue buildOMC(Residue residue, Atom C1s, Atom O4s, Atom C2s, double glyco,
1122 ForceField forceField, List<Bond> bondList) {
1123 return buildCYT(residue, C1s, O4s, C2s, glyco, forceField, bondList);
1124 }
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138 private static Residue buildOMG(Residue residue, Atom C1s, Atom O4s, Atom C2s, double glyco,
1139 ForceField forceField, List<Bond> bondList) {
1140 return buildGUA(residue, C1s, O4s, C2s, glyco, forceField, bondList);
1141 }
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155 private static void buildOP3(Residue residue, Atom phosphate, int aType, ForceField forceField,
1156 List<Bond> bondList, Residue adjacentResidue, boolean at5prime)
1157 throws MissingHeavyAtomException, MissingAtomTypeException {
1158 Atom P = null;
1159 Atom OP1 = null;
1160 Atom OP2 = null;
1161 Atom riboOxygen = null;
1162 Atom riboCarbon = null;
1163 boolean foundOP3 = false;
1164
1165 List<Atom> residueAtoms = residue.getAtomList();
1166
1167 AtomLoop:
1168 for (Atom at : residueAtoms) {
1169 String atName = at.getName().toUpperCase();
1170 switch (atName) {
1171 case "OP3":
1172 buildHeavy(residue, "OP3", phosphate, aType, forceField, bondList);
1173 foundOP3 = true;
1174 break AtomLoop;
1175 case "OP1":
1176 OP1 = at;
1177 break;
1178 case "OP2":
1179 OP2 = at;
1180 break;
1181 case "P":
1182 P = at;
1183 break;
1184 case "O5'":
1185 riboOxygen = at;
1186 break;
1187 case "C5'":
1188 riboCarbon = at;
1189 break;
1190 }
1191 }
1192
1193 if (!at5prime) {
1194 riboOxygen = (Atom) adjacentResidue.getAtomNode("O3'");
1195 riboCarbon = (Atom) adjacentResidue.getAtomNode("C3'");
1196 if (riboCarbon == null || riboOxygen == null) {
1197 logger.severe(format(
1198 " Could not find either O3' " + "or C3' in residue %s prior to presumed 3' "
1199 + "phosphate cap %s", adjacentResidue, residue));
1200 }
1201 }
1202
1203 if (!foundOP3) {
1204 logger.fine(
1205 format(" EXPERIMENTAL: OP3 of residue %s not found, being rebuilt based on ideal geometry",
1206 residue));
1207 if (P == null || OP1 == null || OP2 == null) {
1208 throw new IllegalArgumentException(format(
1209 " Attempted to build OP3 for residue %s, but one of P, OP1, OP2, O5', or C5' were null",
1210 residue));
1211 }
1212 if (at5prime) {
1213 if (riboOxygen == null) {
1214 logger.fine(" Attempting to find O5' of subsequent residue");
1215 riboOxygen = getNextResAtom(residue, adjacentResidue, "O5'");
1216 }
1217 if (riboCarbon == null) {
1218 logger.fine(" Attempting to find C5' of subsequent residue");
1219 riboCarbon = getNextResAtom(residue, adjacentResidue, "C5'");
1220 }
1221 }
1222
1223
1224 double[] xyzOP1 = new double[3];
1225 double[] xyzP = new double[3];
1226 xyzOP1 = OP1.getXYZ(xyzOP1);
1227 xyzP = P.getXYZ(xyzP);
1228 double distance = dist(xyzP, xyzOP1);
1229
1230
1231 double[] xyzRiboO = new double[3];
1232 xyzRiboO = riboOxygen.getXYZ(xyzRiboO);
1233 double angle = toDegrees(DoubleMath.bondAngle(xyzRiboO, xyzP, xyzOP1));
1234
1235
1236 double[] xyzRiboC = new double[3];
1237 xyzRiboC = riboCarbon.getXYZ(xyzRiboC);
1238 double dihedralOP1 = toDegrees(DoubleMath.dihedralAngle(xyzRiboC, xyzRiboO, xyzP, xyzOP1));
1239
1240 Atom OP3 = buildH(residue, "OP3", P, distance, riboOxygen, angle, riboCarbon,
1241 dihedralOP1 + 120, 0, aType, forceField, bondList);
1242
1243
1244 double[] xyzOP2 = new double[3];
1245 xyzOP2 = OP2.getXYZ(xyzOP2);
1246 double[] xyzChiral1 = new double[3];
1247 xyzChiral1 = OP3.getXYZ(xyzChiral1);
1248 double distChiral1 = dist(xyzChiral1, xyzOP2);
1249
1250
1251 intxyz(OP3, P, distance, riboOxygen, angle, riboCarbon, dihedralOP1 + 240, 0);
1252 double[] xyzChiral2 = new double[3];
1253 xyzChiral2 = OP3.getXYZ(xyzChiral2);
1254 double distChiral2 = dist(xyzChiral2, xyzOP2);
1255
1256 if (logger.isLoggable(Level.FINE)) {
1257 logger.fine(
1258 format(" Bond: %10.5f Angle: %10.5f Dihedral: %10.5f", distance, angle, dihedralOP1));
1259 logger.fine(format(" OP2 position: %s", Arrays.toString(xyzOP2)));
1260 logger.fine(format(" Position 1: %10.6g %10.6g %10.6g with distance %10.6g", xyzChiral1[0],
1261 xyzChiral1[1], xyzChiral1[2], distChiral1));
1262 logger.fine(format(" Position 2: %10.6g %10.6g %10.6g with distance %10.6g", xyzChiral2[0],
1263 xyzChiral2[1], xyzChiral2[2], distChiral2));
1264 }
1265 if (distChiral1 > distChiral2) {
1266 logger.fine(" Picked dihedral +120");
1267 OP3.setXYZ(xyzChiral1);
1268 } else {
1269 logger.fine(" Picked dihedral +240");
1270 OP3.setXYZ(xyzChiral2);
1271 }
1272 }
1273 }
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285 private static Residue buildPSU(Residue residue, Atom C1s, ForceField forceField,
1286 List<Bond> bondList) throws MissingHeavyAtomException, MissingAtomTypeException {
1287
1288 Atom C5 = buildHeavy(residue, "C5", C1s, 1485, forceField, bondList);
1289 Atom C6 = buildHeavy(residue, "C6", C5, 1486, forceField, bondList);
1290 Atom N1 = buildHeavy(residue, "N1", C6, 1481, forceField, bondList);
1291 Atom C2 = buildHeavy(residue, "C2", N1, 1482, forceField, bondList);
1292 Atom O2 = buildHeavy(residue, "O2", C2, 1487, forceField, bondList);
1293 Atom N3 = buildHeavy(residue, "N3", C2, 1483, forceField, bondList);
1294 Atom C4 = buildHeavy(residue, "C4", N3, 1484, forceField, bondList);
1295 Atom O4 = buildHeavy(residue, "O4", C4, 1489, forceField, bondList);
1296 buildBond(C4, C5, forceField, bondList);
1297 buildH(residue, "H1", N1, 1.00e0, C2, 120.0e0, O2, 0.0e0, 0, 1491, forceField, bondList);
1298 buildH(residue, "H3", N3, 1.00e0, C2, 120.0e0, O2, 0.0e0, 0, 1488, forceField, bondList);
1299 buildH(residue, "H6", C6, 1.08e0, C5, 120.0e0, C1s, 0.0e0, 0, 1490, forceField, bondList);
1300 return residue;
1301 }
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311 private static Atom buildSugarO5(Residue residue, int lookUp, ForceField forceField) {
1312 Atom C5 = residue.getAtomByName("C5'", true);
1313 Atom C4 = residue.getAtomByName("C4'", true);
1314 Atom C3 = residue.getAtomByName("C3'", true);
1315 return buildHeavy(residue, "O5'", C5, 1.43, C4, 109.5, C3, 180.0, 0, 1244, forceField);
1316 }
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330 private static Residue buildURI(Residue residue, Atom C1s, Atom O4s, Atom C2s, double glyco,
1331 ForceField forceField, List<Bond> bondList) {
1332 Atom N1 = buildHeavy(residue, "N1", C1s, 1.48, O4s, 108.1, C2s, 113.7, 1, 1106, forceField,
1333 bondList);
1334 Atom C2 = buildHeavy(residue, "C2", N1, 1.38, C1s, 117.1, O4s, glyco, 0, 1107, forceField,
1335 bondList);
1336 Atom O2 = buildHeavy(residue, "O2", C2, 1.22, N1, 123.2, C1s, 0.0, 0, 1112, forceField,
1337 bondList);
1338 Atom N3 = buildHeavy(residue, "N3", C2, 1.37, N1, 114.8, C1s, 180.0, 0, 1108, forceField,
1339 bondList);
1340 Atom C4 = buildHeavy(residue, "C4", N3, 1.38, C2, 127.0, N1, 0.0, 0, 1109, forceField, bondList);
1341 Atom O4 = buildHeavy(residue, "O4", C4, 1.23, N3, 119.8, C2, 180.0, 0, 1114, forceField,
1342 bondList);
1343 Atom C5 = buildHeavy(residue, "C5", C4, 1.44, N3, 114.7, C2, 0.0, 0, 1110, forceField, bondList);
1344 Atom C6 = buildHeavy(residue, "C6", C5, 1.34, O4, 119.2, C4, 0.0, 0, 1111, forceField, bondList);
1345 buildBond(C6, N1, forceField, bondList);
1346 buildH(residue, "H3", N3, 1.00e0, C2, 116.5e0, N1, 180.0e0, 0, 1113, forceField, bondList);
1347 buildH(residue, "H5", C5, 1.08e0, C4, 120.4e0, N3, 180.0e0, 0, 1115, forceField, bondList);
1348 buildH(residue, "H6", C6, 1.08e0, C5, 118.6e0, C4, 180.0e0, 0, 1116, forceField, bondList);
1349
1350 return residue;
1351 }
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363 private static Residue buildYYG(Residue residue, Atom C1s, ForceField forceField,
1364 List<Bond> bondList) throws MissingHeavyAtomException, MissingAtomTypeException {
1365 Atom N9 = buildHeavy(residue, "N9", C1s, 1640, forceField, bondList);
1366 Atom C8 = buildHeavy(residue, "C8", N9, 1644, forceField, bondList);
1367 Atom N7 = buildHeavy(residue, "N7", C8, 1643, forceField, bondList);
1368 Atom C5 = buildHeavy(residue, "C5", N7, 1642, forceField, bondList);
1369 Atom C6 = buildHeavy(residue, "C6", C5, 1648, forceField, bondList);
1370 Atom O6 = buildHeavy(residue, "O6", C6, 1650, forceField, bondList);
1371 Atom N1 = buildHeavy(residue, "N1", C6, 1647, forceField, bondList);
1372 Atom C2 = buildHeavy(residue, "C2", N1, 1646, forceField, bondList);
1373 Atom N2 = buildHeavy(residue, "N2", C2, 1649, forceField, bondList);
1374 Atom N3 = buildHeavy(residue, "N3", C2, 1645, forceField, bondList);
1375 Atom C3 = buildHeavy(residue, "C3", N3, 1652, forceField, bondList);
1376 Atom C4 = buildHeavy(residue, "C4", N3, 1641, forceField, bondList);
1377 Atom C11 = buildHeavy(residue, "C11", N2, 1657, forceField, bondList);
1378 Atom C10 = buildHeavy(residue, "C10", C11, 1658, forceField, bondList);
1379 Atom C12 = buildHeavy(residue, "C12", C11, 1656, forceField, bondList);
1380 Atom C13 = buildHeavy(residue, "C13", C12, 1662, forceField, bondList);
1381 Atom C14 = buildHeavy(residue, "C14", C13, 1665, forceField, bondList);
1382 Atom C15 = buildHeavy(residue, "C15", C14, 1668, forceField, bondList);
1383 Atom C16 = buildHeavy(residue, "C16", C15, 1675, forceField, bondList);
1384 Atom O17 = buildHeavy(residue, "O17", C16, 1676, forceField, bondList);
1385 Atom O18 = buildHeavy(residue, "O18", C16, 1674, forceField, bondList);
1386 Atom C19 = buildHeavy(residue, "C19", O18, 1670, forceField, bondList);
1387 Atom N20 = buildHeavy(residue, "N20", C15, 1677, forceField, bondList);
1388 Atom C21 = buildHeavy(residue, "C21", N20, 1679, forceField, bondList);
1389 Atom O22 = buildHeavy(residue, "O22", C21, 1680, forceField, bondList);
1390 Atom O23 = buildHeavy(residue, "O23", C21, 1681, forceField, bondList);
1391 Atom C24 = buildHeavy(residue, "C24", O23, 1682, forceField, bondList);
1392 buildBond(C4, C5, forceField, bondList);
1393 buildBond(C4, N9, forceField, bondList);
1394 buildBond(N1, C12, forceField, bondList);
1395 buildH(residue, "H8", C8, 1.08e0, N7, 123.0e0, C5, 180.0e0, 0, 1651, forceField, bondList);
1396 Atom H31 = buildH(residue, "H31", C3, 1.08e0, N3, 109.5e0, C4, 0.0e0, 0, 1653, forceField,
1397 bondList);
1398 buildH(residue, "H32", C3, 1.08e0, N3, 109.5e0, H31, 109.5e0, 1, 1654, forceField, bondList);
1399 buildH(residue, "H33", C3, 1.08e0, N3, 109.5e0, H31, 109.5e0, -1, 1655, forceField, bondList);
1400 Atom H101 = buildH(residue, "H101", C10, 1.08e0, C11, 109.5e0, N2, 0.0e0, 0, 1659, forceField,
1401 bondList);
1402 buildH(residue, "H102", C10, 1.08e0, C11, 109.5e0, H101, 109.5e0, 1, 1660, forceField, bondList);
1403 buildH(residue, "H103", C10, 1.08e0, C11, 109.5e0, H101, 109.5e0, -1, 1661, forceField,
1404 bondList);
1405 buildH(residue, "H131", C13, 1.08e0, C12, 109.5e0, C14, 109.5e0, 1, 1663, forceField, bondList);
1406 buildH(residue, "H132", C13, 1.08e0, C12, 109.5e0, C14, 109.5e0, -1, 1664, forceField, bondList);
1407 buildH(residue, "H141", C14, 1.08e0, C13, 109.5e0, C15, 109.5e0, 1, 1666, forceField, bondList);
1408 buildH(residue, "H142", C14, 1.08e0, C13, 109.5e0, C15, 109.5e0, -1, 1667, forceField, bondList);
1409 buildH(residue, "H15", C15, 1.08e0, C14, 109.5e0, O18, 180.e0, 0, 1669, forceField, bondList);
1410 Atom H191 = buildH(residue, "H191", C19, 1.08e0, O18, 109.5e0, C16, 0.0e0, 0, 1671, forceField,
1411 bondList);
1412 buildH(residue, "H192", C19, 1.08e0, O18, 109.5e0, H191, 109.5e0, 1, 1672, forceField, bondList);
1413 buildH(residue, "H193", C19, 1.08e0, O18, 109.5e0, H191, 109.5e0, -1, 1673, forceField,
1414 bondList);
1415 buildH(residue, "HN2", N20, 1.00e0, C15, 109.5e0, O22, 180.0e0, 0, 1678, forceField, bondList);
1416 Atom H241 = buildH(residue, "H241", C24, 1.08e0, O23, 109.5e0, C21, 0.0e0, 0, 1683, forceField,
1417 bondList);
1418 buildH(residue, "H242", C24, 1.08e0, O23, 109.5e0, H241, 109.5e0, 1, 1684, forceField, bondList);
1419 buildH(residue, "H243", C24, 1.08e0, O23, 109.5e0, H241, 109.5e0, -1, 1685, forceField,
1420 bondList);
1421 return residue;
1422 }
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433 private static Atom getNextResAtom(Residue residue, Residue nextResidue, String atomName) {
1434 if (nextResidue == null) {
1435 throw new IllegalArgumentException(
1436 String.format(" Residue %s: No subsequent residue to find atom %s in!", residue,
1437 atomName));
1438 }
1439 List<Atom> nrAtoms = nextResidue.getAtomList();
1440 for (Atom atom : nrAtoms) {
1441 if (atom.getName().equalsIgnoreCase(atomName)) {
1442 return atom;
1443 }
1444 }
1445 throw new IllegalArgumentException(
1446 String.format(" Residue %s: Subsequent residue %s did not contain an atom %s", residue,
1447 nextResidue, atomName));
1448 }
1449
1450
1451
1452
1453
1454
1455
1456 public static int getNucleicAcidNumber(String residueName) {
1457 int nucleicAcidNumber = -1;
1458 for (NucleicAcid3 nucleicAcid : nucleicAcidList) {
1459 nucleicAcidNumber++;
1460 if (nucleicAcid.toString().equalsIgnoreCase(residueName)) {
1461 break;
1462 }
1463 }
1464 return nucleicAcidNumber;
1465 }
1466 }