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