d933b800c9018384629817a32a2f3bce60a2eb25
[htsworkflow.git] / scripts / htsw-srf
1 #!/usr/bin/python
2 from __future__ import print_function, unicode_literals
3
4 import logging
5 import optparse
6 import os
7 import sys
8
9 from htsworkflow.pipelines import runfolder
10 from htsworkflow.pipelines.srf import make_srf_commands, make_qseq_commands, \
11                                       run_commands, pathname_to_run_name
12 from htsworkflow.pipelines.srf import ILLUMINA2SRF10, ILLUMINA2SRF11, SOLEXA2SRF
13
14 def make_parser():
15   usage = '%prog: [options] runfolder -l 1,2,3 [runfolder -l 5,6 ...]'
16
17   parser = optparse.OptionParser(usage)
18   parser.add_option('--dry-run', action='store_true',
19                     help='print what would be done',
20                     default=False)
21
22   parser.add_option('-d', '--dest-dir', dest='dest_dir',
23                     help='location to write srf files to',
24                     default='.')
25   parser.add_option('-s', '--site',
26                     help='site name',
27                     default='Individual')
28   parser.add_option('-l', '--lanes', dest='lanes', action="append",
29          default=[],
30          help='comma seperated list of lanes to add to srf'
31   )
32   parser.add_option('-j', '--jobs', default=1, type='int',
33                     help='how many jobs to run simultaneously')
34   parser.add_option('-r', '--runfolder-version', default=ILLUMINA2SRF11, type='int',
35                     help='Which class of srf file should we attempt to create\n'
36                          '0 = Solexa pipeline 0.2.6 - 0.3\n'
37                          '1 = illumina pipeline 1.0\n'
38                          '2 = illumina pipeline 1.1rc1 and later \n')
39                      
40   parser.add_option('-v', '--verbose', dest='verbose',
41                     default=False, action='store_true',
42                     help='report more about internals (INFO)')
43   parser.add_option('--debug', dest='debug',
44                     default=False, action='store_true',
45                     help='report even more about internals (DEBUG)')
46  
47   return parser
48
49 def parse_lane_arg(lane_arg):
50     """
51     Convert comma sperated list of lane ids to a list of integers
52     """
53     lanes = []
54     for lane in lane_arg.split(','):
55         try:
56             lane = int(lane)
57             if lane < 1 or lane > 8:
58                 parser.error('Lanes must be in range [1..8]')
59             lanes.append(lane)
60         except ValueError:
61             parser.error('Lane selections must be integers')
62     return lanes
63
64 def main(cmdline=None):
65     parser = make_parser()
66     opts, args = parser.parse_args(cmdline)
67    
68     if opts.debug: 
69         logging.basicConfig(level=logging.DEBUG)
70     elif opts.verbose:
71         logging.basicConfig(level=logging.INFO)
72     else:
73         logging.basicConfig(level=logging.WARNING)
74
75     if len(args) == 0:
76         parser.error('need runfolder arguments')
77
78     # parse lane arguemnts
79     lanes_list = []
80     if len(opts.lanes) == 0:
81         lanes_list = [[1,2,3,4,5,6,7,8]] * len(args)
82     elif len(opts.lanes) == len(args):
83         for lane_arg in opts.lanes:
84             lanes_list.append(parse_lane_arg(lane_arg))
85     else:
86         parser.error(
87           "Number of lane arguments must match number of runfolders"
88         )
89
90     make_commands = make_qseq_commands
91     # build list of commands
92     cmds = {}
93     for runfolder_path, lanes in zip(args, lanes_list):
94         # normalize paths, either relative to home dirs or current dir
95         runfolder_path = os.path.abspath(runfolder_path)
96         run_name = pathname_to_run_name(runfolder_path)
97         # so any bustard directories?
98         runs = runfolder.get_runs(runfolder_path)
99         # give up if there are anything other than 1 run
100         if len(runs) > 1:
101           print 'ERROR: Too many run directories in %s' %(runfolder_path,)
102           return 1
103         elif len(runs) == 1:
104           bustard_dir = runs[0].bustard.pathname
105           cmds[bustard_dir] = make_commands(run_name,
106                                             bustard_dir,
107                                             lanes,
108                                             opts.site,
109                                             opts.dest_dir,
110                                             opts.runfolder_version)
111         else:
112           print "ERROR: Couldn't find a bustard directory in", runfolder_path
113           return 1
114
115     if not opts.dry_run:
116       for cwd, cmd_list in cmds.items():
117         run_commands(cwd, cmd_list, opts.jobs)
118     else:
119       for cwd, cmd_list in cmds.items():
120         print(cwd)
121         print(cmd_list)
122         print('jobs: ', opts.jobs)
123
124     return 0
125
126 if __name__ == "__main__":
127     sys.exit(main(sys.argv[1:]))