| 
8
 | 
     1 #!/usr/bin/env python
 | 
| 
 | 
     2 """A simple wrapper script to call MIRA and collect its output.
 | 
| 
 | 
     3 """
 | 
| 
 | 
     4 import os
 | 
| 
 | 
     5 import sys
 | 
| 
 | 
     6 import subprocess
 | 
| 
 | 
     7 import shutil
 | 
| 
 | 
     8 import time
 | 
| 
 | 
     9 
 | 
| 
 | 
    10 WRAPPER_VER = "0.0.5" #Keep in sync with the XML file
 | 
| 
 | 
    11 
 | 
| 
 | 
    12 def stop_err(msg, err=1):
 | 
| 
 | 
    13     sys.stderr.write(msg+"\n")
 | 
| 
 | 
    14     sys.exit(err)
 | 
| 
 | 
    15 
 | 
| 
 | 
    16 
 | 
| 
 | 
    17 def get_version():
 | 
| 
 | 
    18     """Run MIRA to find its version number"""
 | 
| 
 | 
    19     # At the commend line I would use: mira -v | head -n 1
 | 
| 
 | 
    20     # however there is some pipe error when doing that here.
 | 
| 
 | 
    21     try:
 | 
| 
 | 
    22         child = subprocess.Popen(["mira", "-v"],
 | 
| 
 | 
    23                                  stdout=subprocess.PIPE,
 | 
| 
 | 
    24                                  stderr=subprocess.STDOUT)
 | 
| 
 | 
    25     except Exception, err:
 | 
| 
 | 
    26         sys.stderr.write("Error invoking command:\n%s\n\n%s\n" % (" ".join(cmd), err))
 | 
| 
 | 
    27         sys.exit(1)
 | 
| 
 | 
    28     ver, tmp = child.communicate()
 | 
| 
 | 
    29     del child
 | 
| 
 | 
    30     return ver.split("\n", 1)[0]
 | 
| 
 | 
    31 
 | 
| 
 | 
    32 
 | 
| 
 | 
    33 mira_ver = get_version()
 | 
| 
 | 
    34 if "V3.4." not in mira_ver:
 | 
| 
 | 
    35     stop_err("This wrapper is for MIRA V3.4, not %s" % mira_ver)
 | 
| 
 | 
    36 if "-v" in sys.argv:
 | 
| 
 | 
    37     print "MIRA wrapper version %s," % WRAPPER_VER
 | 
| 
 | 
    38     print mira_ver
 | 
| 
 | 
    39     sys.exit(0)
 | 
| 
 | 
    40 
 | 
| 
 | 
    41 
 | 
| 
 | 
    42 def collect_output(temp, name):
 | 
| 
 | 
    43     n3 = (temp, name, name, name)
 | 
| 
 | 
    44     f = "%s/%s_assembly/%s_d_results" % (temp, name, name)
 | 
| 
 | 
    45     if not os.path.isdir(f):
 | 
| 
 | 
    46         stop_err("Missing output folder")
 | 
| 
 | 
    47     if not os.listdir(f):
 | 
| 
 | 
    48         stop_err("Empty output folder")
 | 
| 
 | 
    49     missing = []
 | 
| 
 | 
    50     for old, new in [("%s/%s_out.unpadded.fasta" % (f, name), out_fasta),
 | 
| 
 | 
    51                      ("%s/%s_out.unpadded.fasta.qual" % (f, name), out_qual),
 | 
| 
 | 
    52                      ("%s/%s_out.wig" % (f, name), out_wig),
 | 
| 
 | 
    53                      ("%s/%s_out.caf" % (f, name), out_caf),
 | 
| 
 | 
    54                      ("%s/%s_out.ace" % (f, name), out_ace)]:
 | 
| 
 | 
    55         if not os.path.isfile(old):
 | 
| 
 | 
    56             missing.append(os.path.splitext(old)[-1])
 | 
| 
 | 
    57         else:
 | 
| 
 | 
    58             shutil.move(old, new)
 | 
| 
 | 
    59     if missing:
 | 
| 
 | 
    60         stop_err("Missing output files: %s" % ", ".join(missing))
 | 
| 
 | 
    61 
 | 
| 
 | 
    62 def clean_up(temp, name):
 | 
| 
 | 
    63     folder = "%s/%s_assembly" % (temp, name)
 | 
| 
 | 
    64     if os.path.isdir(folder):
 | 
| 
 | 
    65         shutil.rmtree(folder)
 | 
| 
 | 
    66 
 | 
| 
 | 
    67 #TODO - Run MIRA in /tmp or a configurable directory?
 | 
| 
 | 
    68 #Currently Galaxy puts us somewhere safe like:
 | 
| 
 | 
    69 #/opt/galaxy-dist/database/job_working_directory/846/
 | 
| 
 | 
    70 temp = "."
 | 
| 
 | 
    71 name, out_fasta, out_qual, out_ace, out_caf, out_wig, out_log = sys.argv[1:8]
 | 
| 
 | 
    72 
 | 
| 
 | 
    73 start_time = time.time()
 | 
| 
 | 
    74 cmd_list =sys.argv[8:]
 | 
| 
 | 
    75 cmd = " ".join(cmd_list)
 | 
| 
 | 
    76 
 | 
| 
 | 
    77 assert os.path.isdir(temp)
 | 
| 
 | 
    78 d = "%s_assembly" % name
 | 
| 
 | 
    79 assert not os.path.isdir(d), "Path %s already exists" % d
 | 
| 
 | 
    80 try:
 | 
| 
 | 
    81     #Check path access
 | 
| 
 | 
    82     os.mkdir(d)
 | 
| 
 | 
    83 except Exception, err:
 | 
| 
 | 
    84     sys.stderr.write("Error making directory %s\n%s" % (d, err))
 | 
| 
 | 
    85     sys.exit(1)
 | 
| 
 | 
    86 
 | 
| 
 | 
    87 #print os.path.abspath(".")
 | 
| 
 | 
    88 #print cmd
 | 
| 
 | 
    89 
 | 
| 
 | 
    90 handle = open(out_log, "w")
 | 
| 
 | 
    91 try:
 | 
| 
 | 
    92     #Run MIRA
 | 
| 
 | 
    93     child = subprocess.Popen(cmd_list,
 | 
| 
 | 
    94                              stdout=handle,
 | 
| 
 | 
    95                              stderr=subprocess.STDOUT)
 | 
| 
 | 
    96 except Exception, err:
 | 
| 
 | 
    97     sys.stderr.write("Error invoking command:\n%s\n\n%s\n" % (cmd, err))
 | 
| 
 | 
    98     #TODO - call clean up?
 | 
| 
 | 
    99     handle.write("Error invoking command:\n%s\n\n%s\n" % (cmd, err))
 | 
| 
 | 
   100     handle.close()
 | 
| 
 | 
   101     sys.exit(1)
 | 
| 
 | 
   102 #Use .communicate as can get deadlocks with .wait(),
 | 
| 
 | 
   103 stdout, stderr = child.communicate()
 | 
| 
 | 
   104 assert not stdout and not stderr #Should be empty as sent to handle
 | 
| 
 | 
   105 run_time = time.time() - start_time
 | 
| 
 | 
   106 return_code = child.returncode
 | 
| 
 | 
   107 handle.write("\n\nMIRA took %0.2f minutes\n" % (run_time / 60.0))
 | 
| 
 | 
   108 print "MIRA took %0.2f minutes" % (run_time / 60.0)
 | 
| 
 | 
   109 if return_code:
 | 
| 
 | 
   110     handle.write("Return error code %i from command:\n" % return_code)
 | 
| 
 | 
   111     handle.write(cmd + "\n")
 | 
| 
 | 
   112     handle.close()
 | 
| 
 | 
   113     clean_up(temp, name)
 | 
| 
 | 
   114     stop_err("Return error code %i from command:\n%s" % (return_code, cmd),
 | 
| 
 | 
   115              return_code)
 | 
| 
 | 
   116 handle.close()
 | 
| 
 | 
   117 
 | 
| 
 | 
   118 #print "Collecting output..."
 | 
| 
 | 
   119 collect_output(temp, name)
 | 
| 
 | 
   120 
 | 
| 
 | 
   121 #print "Cleaning up..."
 | 
| 
 | 
   122 clean_up(temp, name)
 | 
| 
 | 
   123 
 | 
| 
 | 
   124 print "Done"
 |