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.terms;
39
40 import ffx.potential.bonded.Atom;
41 import ffx.potential.bonded.Bond;
42 import ffx.potential.bonded.BondedTerm;
43 import ffx.potential.bonded.Torsion;
44 import ffx.potential.parameters.ForceField;
45 import ffx.potential.parameters.TorsionType;
46 import org.apache.commons.configuration2.CompositeConfiguration;
47
48 import java.util.ArrayList;
49 import java.util.Collection;
50 import java.util.Collections;
51 import java.util.EmptyStackException;
52 import java.util.List;
53 import java.util.logging.Logger;
54
55
56
57
58
59 public class RestrainTorsionPotentialEnergy extends EnergyTerm {
60
61 private static final Logger logger = Logger.getLogger(RestrainTorsionPotentialEnergy.class.getName());
62
63
64
65
66 private final List<Torsion> restrainTorsions = new ArrayList<>();
67
68
69
70
71
72
73 public RestrainTorsionPotentialEnergy(String name) {
74 super(name);
75 }
76
77
78
79
80
81
82
83 public RestrainTorsionPotentialEnergy(String name, int forceGroup) {
84 super(name, forceGroup);
85 }
86
87
88
89
90
91
92
93
94 public RestrainTorsionPotentialEnergy(String name, int forceGroup, List<Torsion> restrainTorsions) {
95 super(name, forceGroup);
96 if (restrainTorsions != null) {
97 Collections.sort(restrainTorsions);
98 this.restrainTorsions.addAll(restrainTorsions);
99 logger.info(String.format(" Restrain Torsions: %10d", getNumberOfRestrainTorsions()));
100 }
101 }
102
103
104
105
106 @Override
107 public int getNumberOfTerms() {
108 return getNumberOfRestrainTorsions();
109 }
110
111
112
113
114 @Override
115 public BondedTerm[] getBondedTermsArray() {
116 return getRestrainTorsionArray();
117 }
118
119
120
121
122
123
124
125 public RestrainTorsionPotentialEnergy(String name, Collection<Torsion> restrainTorsions) {
126 super(name);
127 if (restrainTorsions != null) {
128 this.restrainTorsions.addAll(restrainTorsions);
129 }
130 }
131
132
133
134
135
136
137
138 public boolean addRestrainTorsion(Torsion torsion) {
139 if (torsion == null) {
140 return false;
141 }
142 return restrainTorsions.add(torsion);
143
144 }
145
146
147
148
149
150
151
152 public boolean addRestrainTorsions(Torsion[] torsions) {
153 if (torsions == null) {
154 return false;
155 }
156 Collections.addAll(this.restrainTorsions, torsions);
157 return true;
158 }
159
160
161
162
163
164
165
166 public boolean addRestrainTorsions(List<Torsion> torsions) {
167 if (torsions == null) {
168 return false;
169 }
170 this.restrainTorsions.addAll(torsions);
171 return true;
172 }
173
174
175
176
177
178
179
180 public boolean removeRestrainTorsion(Torsion torsion) {
181 if (torsion == null) {
182 return false;
183 }
184 return restrainTorsions.remove(torsion);
185 }
186
187
188
189
190
191
192
193
194 public Torsion getRestrainTorsion(int index) {
195 return restrainTorsions.get(index);
196 }
197
198
199
200
201
202
203 public List<Torsion> getRestrainTorsions() {
204 return Collections.unmodifiableList(restrainTorsions);
205 }
206
207
208
209
210
211
212 public Torsion[] getRestrainTorsionArray() {
213 return restrainTorsions.toArray(new Torsion[0]);
214 }
215
216
217
218
219
220
221 public int getNumberOfRestrainTorsions() {
222 return restrainTorsions.size();
223 }
224
225 @Override
226 public String toPDBString() {
227 if (getNumberOfRestrainTorsions() <= 0) {
228 return "";
229 }
230 return String.format("REMARK 3 %s %g (%d)\n", "RESTRAIN TORSION : ", getEnergy(), getNumberOfRestrainTorsions());
231 }
232
233 @Override
234 public String toString() {
235 return String.format(" %s %20.8f %12d %12.3f\n", "Restrain Torsion ",
236 getEnergy(), getNumberOfRestrainTorsions(), getTime());
237 }
238
239
240
241
242 @Override
243 public void log() {
244 if (getNumberOfRestrainTorsions() <= 0) {
245 return;
246 }
247 logger.info("\n Restrain Torsion Interactions:");
248 for (Torsion torsion : getRestrainTorsions()) {
249 logger.info(" Restrain Torsion \t" + torsion.toString());
250 }
251 }
252
253
254
255
256
257
258
259
260
261
262 public static Torsion[] configureRestrainTorsions(CompositeConfiguration properties,
263 ForceField forceField,
264 Atom[] atoms,
265 Torsion[] torsions) {
266 StringBuilder restrainLog = new StringBuilder("\n Restrain-Torsions");
267
268 String[] restrainTorsions = properties.getStringArray("restrain-torsion");
269 double torsionUnits = forceField.getDouble("TORSIONUNIT", TorsionType.DEFAULT_TORSION_UNIT);
270 List<Torsion> restrainTorsionList = new ArrayList<>(restrainTorsions.length);
271 for (String restrainString : restrainTorsions) {
272
273 restrainString = "restrain-torsion " + restrainString;
274
275 String input = restrainString.split("#+")[0];
276
277 String[] tokens = input.trim().split(" +");
278
279
280 TorsionType torsionType = TorsionType.parse(input, tokens);
281 torsionType.torsionUnit = torsionUnits;
282
283
284 int[] atomIndices = torsionType.atomClasses;
285 int ai1 = atomIndices[0] - 1;
286 int ai2 = atomIndices[1] - 1;
287 int ai3 = atomIndices[2] - 1;
288 int ai4 = atomIndices[3] - 1;
289 Atom a1 = atoms[ai1];
290 Atom a2 = atoms[ai2];
291 Atom a3 = atoms[ai3];
292 Atom a4 = atoms[ai4];
293
294
295 Bond firstBond = a1.getBond(a2);
296 Bond middleBond = a2.getBond(a3);
297 Bond lastBond = a3.getBond(a4);
298 Torsion torsion = new Torsion(firstBond, middleBond, lastBond);
299 torsion.setTorsionType(torsionType);
300 restrainTorsionList.add(torsion);
301 restrainLog.append("\n ").append(torsion);
302 }
303
304
305 restrainTorsionList.addAll(restrainAllTorsions(torsions, properties));
306
307 if (!restrainTorsionList.isEmpty()) {
308 logger.info(restrainLog.toString());
309 return restrainTorsionList.toArray(new Torsion[0]);
310 } else {
311 return null;
312 }
313 }
314
315
316
317
318
319
320
321
322 private static List<Torsion> restrainAllTorsions(Torsion[] torsions,
323 CompositeConfiguration properties) {
324
325 List<Torsion> restrainTorsionList = new ArrayList<>();
326
327 String restrainTorsions;
328 boolean noHydrogenTorsions = false;
329 if (properties.containsKey("restrain-all-torsions")) {
330 restrainTorsions = properties.getString("restrain-all-torsions");
331 } else if (properties.containsKey("restrain-heavy-torsions")) {
332 restrainTorsions = properties.getString("restrain-heavy-torsions");
333 noHydrogenTorsions = true;
334 } else {
335 return restrainTorsionList;
336 }
337
338 logger.info(" Restrain torsions " + restrainTorsions);
339
340 String input = restrainTorsions.split("#+")[0];
341
342 String[] tokens = input.trim().split(" +");
343 double forceConstant = Double.parseDouble(tokens[0]);
344 logger.info(" Force constant %10.6f".formatted(forceConstant));
345
346 for (Torsion torsion : torsions) {
347
348 if (noHydrogenTorsions && torsion.containsHydrogen()) {
349 continue;
350 }
351
352
353 TorsionType torsionType = torsion.torsionType;
354 int[] atomClasses = torsionType.atomClasses.clone();
355
356 double[] amplitude = {forceConstant};
357 double[] phase = {torsion.measure() + 180.0};
358 int[] periodicity = {1};
359
360
361 TorsionType newTorsionType = new TorsionType(atomClasses, amplitude, phase, periodicity);
362 newTorsionType.torsionUnit = torsionType.torsionUnit;
363
364 Bond b1 = torsion.getBond(0);
365 Bond b2 = torsion.getBond(1);
366 Bond b3 = torsion.getBond(2);
367 Torsion newTorsion = new Torsion(b1, b2, b3);
368 newTorsion.setTorsionType(newTorsionType);
369
370 restrainTorsionList.add(newTorsion);
371 }
372
373 return restrainTorsionList;
374 }
375 }