Use a logger initialized to the module name much more consistently.
[htsworkflow.git] / scripts / htsw-runfolder
1 #!/usr/bin/env python
2 """
3 Runfolder.py can generate a xml file capturing all the 'interesting' parameters from a finished pipeline run. (using the -a option). The information currently being captured includes:
4
5   * Flowcell ID
6   * run dates
7   * start/stop cycle numbers
8   * Firecrest, bustard, gerald version numbers
9   * Eland analysis types, and everything in the eland configuration file.
10   * cluster numbers and other values from the Summary.htm
11     LaneSpecificParameters table.
12   * How many reads mapped to a genome from an eland file
13
14 The ELAND "mapped reads" counter will also check for eland squashed file
15 that were symlinked from another directory. This is so I can track how
16 many reads landed on the genome of interest and on the spike ins.
17
18 Basically my subdirectories something like:
19
20 genomes/hg18
21 genomes/hg18/chr*.2bpb <- files for hg18 genome
22 genomes/hg18/chr*.vld
23 genomes/hg18/VATG.fa.2bp <- symlink to genomes/spikeins
24 genomes/spikein
25
26 runfolder.py can also spit out a simple summary report (-s option)
27 that contains the per lane post filter cluster numbers and the mapped
28 read counts. (The report isn't currently very pretty)
29 """
30 from glob import glob
31 import logging
32 import optparse
33 import os
34 import sys
35
36 from htsworkflow.pipelines import runfolder
37 from htsworkflow.pipelines.runfolder import ElementTree
38
39 LOGGER = logging.getLogger(__name__)
40
41 def make_parser():
42     usage = 'usage: %prog [options] runfolder_root_dir'
43     parser = optparse.OptionParser(usage)
44
45     parser.add_option('-v', '--verbose', dest='verbose', action='store_true',
46                       default=False,
47                       help='turn on verbose mode')
48     parser.add_option('--dry-run', action='store_true', default=False,
49                       help="Don't delete anything (in clean mode)")
50
51     commands = optparse.OptionGroup(parser, 'Commands')
52
53     commands.add_option('-s', '--summary', dest='summary', action='store_true',
54                         default=False,
55                         help='produce summary report')
56     commands.add_option('-a', '--archive', dest='archive', action='store_true',
57                         default=False,
58                         help='generate run configuration archive')
59     commands.add_option('--extract-results', action='store_true',
60            default=False,
61            help='create run-xml summary, compress the eland result files, build srf files and '
62                 'copy all that and the Summary.htm file into an archival directory.')
63     commands.add_option('-c', '--clean', action='store_true', default=False,
64                         help='Clean runfolder, preparing it for long-term storage')
65     parser.add_option_group(commands)
66
67     parser.add_option('-j', '--max-jobs', default=1,
68                       help='sepcify the maximum number of processes to run '
69                            '(used in extract-results)')
70     parser.add_option('-o', '--output-dir', default=None,
71            help="specify the default output directory for extract results")
72     parser.add_option('--run-xml', dest='run_xml',
73            default=None,
74            help='specify a run_<FlowCell>.xml file for summary reports')
75     parser.add_option('--site', default=None,
76                       help='create srf files tagged with the provided site name')
77     parser.add_option('-u', '--use-run', dest='use_run', default=None,
78                       help='Specify which run to use instead of autoscanning '
79                            'the runfolder. You do this by providing the final '
80                            ' GERALD directory, and it assumes the parent '
81                            'directories are the bustard and image processing '
82                            'directories.')
83     parser.add_option('--raw-format', dest="raw_format", default='qseq',
84                       choices=['qseq', 'srf'],
85                       help='Specify which type of raw format to use. '
86                            'Currently supported options: qseq, srf')
87
88     return parser
89
90 def main(cmdlist=None):
91     parser = make_parser()
92     opt, args = parser.parse_args(cmdlist)
93
94     logging.basicConfig()
95     if opt.verbose:
96         LOGGER.setLevel(logging.INFO)
97
98     LOGGER.info('Starting htsworkflow illumina runfolder processing tool.')
99     runs = []
100     if opt.run_xml:
101         # handle ~ shortcut
102         opt.run_xml = os.path.expanduser(opt.run_xml)
103         tree = ElementTree.parse(opt.run_xml).getroot()
104         runs.append(runfolder.PipelineRun(xml=tree))
105
106     # look for manually specified run
107     if opt.use_run is not None:
108         specific_run = runfolder.get_specific_run(opt.use_run)
109         if specific_run is not None:
110             runs.append(specific_run)
111         else:
112             LOGGER.warn("Couldn't find a run in %s" % (opt.use_run,))
113
114     # scan runfolders for runs
115     for run_pattern in args:
116         # expand args on our own if needed
117         for run_dir in glob(run_pattern):
118             runs.extend(runfolder.get_runs(run_dir))
119
120     if len(runs) > 0:
121         command_run = False
122         if opt.summary:
123             print runfolder.summary_report(runs)
124             command_run = True
125         if opt.archive:
126             runfolder.extract_run_parameters(runs)
127             command_run = True
128         if opt.extract_results:
129             if opt.dry_run:
130                 parser.error("Dry-run is not supported for extract-results")
131             runfolder.extract_results(runs,
132                                       opt.output_dir,
133                                       opt.site,
134                                       opt.max_jobs,
135                                       opt.raw_format)
136             command_run = True
137         if opt.clean:
138             runfolder.clean_runs(runs, opt.dry_run)
139             command_run = True
140
141         if command_run == False:
142             print "You need to specify a command." + os.linesep
143             parser.print_help()
144     else:
145         print "You need to specify some run folders to process..." + os.linesep
146         parser.print_help()
147
148     return 0
149
150 if __name__ == "__main__":
151   sys.exit(main(sys.argv[1:]))