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.algorithms.commands;
39
40 import ffx.algorithms.cli.AlgorithmsCommand;
41 import ffx.algorithms.cli.MinimizeOptions;
42 import ffx.crystal.Crystal;
43 import ffx.numerics.Potential;
44 import ffx.potential.ForceFieldEnergy;
45 import ffx.potential.cli.AtomSelectionOptions;
46 import ffx.potential.openmm.OpenMMEnergy;
47 import ffx.potential.parsers.PDBFilter;
48 import ffx.potential.parsers.SystemFilter;
49 import ffx.potential.parsers.XYZFilter;
50 import ffx.utilities.FFXBinding;
51 import ffx.utilities.FileUtils;
52 import org.apache.commons.io.FilenameUtils;
53 import picocli.CommandLine.Command;
54 import picocli.CommandLine.Mixin;
55 import picocli.CommandLine.Parameters;
56
57 import java.io.File;
58 import java.util.Collections;
59 import java.util.List;
60
61 import static java.lang.String.format;
62
63
64
65
66
67
68
69
70
71 @Command(description = " Run OpenMM Accelerated L-BFGS minimization on a system.", name = "MinimizeOpenMM")
72 public class MinimizeOpenMM extends AlgorithmsCommand {
73
74 @Mixin
75 private AtomSelectionOptions atomSelectionOptions;
76
77 @Mixin
78 private MinimizeOptions minimizeOptions;
79
80
81
82
83 @Parameters(arity = "1", paramLabel = "file",
84 description = "XYZ or PDB input file.")
85 private String filename;
86
87 private ForceFieldEnergy forceFieldEnergy;
88
89
90
91
92 public MinimizeOpenMM() {
93 super();
94 }
95
96
97
98
99
100
101 public MinimizeOpenMM(FFXBinding binding) {
102 super(binding);
103 }
104
105
106
107
108
109
110 public MinimizeOpenMM(String[] args) {
111 super(args);
112 }
113
114
115
116
117 @Override
118 public MinimizeOpenMM run() {
119
120
121 if (!init()) {
122 return this;
123 }
124
125 if (System.getProperty("platform") == null || System.getProperty("platform").isEmpty()) {
126 System.setProperty("platform", "OMM");
127 }
128
129
130 activeAssembly = getActiveAssembly(filename);
131 if (activeAssembly == null) {
132 logger.info(helpString());
133 return this;
134 }
135
136
137 filename = activeAssembly.getFile().getAbsolutePath();
138
139 atomSelectionOptions.setActiveAtoms(activeAssembly);
140
141 forceFieldEnergy = activeAssembly.getPotentialEnergy();
142 switch (forceFieldEnergy.getPlatform()) {
143 case OMM:
144 case OMM_CUDA:
145 case OMM_OPENCL:
146 case OMM_CPU:
147 case OMM_REF:
148 logger.fine(" Platform is appropriate for OpenMM Minimization.");
149 break;
150 case FFX:
151 default:
152 logger.severe(format(
153 " Platform %s is inappropriate for OpenMM minimization. Please explicitly specify an OpenMM platform.",
154 forceFieldEnergy.getPlatform()));
155 break;
156 }
157
158 if (forceFieldEnergy instanceof OpenMMEnergy) {
159 ffx.algorithms.optimize.MinimizeOpenMM minimizeOpenMM = new ffx.algorithms.optimize.MinimizeOpenMM(
160 activeAssembly);
161 minimizeOpenMM.minimize(minimizeOptions.getEps(), minimizeOptions.getIterations());
162
163 if (baseDir == null || !baseDir.exists() || !baseDir.isDirectory() || !baseDir.canWrite()) {
164 baseDir = new File(FilenameUtils.getFullPath(filename));
165 }
166
167 String dirName = baseDir.toString() + File.separator;
168 String name = FilenameUtils.getName(filename);
169 String ext = FilenameUtils.getExtension(name);
170 name = FilenameUtils.removeExtension(name);
171
172 File saveFile;
173 SystemFilter writeFilter;
174 PDBFilter pdbFilter = null;
175 XYZFilter xyzFilter = null;
176 if (ext.toUpperCase().contains("XYZ")) {
177 saveFile = new File(dirName + name + ".xyz");
178 xyzFilter = new XYZFilter(saveFile, activeAssembly, activeAssembly.getForceField(),
179 activeAssembly.getProperties());
180 writeFilter = xyzFilter;
181 algorithmFunctions.saveAsXYZ(activeAssembly, saveFile);
182 } else if (ext.toUpperCase().contains("ARC")) {
183 saveFile = new File(dirName + name + ".arc");
184 xyzFilter = new XYZFilter(saveFile, activeAssembly, activeAssembly.getForceField(),
185 activeAssembly.getProperties());
186 writeFilter = xyzFilter;
187 algorithmFunctions.saveAsXYZ(activeAssembly, saveFile);
188 } else {
189 saveFile = new File(dirName + name + ".pdb");
190 pdbFilter = new PDBFilter(saveFile, activeAssembly, activeAssembly.getForceField(),
191 activeAssembly.getProperties());
192 writeFilter = pdbFilter;
193 int numModels = algorithmFunctions.getFilter().countNumModels();
194 if (numModels > 1) {
195 pdbFilter.setModelNumbering(0);
196 }
197 pdbFilter.writeFile(saveFile, true, false, false);
198 }
199
200 SystemFilter systemFilter = algorithmFunctions.getFilter();
201 saveFile = activeAssembly.getFile();
202
203 if (systemFilter instanceof XYZFilter || systemFilter instanceof PDBFilter) {
204 while (systemFilter.readNext()) {
205 Crystal crystal = activeAssembly.getCrystal();
206 ForceFieldEnergy forceFieldEnergy = activeAssembly.getPotentialEnergy();
207 forceFieldEnergy.setCrystal(crystal);
208 if (systemFilter instanceof PDBFilter) {
209 FileUtils.append(saveFile, "ENDMDL\n");
210 minimizeOpenMM.minimize(minimizeOptions.getEps(), minimizeOptions.getIterations());
211 pdbFilter.writeFile(saveFile, true, false, false);
212 } else if (systemFilter instanceof XYZFilter) {
213 minimizeOpenMM.minimize(minimizeOptions.getEps(), minimizeOptions.getIterations());
214 writeFilter.writeFile(saveFile, true);
215 }
216 }
217 if (systemFilter instanceof PDBFilter) {
218 FileUtils.append(saveFile, "END\n");
219 }
220 }
221 } else {
222 logger.severe(" Could not start OpenMM minimization.");
223 }
224
225 return this;
226 }
227
228
229
230
231 @Override
232 public List<Potential> getPotentials() {
233 List<Potential> potentials;
234 if (forceFieldEnergy == null) {
235 potentials = Collections.emptyList();
236 } else {
237 potentials = Collections.singletonList(forceFieldEnergy);
238 }
239 return potentials;
240 }
241
242 }