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.commands;
39
40 import ffx.potential.bonded.Atom;
41 import ffx.potential.cli.PotentialCommand;
42 import ffx.potential.cli.SaveOptions;
43 import ffx.potential.extended.ExtendedSystem;
44 import ffx.potential.parsers.PDBFilter;
45 import ffx.potential.parsers.SystemFilter;
46 import ffx.potential.parsers.XPHFilter;
47 import ffx.potential.parsers.XYZFilter;
48 import ffx.utilities.FFXBinding;
49 import picocli.CommandLine.Command;
50 import picocli.CommandLine.Mixin;
51 import picocli.CommandLine.Option;
52 import picocli.CommandLine.Parameters;
53
54 import java.io.File;
55 import java.io.IOException;
56 import java.nio.file.Files;
57 import java.nio.file.StandardOpenOption;
58
59 import static java.nio.file.StandardOpenOption.APPEND;
60 import static java.nio.file.StandardOpenOption.CREATE;
61 import static org.apache.commons.io.FilenameUtils.concat;
62 import static org.apache.commons.io.FilenameUtils.getName;
63 import static org.apache.commons.io.FilenameUtils.removeExtension;
64
65
66
67
68
69
70
71 @Command(name = "SaveAsPDB", description = " Save the system as a PDB file.")
72 public class SaveAsPDB extends PotentialCommand {
73
74 @Mixin
75 private SaveOptions saveOptions = new SaveOptions();
76
77
78 @Option(names = {"--fs", "--firstSnapshot"}, paramLabel = "-1", defaultValue = "-1",
79 description = "First snapshot to write out (indexed from 0).")
80 private int firstSnapshot = -1;
81
82
83 @Option(names = {"--ls", "--lastSnapshot"}, paramLabel = "-1", defaultValue = "-1",
84 description = "Last snapshot to write out (indexed from 0).")
85 private int lastSnapshot = -1;
86
87
88 @Option(names = {"--si", "--snapshotIncrement"}, paramLabel = "1", defaultValue = "1",
89 description = "Increment between written snapshots.")
90 private int snapshotIncrement = 1;
91
92
93 @Option(names = {"--wd", "--writeToDirectories"}, paramLabel = "false", defaultValue = "false",
94 description = "Write snapshots to numbered subdirectories.")
95 private boolean writeToDirectories = false;
96
97
98 @Option(names = {"--cp", "--copyProperties"}, paramLabel = "true", defaultValue = "true",
99 description = "Copy the property file to numbered subdirectories (ignored if not writing to subdirectories).")
100 private boolean copyProperties = true;
101
102
103 @Option(names = {"--esv"}, paramLabel = "file", defaultValue = "",
104 description = "PDB file to build extended system from.")
105 private String extended = "";
106
107
108 @Parameters(arity = "1", paramLabel = "file",
109 description = "The atomic coordinate file in XYZ or ARC format.")
110 private String filename = null;
111
112 public SaveAsPDB() { super(); }
113 public SaveAsPDB(FFXBinding binding) { super(binding); }
114 public SaveAsPDB(String[] args) { super(args); }
115
116 @Override
117 public SaveAsPDB run() {
118 if (!init()) {
119 return this;
120 }
121
122
123 activeAssembly = getActiveAssembly(filename);
124 if (activeAssembly == null) {
125 logger.info(helpString());
126 return this;
127 }
128
129
130 filename = activeAssembly.getFile().getAbsolutePath();
131 SystemFilter openFilter = potentialFunctions.getFilter();
132 ExtendedSystem esvSystem = null;
133
134 if (openFilter instanceof XYZFilter && extended != null && !extended.isEmpty()) {
135 logger.info(" Building extended system from " + extended);
136
137 activeAssembly = getActiveAssembly(extended);
138 esvSystem = new ExtendedSystem(activeAssembly, 7.4, null);
139
140 activeAssembly.setFile(new File(filename));
141 openFilter = new XPHFilter(activeAssembly.getFile(), activeAssembly, activeAssembly.getForceField(),
142 activeAssembly.getProperties(), esvSystem);
143 openFilter.readFile();
144 logger.info(" Reading ESV lambdas from XPH file");
145 }
146
147 logger.info("\n Saving PDB for " + filename);
148
149
150 String dirString = getBaseDirString(filename);
151
152 String name = removeExtension(getName(filename)) + ".pdb";
153 File saveFile = new File(dirString + name);
154
155 if (firstSnapshot >= 0) {
156
157 PDBFilter snapshotFilter = new PDBFilter(saveFile, activeAssembly,
158 activeAssembly.getForceField(), activeAssembly.getProperties());
159 openFilter.readNext(true);
160 boolean resetPosition = true;
161 int counter = 0;
162 int snapshotCounter = 0;
163 logger.info(" Writing snapshots from " + firstSnapshot + " to " + lastSnapshot + " with increment " + snapshotIncrement);
164
165 while (openFilter.readNext(resetPosition)) {
166
167 resetPosition = false;
168 int offset = counter - firstSnapshot;
169 if (counter >= firstSnapshot && (lastSnapshot < 0 || counter <= lastSnapshot) && offset % snapshotIncrement == 0) {
170 File snapshotFile;
171 if (writeToDirectories) {
172 String subdirectory = concat(dirString, Integer.toString(snapshotCounter));
173 snapshotFile = new File(concat(subdirectory, name));
174
175
176 new File(subdirectory).mkdirs();
177 if (copyProperties) {
178 String propertyFile = activeAssembly.getProperties().getString("propertyFile");
179 if (propertyFile != null) {
180 File copyOfPropFile = new File(concat(subdirectory, getName(propertyFile)));
181 try {
182 Files.createDirectories(copyOfPropFile.getParentFile().toPath());
183 Files.copy(new File(propertyFile).toPath(), copyOfPropFile.toPath(), java.nio.file.StandardCopyOption.REPLACE_EXISTING);
184 } catch (IOException e) {
185 logger.info(" Could not copy properties file: " + e.getMessage());
186 }
187 }
188 }
189 } else {
190 snapshotFile = new File(concat(dirString,
191 removeExtension(name) + "." + counter + ".pdb"));
192 }
193 potentialFunctions.versionFile(snapshotFile);
194 saveOptions.preSaveOperations(activeAssembly);
195 logger.info(" Saving PDB to " + snapshotFile);
196 snapshotFilter.writeFile(snapshotFile, true, false, false);
197 try {
198 Files.writeString(snapshotFile.toPath(), "END\n", APPEND, CREATE);
199 } catch (IOException e) { }
200 snapshotCounter++;
201 }
202 counter++;
203 }
204 return this;
205 }
206
207
208 saveFile = potentialFunctions.versionFile(saveFile);
209
210 int numModels = openFilter.countNumModels();
211 if (numModels == 1) {
212
213 saveOptions.preSaveOperations(activeAssembly);
214 potentialFunctions.saveAsPDB(activeAssembly, saveFile);
215 return this;
216 }
217
218
219 try {
220 Files.writeString(saveFile.toPath(), "MODEL 1\n");
221 } catch (IOException e) { }
222 saveOptions.preSaveOperations(activeAssembly);
223 potentialFunctions.saveAsPDB(activeAssembly, saveFile, false, true);
224 try {
225 Files.writeString(saveFile.toPath(), "ENDMDL\n", APPEND, CREATE);
226 } catch (IOException e) { }
227
228 PDBFilter saveFilter = (PDBFilter) potentialFunctions.getFilter();
229 saveFilter.setModelNumbering(1);
230
231
232 if (openFilter instanceof XYZFilter || openFilter instanceof PDBFilter || openFilter instanceof XPHFilter) {
233 try {
234 while (openFilter.readNext(false)) {
235 if (esvSystem != null) {
236 for (Atom atom : activeAssembly.getAtomList()) {
237 int atomIndex = atom.getIndex() - 1;
238 atom.setOccupancy(esvSystem.getTitrationLambda(atomIndex));
239 atom.setTempFactor(esvSystem.getTautomerLambda(atomIndex));
240 }
241 }
242 saveOptions.preSaveOperations(activeAssembly);
243 saveFilter.writeFile(saveFile, true, true, false);
244 }
245 } catch (Exception e) {
246
247 }
248
249 try {
250 Files.writeString(saveFile.toPath(), "END\n", APPEND, CREATE);
251 } catch (IOException e) { }
252 }
253 return this;
254 }
255 }