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.DynamicsOptions;
42 import ffx.algorithms.cli.LambdaParticleOptions;
43 import ffx.algorithms.cli.MultiDynamicsOptions;
44 import ffx.algorithms.cli.OSTOptions;
45 import ffx.algorithms.cli.ThermodynamicsOptions;
46 import ffx.algorithms.thermodynamics.OrthogonalSpaceTempering;
47 import ffx.numerics.Potential;
48 import ffx.potential.ForceFieldEnergy;
49 import ffx.utilities.FFXBinding;
50 import org.apache.commons.io.FilenameUtils;
51 import picocli.CommandLine.Command;
52 import picocli.CommandLine.Option;
53 import picocli.CommandLine.Parameters;
54
55 import java.io.File;
56 import java.io.FileWriter;
57 import java.io.IOException;
58 import java.util.Collections;
59 import java.util.List;
60
61
62
63
64
65
66
67
68 @Command(description = " Evaluate the Orthogonal Space Histogram.", name = "Histogram")
69 public class Histogram extends AlgorithmsCommand {
70
71
72
73
74 @Option(names = {"-s", "--save"}, paramLabel = "false",
75 description = "Save the bias histogram to histogram.txt, the total PMF to pmf.txt, and 2D PMF to pmf.2D.txt")
76 private boolean save = false;
77
78
79
80
81 @Option(names = {"-b", "--bias"}, paramLabel = "false",
82 description = "By default, the PMF is saved. This flag flips the sign to give the OST bias.")
83 private boolean bias = false;
84
85
86
87
88 @Parameters(arity = "1", paramLabel = "file",
89 description = "XYZ or PDB input file.")
90 private String filename;
91
92 private OrthogonalSpaceTempering orthogonalSpaceTempering;
93 private File saveDir = null;
94
95
96
97
98 public Histogram() {
99 super();
100 }
101
102
103
104
105
106
107 public Histogram(FFXBinding binding) {
108 super(binding);
109 }
110
111
112
113
114
115
116 public Histogram(String[] args) {
117 super(args);
118 }
119
120
121
122
123 @Override
124 public Histogram run() {
125
126
127 if (!init()) {
128 return this;
129 }
130
131
132 activeAssembly = getActiveAssembly(filename);
133 if (activeAssembly == null) {
134 logger.info(helpString());
135 return this;
136 }
137
138
139 filename = activeAssembly.getFile().getAbsolutePath();
140
141 logger.info("\n Evaluating Histogram for " + filename);
142
143 File structureFile = new File(FilenameUtils.normalize(filename));
144 structureFile = new File(structureFile.getAbsolutePath());
145 String baseFilename = FilenameUtils.removeExtension(structureFile.getName());
146 File histogramRestart = new File(baseFilename + ".his");
147 File lambdaRestart = null;
148
149
150 ForceFieldEnergy energy = activeAssembly.getPotentialEnergy();
151
152
153 energy.energy(true, true);
154 logger.info("");
155
156 if (saveDir == null || !saveDir.exists() || !saveDir.isDirectory() || !saveDir.canWrite()) {
157 saveDir = new File(FilenameUtils.getFullPath(filename));
158 }
159
160
161 DynamicsOptions dynamicsOptions = new DynamicsOptions();
162 LambdaParticleOptions lambdaParticleOptions = new LambdaParticleOptions();
163 MultiDynamicsOptions multiDynamicsOptions = new MultiDynamicsOptions();
164 ThermodynamicsOptions thermodynamicsOptions = new ThermodynamicsOptions();
165 OSTOptions ostOptions = new OSTOptions();
166
167
168 orthogonalSpaceTempering = ostOptions.constructOST(energy,
169 lambdaRestart, histogramRestart, activeAssembly, null,
170 dynamicsOptions, thermodynamicsOptions, lambdaParticleOptions,
171 algorithmListener, !multiDynamicsOptions.isSynchronous());
172
173 if (save) {
174 orthogonalSpaceTempering.setMolecularAssembly(activeAssembly);
175 OrthogonalSpaceTempering.Histogram histogram = orthogonalSpaceTempering.getHistogram();
176 histogram.updateFreeEnergyDifference(false, true);
177 StringBuffer sb = histogram.evaluateTotalOSTBias(bias);
178
179 String dirName = saveDir.toString() + File.separator;
180 String file = dirName + "pmf.txt";
181 logger.info(" Writing " + file);
182 try (FileWriter fileWriter = new FileWriter(file)) {
183 fileWriter.write(sb.toString());
184 } catch (IOException e) {
185 logger.severe("Error writing file " + file + ": " + e.getMessage());
186 }
187
188 sb = histogram.evaluate2DOSTBias(bias);
189 file = dirName + "pmf.2D.txt";
190 logger.info(" Writing " + file);
191 try (FileWriter fileWriter = new FileWriter(file)) {
192 fileWriter.write(sb.toString());
193 } catch (IOException e) {
194 logger.severe("Error writing file " + file + ": " + e.getMessage());
195 }
196 }
197 return this;
198 }
199
200
201
202
203 @Override
204 public List<Potential> getPotentials() {
205 List<Potential> potentials;
206 if (orthogonalSpaceTempering == null) {
207 potentials = Collections.emptyList();
208 } else {
209 potentials = Collections.singletonList(orthogonalSpaceTempering);
210 }
211 return potentials;
212 }
213
214 }