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 ffx.utilities.FFXProperty;
41
42 import java.util.Comparator;
43 import java.util.Objects;
44 import java.util.logging.Level;
45 import java.util.logging.Logger;
46
47 import static ffx.potential.parameters.ForceField.ForceFieldType.BIOTYPE;
48 import static ffx.utilities.PropertyGroup.PotentialFunctionParameter;
49 import static java.lang.Integer.parseInt;
50 import static java.lang.String.format;
51 import static java.lang.System.arraycopy;
52
53
54
55
56
57
58
59 @FFXProperty(name = "biotype", clazz = String.class, propertyGroup = PotentialFunctionParameter, description = """
60 [integer, name, quoted string and integer]
61 Provides the values to define the correspondence between a single bio-polymer atom type and its force field atom type.
62 """)
63 public final class BioType extends BaseType implements Comparator<String> {
64
65
66
67
68 private static final Logger logger = Logger.getLogger(BioType.class.getName());
69
70
71
72 public final String atomName;
73
74
75
76 public final String moleculeName;
77
78
79
80 public final String[] bonds;
81
82
83
84 public int index;
85
86
87
88 public int atomType;
89
90
91
92
93
94
95
96
97
98
99 public BioType(int index, String atomName, String moleculeName, int atomType, String[] bonds) {
100 super(BIOTYPE, Integer.toString(index));
101 this.index = index;
102 this.atomName = atomName;
103 if (moleculeName != null) {
104 this.moleculeName = moleculeName.replace(',', ' ').replace('"', ' ').trim();
105 } else {
106 this.moleculeName = null;
107 }
108 this.atomType = atomType;
109 this.bonds = bonds;
110 }
111
112
113
114
115
116
117
118
119 public static BioType parse(String input, String[] tokens) {
120 if (tokens.length < 5) {
121 logger.log(Level.WARNING, "Invalid BIOTYPE type:\n{0}", input);
122 } else {
123 try {
124 int index = parseInt(tokens[1]);
125 String atomName = tokens[2];
126
127
128
129 int first = input.indexOf("\"");
130 int last = input.lastIndexOf("\"");
131 if (first >= last) {
132 logger.log(Level.WARNING, "Invalid BIOTYPE type:\n{0}", input);
133 return null;
134 }
135
136 String moleculeName = input.substring(first, last + 1).intern();
137
138
139 tokens = input.substring(last + 1).trim().split(" +");
140 int atomType = parseInt(tokens[0]);
141 int bondCount = tokens.length - 1;
142 String[] bonds = null;
143 if (bondCount > 0) {
144 bonds = new String[bondCount];
145 arraycopy(tokens, 1, bonds, 0, bondCount);
146 }
147 return new BioType(index, atomName, moleculeName, atomType, bonds);
148 } catch (NumberFormatException e) {
149 String message = "Exception parsing BIOTYPE type:\n" + input + "\n";
150 logger.log(Level.SEVERE, message, e);
151 }
152 }
153 return null;
154 }
155
156
157
158
159 @Override
160 public int compare(String s1, String s2) {
161 int t1 = parseInt(s1);
162 int t2 = parseInt(s2);
163 return Integer.compare(t1, t2);
164 }
165
166
167
168
169 @Override
170 public boolean equals(Object o) {
171 if (this == o) {
172 return true;
173 }
174 if (o == null || getClass() != o.getClass()) {
175 return false;
176 }
177 BioType bioType = (BioType) o;
178 return bioType.index == this.index;
179 }
180
181
182
183
184 @Override
185 public int hashCode() {
186 return Objects.hash(index);
187 }
188
189
190
191
192
193
194 @Override
195 public String toString() {
196 StringBuilder sb =
197 new StringBuilder(
198 format("biotype %5d %-4s \"%s\" %5d", index, atomName, moleculeName, atomType));
199 if (bonds != null) {
200 for (String bond : bonds) {
201 sb.append(format(" %-4s", bond));
202 }
203 }
204 return sb.toString();
205 }
206
207
208
209
210
211
212
213 void incrementIndexAndType(int indexIncrement, int typeIncrement) {
214 index += indexIncrement;
215 atomType += typeIncrement;
216 setKey(Integer.toString(index));
217 }
218 }