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 (17 years, 4 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 User Rev File contents
1 duarte 323 package tinker;
2 duarte 322
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 duarte 338 * 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 duarte 322 * @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     }