ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/owl/trunk/tinker/TinkerRunner.java
Revision: 338
Committed: Fri Oct 5 11:56:28 2007 UTC (16 years, 11 months ago) by duarte
File size: 14717 byte(s)
Log Message:
Initial commit of reconstruct script. Works only sometimes!! Some others doesn't run distgeom without apparent reason!
Throwing less exceptions in ConstraintsMaker
Line File contents
1 package tinker;
2
3 import java.io.BufferedReader;
4 import java.io.File;
5 import java.io.FileInputStream;
6 import java.io.FileNotFoundException;
7 import java.io.FileOutputStream;
8 import java.io.IOException;
9 import java.io.InputStreamReader;
10 import java.io.PrintWriter;
11 import java.nio.channels.FileChannel;
12 import java.util.Formatter;
13 import java.util.regex.Matcher;
14 import java.util.regex.Pattern;
15
16 public class TinkerRunner {
17
18 private static final String PROTEIN_PROG = "protein";
19 private static final String DISTGEOM_PROG = "distgeom";
20 private static final String PDBXYZ_PROG = "pdbxyz";
21 private static final String XYZPDB_PROG = "xyzpdb";
22 private static final String CYCLISE_PROTEIN_STR = "N";
23 private static final String DGEOM_PARAMS = "Y N Y Y N N A";
24 private static final String TINKER_ERROR_STR = " TINKER is Unable to Continue";
25
26 private String tinkerBinDir;
27
28 private String forceFieldFileName;
29
30 private String proteinProg;
31 private String distgeomProg;
32 private String pdbxyzProg;
33 private String xyzpdbProg;
34
35 private File logFile;
36 private PrintWriter log;
37
38 // arrays for storing distgeom output data
39 private int[] numUpperBoundViol;
40 private int[] numLowerBoundViol;
41 private double[] maxUpperBoundViol;
42 private double[] maxLowerBoundViol;
43 private double[] rmsBoundViol;
44 private int[] numUpperViol;
45 private int[] numLowerViol;
46 private double[] maxUpperViol;
47 private double[] maxLowerViol;
48 private double[] rmsRestViol;
49
50
51 /**
52 * Constructs a TinkerRunner object by passing initial parameters
53 * @param tinkerBinDir The directory where the tinker executables are
54 * @param forceFieldFileName The force field file
55 * @param logFile File where all tinker output will be logged to
56 * @throws FileNotFoundException If logFile can't be written
57 */
58 public TinkerRunner(String tinkerBinDir, String forceFieldFileName, File logFile) throws FileNotFoundException {
59 this.tinkerBinDir = tinkerBinDir;
60 this.forceFieldFileName = forceFieldFileName;
61 this.proteinProg = new File(this.tinkerBinDir,PROTEIN_PROG).getAbsolutePath();
62 this.distgeomProg = new File(this.tinkerBinDir,DISTGEOM_PROG).getAbsolutePath();
63 this.pdbxyzProg = new File(this.tinkerBinDir,PDBXYZ_PROG).getAbsolutePath();
64 this.xyzpdbProg = new File(this.tinkerBinDir,XYZPDB_PROG).getAbsolutePath();
65
66 this.logFile = logFile;
67 this.log = new PrintWriter(new FileOutputStream(logFile));
68 }
69
70 /**
71 * To get the expected File that a tinker program will output given an input file and an extension for the output files
72 * The directory where the input file is will be scanned to see if it contains files of the form basename.ext, basename.ext_2, basename.ext_3 etc.
73 * @param file
74 * @param ext
75 * @return
76 */
77 private File getTinkerOutputFileName(File file, String ext){
78 String basename = file.getName();
79 basename = basename.substring(0, basename.lastIndexOf("."));
80 String dirname = file.getParent();
81
82 String tinkerOutFileName = basename + "." + ext;
83
84 if (new File(dirname,tinkerOutFileName).exists()) {
85 int i = 2;
86 tinkerOutFileName = basename + "." + ext + "_" + i;
87 while (new File(dirname,tinkerOutFileName).exists()) {
88 i++;
89 tinkerOutFileName = basename + "." + ext + "_" + i;
90 }
91 }
92 return new File(dirname,tinkerOutFileName);
93 }
94
95 /**
96 * Runs tinker's protein program to generate an elongated protein structure given a sequence
97 * @param sequence
98 * @param outPath The directory where output files will be written
99 * @param outBasename The base name for the output files
100 * @throws IOException
101 * @throws TinkerError
102 */
103 public void runProtein(String sequence, String outPath, String outBasename) throws IOException, TinkerError {
104 boolean tinkerError = false; // to store the exit state of the tinker program
105
106 if (!new File(outPath).exists()) {
107 throw new FileNotFoundException("Specified directory "+outPath+" does not exist");
108 }
109 File tinkerxyzout = getTinkerOutputFileName(new File(outPath,outBasename+".xyz"),"xyz");
110 File tinkerintout = getTinkerOutputFileName(new File(outPath,outBasename+".int"),"int");
111 tinkerintout.deleteOnExit();
112 File tinkerseqout = getTinkerOutputFileName(new File(outPath,outBasename+".seq"),"seq");
113
114 // running protein program in outPath dir (so that output files are written to outPath)
115 Process protProc = Runtime.getRuntime().exec(proteinProg, null, new File(outPath));
116 // piping input
117 PrintWriter protInput = new PrintWriter(protProc.getOutputStream());
118 protInput.println(outBasename);
119 protInput.println("Unfolded chain created by tinker's protein program");
120 protInput.println(forceFieldFileName);
121 for (int i=0;i<sequence.length();i++) {
122 // we've got to use 3 letter code for CYS, otherwise tinker takes the default CYX (which means cystein with disulfide bridge)
123 if (sequence.charAt(i)=='C') {
124 protInput.println("CYS");
125 } else {
126 protInput.println(sequence.charAt(i));
127 }
128 }
129 protInput.println();
130 protInput.println(CYCLISE_PROTEIN_STR);
131 protInput.close();
132
133 // logging output
134 BufferedReader protOutput = new BufferedReader(new InputStreamReader(protProc.getInputStream()));
135 String line;
136 while((line = protOutput.readLine()) != null) {
137 log.println(line);
138 if (line.startsWith(TINKER_ERROR_STR)) {
139 tinkerError = true;
140 }
141 }
142
143 tinkerxyzout.renameTo(new File(outPath,outBasename+".xyz"));
144 tinkerseqout.renameTo(new File(outPath,outBasename+".seq"));
145
146 if (tinkerError) {
147 log.close();
148 throw new TinkerError("Tinker error, revise log file "+logFile.getAbsolutePath());
149 }
150 }
151
152 /**
153 * Runs tinker's distgeom program capturing output with restrain violation statistics into member variable arrays
154 * that can be retrieved using the getters: getMaxLowerBoundViol, getMaxUpperBoundViol, getMaxLowerViol etc...
155 * Two files are needed as input for distgeom: an xyz file and a key file, the latter is not passed but instead implicitely
156 * defined by xyzFile: must be in same directory and must have same basename with extension .key
157 * @param xyzFile
158 * @param outPath Directory where output files will be written
159 * @param outBasename Base name of the output files
160 * @param n Number of models that we want distgeom to produce
161 * @throws TinkerError If an error seen in tinker's output
162 * @throws IOException
163 */
164 public void runDistgeom(File xyzFile, String outPath, String outBasename, int n) throws TinkerError, IOException {
165 boolean tinkerError = false; // to store the exit state of the tinker program
166 if (!new File(outPath).exists()) {
167 throw new FileNotFoundException("Specified directory "+outPath+" does not exist");
168 }
169 if (!xyzFile.exists()){
170 throw new FileNotFoundException("Specified xyz file "+xyzFile.getAbsolutePath()+" does not exist");
171 }
172 String basename = xyzFile.getName();
173 basename = basename.substring(0, basename.lastIndexOf("."));
174 File keyFile = new File(xyzFile.getParent(),basename+".key");
175 if (! keyFile.exists()) {
176 throw new FileNotFoundException("Key file "+keyFile.getAbsolutePath()+" not present in input directory "+xyzFile.getParent());
177 }
178 // getting names of tinker output files
179 File[] tinkerout = new File[n+1];
180 for (int i=1;i<=n;i++) {
181 String ext = new Formatter().format("%03d", i).toString();
182 tinkerout[i] = getTinkerOutputFileName(xyzFile, ext);
183 }
184 // initialising arrays were we store captured output data
185 numUpperBoundViol = new int[n+1];
186 numLowerBoundViol = new int[n+1];
187 maxUpperBoundViol = new double[n+1];
188 maxLowerBoundViol = new double[n+1];
189 rmsBoundViol = new double[n+1];
190 numUpperViol = new int[n+1];
191 numLowerViol = new int[n+1];
192 maxUpperViol = new double[n+1];
193 maxLowerViol = new double[n+1];
194 rmsRestViol = new double[n+1];
195 // running distgeom program
196 Process dgeomProc = Runtime.getRuntime().exec(distgeomProg+" "+xyzFile.getAbsolutePath()+" "+n+" "+DGEOM_PARAMS);
197 // logging and capturing output
198 BufferedReader dgeomOutput = new BufferedReader(new InputStreamReader(dgeomProc.getInputStream()));
199 String line;
200 int i=1;
201 while((line = dgeomOutput.readLine()) != null) {
202 log.println(line);
203 if (line.startsWith(TINKER_ERROR_STR)) {
204 tinkerError = true;
205 }
206 Pattern p = Pattern.compile("^ Num Upper Bound Violations :\\s+(\\d+)");
207 Matcher m = p.matcher(line);
208 if (m.find()) {
209 numUpperBoundViol[i]=Integer.parseInt(m.group(1));
210 }
211 p = Pattern.compile("^ Num Lower Bound Violations :\\s+(\\d+)");
212 m = p.matcher(line);
213 if (m.find()) {
214 numLowerBoundViol[i]=Integer.parseInt(m.group(1));
215 }
216 p = Pattern.compile("^ Max Upper Bound Violation :\\s+(\\d+\\.\\d\\d\\d\\d)");
217 m = p.matcher(line);
218 if (m.find()) {
219 maxUpperBoundViol[i]=Double.parseDouble(m.group(1));
220 }
221 p = Pattern.compile("^ Max Lower Bound Violation :\\s+(\\d+\\.\\d\\d\\d\\d)");
222 m = p.matcher(line);
223 if (m.find()) {
224 maxLowerBoundViol[i]=Double.parseDouble(m.group(1));
225 }
226 p = Pattern.compile("^ RMS Deviation from Bounds :\\s+(\\d+\\.\\d\\d\\d\\d)");
227 m = p.matcher(line);
228 if (m.find()) {
229 rmsBoundViol[i]=Double.parseDouble(m.group(1));
230 }
231 p = Pattern.compile("^ Num Upper Restraint Violations :\\s+(\\d+)");
232 m = p.matcher(line);
233 if (m.find()) {
234 numUpperViol[i]=Integer.parseInt(m.group(1));
235 }
236 p = Pattern.compile("^ Num Lower Restraint Violations :\\s+(\\d+)");
237 m = p.matcher(line);
238 if (m.find()) {
239 numLowerViol[i]=Integer.parseInt(m.group(1));
240 }
241 p = Pattern.compile("^ Max Upper Restraint Violation :\\s+(\\d+\\.\\d\\d\\d\\d)");
242 m = p.matcher(line);
243 if (m.find()) {
244 maxUpperViol[i]=Double.parseDouble(m.group(1));
245 }
246 p = Pattern.compile("^ Max Lower Restraint Violation :\\s+(\\d+\\.\\d\\d\\d\\d)");
247 m = p.matcher(line);
248 if (m.find()) {
249 maxLowerViol[i]=Double.parseDouble(m.group(1));
250 }
251 p = Pattern.compile("^ RMS Restraint Dist Violation :\\s+(\\d+\\.\\d\\d\\d\\d)");
252 m = p.matcher(line);
253 if (m.find()) {
254 rmsRestViol[i]=Double.parseDouble(m.group(1));
255 i++;
256 }
257 }
258 //renaming files to our chosen outBasename+ext
259 for (i=1;i<=n;i++) {
260 String ext = new Formatter().format("%03d", i).toString();
261 tinkerout[i].renameTo(new File(outPath,outBasename+"."+ext));
262 }
263 // throwing exception if error string was caught in output
264 if (tinkerError) {
265 log.close();
266 throw new TinkerError("Tinker error, revise log file "+logFile.getAbsolutePath());
267 }
268
269 }
270
271 /**
272 * Runs tinker's xyzpdb program to convert a given xyzFile (needing also a seqFile) to a pdbFile
273 * @param xyzFile
274 * @param seqFile
275 * @param pdbFile
276 * @throws IOException
277 * @throws TinkerError If an error seen in tinker's output
278 */
279 public void runXyzpdb(File xyzFile, File seqFile, File pdbFile) throws IOException, TinkerError {
280 boolean tinkerError = false; // to store the exit state of the tinker program
281 if (!xyzFile.exists()){
282 throw new FileNotFoundException("Specified xyz file "+xyzFile.getAbsolutePath()+" does not exist");
283 }
284 if (!seqFile.exists()){
285 throw new FileNotFoundException("Specified seq file "+seqFile.getAbsolutePath()+" does not exist");
286 }
287
288 String basename = xyzFile.getName();
289 basename = basename.substring(0, basename.lastIndexOf("."));
290 File tmpSeqFile = new File(seqFile.getParent(),basename+".seq");
291
292 // if seqFile doesn't follow the naming convention (basename of xyzFile+seq extension) that tinker expects, we copy it to tmpSeqFile (which has right name)
293 if (!tmpSeqFile.equals(seqFile)) {
294 FileChannel srcChannel = new FileInputStream(seqFile).getChannel();
295 FileChannel dstChannel = new FileOutputStream(tmpSeqFile).getChannel();
296 dstChannel.transferFrom(srcChannel, 0, srcChannel.size());
297 srcChannel.close();
298 dstChannel.close();
299 // if we copied then that means tmpSeqFile is different from seqFile and thus we want to delete the tmp file on exit
300 tmpSeqFile.deleteOnExit();
301 }
302
303 File tinkerpdbout = getTinkerOutputFileName(xyzFile, "pdb");
304
305 // running tinker's xyzpdb
306 // beware: it takes as a silent input the seq file seqFile (or tmpSeqFile if the input seqFile didn't have the right name)
307 Process xyzpdbProc = Runtime.getRuntime().exec(xyzpdbProg+" "+xyzFile.getAbsolutePath()+" "+forceFieldFileName);
308
309 // logging output
310 BufferedReader xyzpdbOutput = new BufferedReader(new InputStreamReader(xyzpdbProc.getInputStream()));
311 String line;
312 while((line = xyzpdbOutput.readLine()) != null) {
313 log.println(line);
314 if (line.startsWith(TINKER_ERROR_STR)) {
315 tinkerError = true;
316 }
317 }
318
319 tinkerpdbout.renameTo(pdbFile);
320
321 if (tinkerError) {
322 log.close();
323 throw new TinkerError("Tinker error, revise log file "+logFile.getAbsolutePath());
324 }
325 }
326
327 /**
328 * Runs tinker's pdbxyz program to convert a pdbFile to a xyzFile
329 * @param pdbFile
330 * @param xyzFile
331 * @throws IOException
332 * @throws TinkerError If an error seen in tinker's output
333 */
334 public void runPdbxyz(File pdbFile, File xyzFile) throws IOException, TinkerError{
335 boolean tinkerError = false; // to store the exit state of the tinker program
336 if (!pdbFile.exists()){
337 throw new FileNotFoundException("Specified pdb file "+pdbFile.getAbsolutePath()+" does not exist");
338 }
339 File tinkerxyzout = getTinkerOutputFileName(pdbFile, "xyz");
340 // running tinker's pdbxyz
341 Process pdbxyzProc = Runtime.getRuntime().exec(pdbxyzProg+" "+pdbFile.getAbsolutePath()+" "+forceFieldFileName);
342
343 // logging output
344 BufferedReader pdbxyzOutput = new BufferedReader(new InputStreamReader(pdbxyzProc.getInputStream()));
345 String line;
346 while((line = pdbxyzOutput.readLine()) != null) {
347 log.println(line);
348 if (line.startsWith(TINKER_ERROR_STR)) {
349 tinkerError = true;
350 }
351 }
352 tinkerxyzout.renameTo(xyzFile);
353 if (tinkerError) {
354 log.close();
355 throw new TinkerError("Tinker error, revise log file "+logFile.getAbsolutePath());
356 }
357 }
358
359 /**
360 * Closes log stream, must be called after no other tinker program will be run with this TinkerRunner object
361 * (otherwise log is not flushed to file)
362 */
363 public void closeLog() {
364 log.close();
365 }
366
367 public double[] getMaxLowerBoundViol() {
368 return maxLowerBoundViol;
369 }
370
371 public double[] getMaxLowerViol() {
372 return maxLowerViol;
373 }
374
375 public double[] getMaxUpperBoundViol() {
376 return maxUpperBoundViol;
377 }
378
379 public double[] getMaxUpperViol() {
380 return maxUpperViol;
381 }
382
383 public int[] getNumLowerBoundViol() {
384 return numLowerBoundViol;
385 }
386
387 public int[] getNumLowerViol() {
388 return numLowerViol;
389 }
390
391 public int[] getNumUpperBoundViol() {
392 return numUpperBoundViol;
393 }
394
395 public int[] getNumUpperViol() {
396 return numUpperViol;
397 }
398
399 public double[] getRmsBoundViol() {
400 return rmsBoundViol;
401 }
402
403 public double[] getRmsRestViol() {
404 return rmsRestViol;
405 }
406 }