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.numerics.Potential;
42 import ffx.potential.Utilities;
43 import ffx.potential.parsers.BARFilter;
44 import ffx.utilities.FFXCommand;
45 import ffx.utilities.FFXBinding;
46 import picocli.CommandLine.Command;
47 import picocli.CommandLine.Option;
48 import picocli.CommandLine.Parameters;
49
50 import java.io.BufferedReader;
51 import java.io.File;
52 import java.io.FileReader;
53 import java.io.IOException;
54 import java.util.ArrayList;
55 import java.util.Collections;
56 import java.util.List;
57 import java.util.regex.Matcher;
58 import java.util.regex.Pattern;
59
60 import static ffx.utilities.FileUtils.traverseFiles;
61 import static java.lang.String.format;
62 import static org.apache.commons.io.FilenameUtils.getBaseName;
63 import static org.apache.commons.io.FilenameUtils.normalize;
64
65
66
67
68
69
70
71
72
73 @Command(description = "Performs analysis of Non-equilibrium work simulations.", name = "AnalyzeNEQ")
74 public class AnalyzeNEQ extends AlgorithmsCommand {
75
76
77
78
79 @Option(names = {"--reFile", "--fileSelectionRegex"}, paramLabel = "work.log", defaultValue = "work.log",
80 description = "Locate files that match a regular expression.")
81 private String reFile;
82
83
84
85
86 @Option(names = {"--reSearch", "--fileSearchRegex"}, paramLabel = "Boole", defaultValue = "Boole",
87 description = "Locate this regular expression in log files.")
88 private String reSearch;
89
90
91
92
93 @Option(names = {"--bi", "--barIterations"}, paramLabel = "100", defaultValue = "100",
94 description = "Maximum iterations for BAR calculation.")
95 private int barIterations;
96
97
98
99
100 @Parameters(arity = "2", paramLabel = "path",
101 description = "Two paths to directories. The first to the forward work directory and second to the reverse work directory.")
102 private List<String> directories = null;
103
104
105
106
107 public AnalyzeNEQ() {
108 super();
109 }
110
111
112
113
114
115
116 public AnalyzeNEQ(FFXBinding binding) {
117 super(binding);
118 }
119
120
121
122
123
124
125 public AnalyzeNEQ(String[] args) {
126 super(args);
127 }
128
129
130
131
132 @Override
133 public AnalyzeNEQ run() {
134
135 if (!init()) {
136 return this;
137 }
138
139 int recurse = 1;
140
141 String forwardDir = directories.get(0);
142 String reverseDir = directories.get(1);
143
144
145 File fdir = new File(forwardDir);
146 List<File> ffiles = traverseFiles(fdir, recurse, reFile);
147 double[] fworks = grabWorks(ffiles);
148
149
150 File rdir = new File(reverseDir);
151 List<File> rfiles = traverseFiles(rdir, recurse, reFile);
152 double[] rworks = grabWorks(rfiles);
153
154
155 String outputName = getBaseName(fdir.getName()) + "-" + getBaseName(rdir.getName()) + ".bar";
156
157 File barFile = new File(".", "this.xyz");
158 double temp = 300.0;
159 BARFilter barFilter = new BARFilter(barFile, new double[fworks.length], fworks, rworks, new double[rworks.length],
160 new double[3], new double[3], temp, temp);
161 barFilter.writeFile(outputName, false, false);
162
163
164 List<String> commandArgs = new ArrayList<>();
165
166
167 commandArgs.add("--ns");
168 commandArgs.add("2");
169 commandArgs.add("--ni");
170 commandArgs.add(Integer.toString(barIterations));
171 commandArgs.add("--useTinker");
172 commandArgs.add("--bf");
173 commandArgs.add(outputName);
174
175
176
177
178 FFXBinding binding = new FFXBinding();
179 binding.setVariable("args", commandArgs);
180
181 Class<? extends FFXCommand> script;
182 script = getCommand("BAR");
183
184
185 try {
186 FFXCommand command = script.getDeclaredConstructor().newInstance();
187 command.setBinding(binding);
188 command.run();
189 } catch (Exception e) {
190 logger.info(" Exception running BAR.");
191 logger.info(e.toString());
192 logger.info(Utilities.stackTraceToString(e));
193 }
194
195 return this;
196 }
197
198
199
200
201
202
203
204 private double[] grabWorks(List<File> files) {
205
206 Collections.sort(files);
207
208 int numFiles = files.size();
209 List<Double> works = new ArrayList<>();
210
211
212 Pattern workRegEx = Pattern.compile(reSearch);
213
214 for (int i = 0; i < numFiles; i++) {
215 File file = files.get(i);
216 if (!file.exists()) {
217 logger.info(format(" Ignoring file that does not exist: %s", file.getAbsolutePath()));
218 continue;
219 }
220
221 String path = normalize(file.getAbsolutePath());
222 try (BufferedReader reader = new BufferedReader(new FileReader(path))) {
223 String line;
224
225 while ((line = reader.readLine()) != null) {
226 Matcher matcher = workRegEx.matcher(line);
227 if (matcher.find()) {
228 String[] workSplit = line.trim().split("\\s+");
229 if (!(workSplit.length == 4 || workSplit.length == 5)) {
230 logger.warning(format("%s line is NOT length four or five: \"%s\"", reSearch, line));
231 continue;
232 }
233 works.add(Double.parseDouble(workSplit[workSplit.length - 1]));
234 }
235 }
236
237 } catch (IOException e) {
238 System.err.println("Error reading file: " + e.getMessage());
239 }
240 }
241
242
243 double[] result = new double[works.size()];
244 for (int i = 0; i < works.size(); i++) {
245 result[i] = works.get(i);
246 }
247 return result;
248 }
249
250
251
252
253 @Override
254 public List<Potential> getPotentials() {
255 return Collections.emptyList();
256 }
257 }