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.xray.commands;
39
40 import ffx.algorithms.cli.AlgorithmsCommand;
41 import ffx.algorithms.cli.MinimizeOptions;
42 import ffx.numerics.Potential;
43 import ffx.potential.MolecularAssembly;
44 import ffx.utilities.FFXBinding;
45 import ffx.xray.DiffractionData;
46 import ffx.xray.RefinementMinimize;
47 import ffx.xray.RefinementMinimize.RefinementMode;
48 import ffx.xray.cli.XrayOptions;
49 import org.apache.commons.configuration2.CompositeConfiguration;
50 import picocli.CommandLine.Command;
51 import picocli.CommandLine.Mixin;
52 import picocli.CommandLine.Option;
53 import picocli.CommandLine.Parameters;
54
55 import java.util.ArrayList;
56 import java.util.Arrays;
57 import java.util.List;
58 import java.util.stream.Collectors;
59
60 import static java.lang.String.format;
61 import static org.apache.commons.io.FilenameUtils.removeExtension;
62
63
64
65
66
67
68
69
70 @Command(description = " Refine an X-ray/Neutron target.", name = "xray.Minimize")
71 public class Minimize extends AlgorithmsCommand {
72
73 @Mixin
74 private MinimizeOptions minimizeOptions;
75
76 @Mixin
77 private XrayOptions xrayOptions;
78
79
80
81
82 @Option(names = {"-t", "--threeStage"}, paramLabel = "false",
83 description = "Perform refinement in 3 stages: coordinates, b-factors, and then occupancies (overrides mode setting if true)")
84 private boolean threeStage = false;
85
86
87
88
89 @Option(names = {"-E", "--eps3"}, paramLabel = "-1.0", arity = "3",
90 description = "RMS gradient convergence criteria for three stage refinement (default of -1.0 automatically determines eps for each stage).")
91 private double[] eps3 = {-1.0, -1.0, -1.0};
92
93
94
95
96 @Parameters(arity = "1..*", paramLabel = "files", description = "PDB and Diffraction input files.")
97 private List<String> filenames;
98 private MolecularAssembly[] molecularAssemblies;
99 private DiffractionData diffractionData;
100
101
102
103
104 public Minimize() {
105 super();
106 }
107
108
109
110
111
112
113 public Minimize(String[] args) {
114 super(args);
115 }
116
117
118
119
120
121
122 public Minimize(FFXBinding binding) {
123 super(binding);
124 }
125
126 @Override
127 public Minimize run() {
128
129 if (!init()) {
130 return this;
131 }
132
133 xrayOptions.init();
134
135 String filename;
136 if (filenames != null && !filenames.isEmpty()) {
137
138 molecularAssemblies = algorithmFunctions.openAll(filenames.get(0));
139 activeAssembly = molecularAssemblies[0];
140 filename = filenames.get(0);
141 } else if (activeAssembly == null) {
142 logger.info(helpString());
143 return this;
144 } else {
145 molecularAssemblies = new MolecularAssembly[]{activeAssembly};
146 filename = activeAssembly.getFile().getAbsolutePath();
147 }
148
149 logger.info("\n Running xray.Minimize on " + filename);
150
151
152 CompositeConfiguration properties = activeAssembly.getProperties();
153 xrayOptions.setProperties(parseResult, properties);
154
155
156 diffractionData = xrayOptions.getDiffractionData(filenames, molecularAssemblies, properties);
157 diffractionData.scaleBulkFit();
158 diffractionData.printStats();
159 algorithmFunctions.energy(molecularAssemblies);
160
161
162 double coordinateEPS = eps3[0];
163 double bfactorEPS = eps3[1];
164 double occupancyEPS = eps3[2];
165
166
167 int nBFGS = minimizeOptions.getNBFGS();
168
169
170 int maxIterations = minimizeOptions.getIterations();
171
172 if (threeStage) {
173
174 RefinementMinimize refinementMinimize = new RefinementMinimize(diffractionData,
175 RefinementMode.COORDINATES);
176 if (coordinateEPS < 0.0) {
177 coordinateEPS = refinementMinimize.getEps();
178 }
179 if (maxIterations < Integer.MAX_VALUE) {
180 logger.info(format(
181 "\n RMS gradient convergence criteria: %8.5f, Maximum iterations %d", coordinateEPS,
182 maxIterations));
183 } else {
184 logger.info(format("\n RMS gradient convergence criteria: %8.5f", coordinateEPS));
185 }
186 refinementMinimize.minimize(nBFGS, coordinateEPS, maxIterations);
187 diffractionData.scaleBulkFit();
188 diffractionData.printStats();
189 algorithmFunctions.energy(molecularAssemblies);
190
191
192 refinementMinimize = new RefinementMinimize(diffractionData, RefinementMode.BFACTORS);
193 if (bfactorEPS < 0.0) {
194 bfactorEPS = refinementMinimize.getEps();
195 }
196 if (maxIterations < Integer.MAX_VALUE) {
197 logger.info(
198 format("\n RMS gradient convergence criteria: %8.5f, Maximum iterations %d", bfactorEPS,
199 maxIterations));
200 } else {
201 logger.info(format("\n RMS gradient convergence criteria: %8.5f", bfactorEPS));
202 }
203 refinementMinimize.minimize(nBFGS, bfactorEPS, maxIterations);
204 diffractionData.scaleBulkFit();
205 diffractionData.printStats();
206
207
208 if (
209 !diffractionData.getAltResidues().isEmpty() || !diffractionData.getAltMolecules().isEmpty()) {
210 refinementMinimize = new RefinementMinimize(diffractionData, RefinementMode.OCCUPANCIES);
211 if (occupancyEPS < 0.0) {
212 occupancyEPS = refinementMinimize.getEps();
213 }
214 if (maxIterations < Integer.MAX_VALUE) {
215 logger.info(format("\n RMS gradient convergence criteria: %8.5f, Maximum iterations %d",
216 occupancyEPS, maxIterations));
217 } else {
218 logger.info(format("\n RMS gradient convergence criteria: %8.5f", occupancyEPS));
219 }
220 refinementMinimize.minimize(occupancyEPS, maxIterations);
221 diffractionData.scaleBulkFit();
222 diffractionData.printStats();
223 } else {
224 logger.info("Occupancy refinement not necessary, skipping");
225 }
226
227 } else {
228
229 RefinementMode refinementMode = xrayOptions.refinementMode;
230 RefinementMinimize refinementMinimize = new RefinementMinimize(diffractionData, refinementMode);
231 double eps = minimizeOptions.getEps();
232 if (eps < 0.0) {
233 eps = refinementMinimize.getEps();
234 }
235
236 if (maxIterations < Integer.MAX_VALUE) {
237 logger.info(format("\n RMS gradient convergence criteria: %8.5f, Maximum iterations %d", eps,
238 maxIterations));
239 } else {
240 logger.info(format("\n RMS gradient convergence criteria: %8.5f", eps));
241 }
242 refinementMinimize.minimize(eps, maxIterations);
243 diffractionData.scaleBulkFit();
244 diffractionData.printStats();
245 }
246
247
248 algorithmFunctions.energy(molecularAssemblies);
249
250 logger.info(" ");
251 diffractionData.writeModel(removeExtension(filename) + ".pdb");
252 diffractionData.writeData(removeExtension(filename) + ".mtz");
253
254 return this;
255 }
256
257 @Override
258 public List<Potential> getPotentials() {
259 if (molecularAssemblies == null) {
260 return new ArrayList<>();
261 } else {
262 return Arrays.stream(molecularAssemblies)
263 .filter(a -> a != null)
264 .map(MolecularAssembly::getPotentialEnergy)
265 .filter(e -> e != null)
266 .collect(Collectors.toList());
267 }
268 }
269
270 @Override
271 public boolean destroyPotentials() {
272 return diffractionData == null ? true : diffractionData.destroy();
273 }
274 }