1# Time-stamp: <2019-09-25 10:15:20 taoliu>
2
3"""Module Description
4
5This code is free software; you can redistribute it and/or modify it
6under the terms of the BSD License (see the file LICENSE included with
7the distribution).
8"""
9
10# ------------------------------------
11# python modules
12# ------------------------------------
13import sys
14import os
15import re
16import logging
17from argparse import ArgumentError
18from subprocess import Popen, PIPE
19from math import log
20from MACS2.IO.Parser import BEDParser, ELANDResultParser, ELANDMultiParser, \
21    ELANDExportParser, SAMParser, BAMParser, BAMPEParser,\
22    BEDPEParser, BowtieParser,  guess_parser
23# ------------------------------------
24# constants
25# ------------------------------------
26
27efgsize = {"hs":2.7e9,
28           "mm":1.87e9,
29           "ce":9e7,
30           "dm":1.2e8}
31
32# ------------------------------------
33# Misc functions
34# ------------------------------------
35def opt_validate ( options ):
36    """Validate options from a OptParser object.
37
38    Ret: Validated options object.
39    """
40    # gsize
41    try:
42        options.gsize = efgsize[options.gsize]
43    except:
44        try:
45            options.gsize = float(options.gsize)
46        except:
47            logging.error("Error when interpreting --gsize option: %s" % options.gsize)
48            logging.error("Available shortcuts of effective genome sizes are %s" % ",".join(list(efgsize.keys())))
49            sys.exit(1)
50
51    # format
52    options.gzip_flag = False           # if the input is gzip file
53
54    options.format = options.format.upper()
55    if options.format == "ELAND":
56        options.parser = ELANDResultParser
57    elif options.format == "BED":
58        options.parser = BEDParser
59    elif options.format == "ELANDMULTI":
60        options.parser = ELANDMultiParser
61    elif options.format == "ELANDEXPORT":
62        options.parser = ELANDExportParser
63    elif options.format == "SAM":
64        options.parser = SAMParser
65    elif options.format == "BAM":
66        options.parser = BAMParser
67        options.gzip_flag = True
68    elif options.format == "BAMPE":
69        options.parser = BAMPEParser
70        options.gzip_flag = True
71        options.nomodel = True
72    elif options.format == "BEDPE":
73        options.parser = BEDPEParser
74        options.nomodel = True
75    elif options.format == "BOWTIE":
76        options.parser = BowtieParser
77    elif options.format == "AUTO":
78        options.parser = guess_parser
79    else:
80        logging.error("Format \"%s\" cannot be recognized!" % (options.format))
81        sys.exit(1)
82
83    # duplicate reads
84    if options.keepduplicates != "auto" and options.keepduplicates != "all":
85        if not options.keepduplicates.isdigit():
86            logging.error("--keep-dup should be 'auto', 'all' or an integer!")
87            sys.exit(1)
88
89    # shiftsize>0
90    #if options.shiftsize:               # only if --shiftsize is set, it's true
91    #    options.extsize = 2 * options.shiftsize
92    #else:                               # if --shiftsize is not set
93    #    options.shiftsize = options.extsize / 2
94    if options.extsize < 1 :
95        logging.error("--extsize must >= 1!")
96        sys.exit(1)
97
98    # refine_peaks, call_summits can't be combined with --broad
99    #if options.broad and (options.refine_peaks or options.call_summits):
100    #    logging.error("--broad can't be combined with --refine-peaks or --call-summits!")
101    #    sys.exit(1)
102
103    if options.broad and options.call_summits:
104        logging.error("--broad can't be combined with --call-summits!")
105        sys.exit(1)
106
107    if options.pvalue:
108        # if set, ignore qvalue cutoff
109        options.log_qvalue = None
110        options.log_pvalue = log(options.pvalue,10)*-1
111    else:
112        options.log_qvalue = log(options.qvalue,10)*-1
113        options.log_pvalue = None
114    if options.broad:
115        options.log_broadcutoff = log(options.broadcutoff,10)*-1
116
117    # uppercase the format string
118    options.format = options.format.upper()
119
120    # d_min is non-negative
121    if options.d_min < 0:
122        logging.error("Minimum fragment size shouldn't be negative!" % options.d_min)
123        sys.exit(1)
124
125    # upper and lower mfold
126    options.lmfold = options.mfold[0]
127    options.umfold = options.mfold[1]
128    if options.lmfold > options.umfold:
129        logging.error("Upper limit of mfold should be greater than lower limit!" % options.mfold)
130        sys.exit(1)
131
132    # output filenames
133    options.peakxls = os.path.join( options.outdir, options.name+"_peaks.xls" )
134    options.peakbed = os.path.join( options.outdir, options.name+"_peaks.bed" )
135    options.peakNarrowPeak = os.path.join( options.outdir, options.name+"_peaks.narrowPeak" )
136    options.peakBroadPeak = os.path.join( options.outdir, options.name+"_peaks.broadPeak" )
137    options.peakGappedPeak = os.path.join( options.outdir, options.name+"_peaks.gappedPeak" )
138    options.summitbed = os.path.join( options.outdir, options.name+"_summits.bed" )
139    options.bdg_treat = os.path.join( options.outdir, options.name+"_treat_pileup.bdg" )
140    options.bdg_control= os.path.join( options.outdir, options.name+"_control_lambda.bdg" )
141    if options.cutoff_analysis:
142        options.cutoff_analysis_file = os.path.join( options.outdir, options.name+"_cutoff_analysis.txt" )
143    else:
144        options.cutoff_analysis_file = "None"
145    #options.negxls  = os.path.join( options.name+"_negative_peaks.xls" )
146    #options.diagxls = os.path.join( options.name+"_diag.xls" )
147    options.modelR  = os.path.join( options.outdir, options.name+"_model.r" )
148    #options.pqtable  = os.path.join( options.outdir, options.name+"_pq_table.txt" )
149
150    # logging object
151    logging.basicConfig(level=(4-options.verbose)*10,
152                        format='%(levelname)-5s @ %(asctime)s: %(message)s ',
153                        datefmt='%a, %d %b %Y %H:%M:%S',
154                        stream=sys.stderr,
155                        filemode="w"
156                        )
157
158    options.error   = logging.critical        # function alias
159    options.warn    = logging.warning
160    options.debug   = logging.debug
161    options.info    = logging.info
162
163    options.argtxt = "\n".join((
164        "# Command line: %s" % " ".join(sys.argv[1:]),\
165        "# ARGUMENTS LIST:",\
166        "# name = %s" % (options.name),\
167        "# format = %s" % (options.format),\
168        "# ChIP-seq file = %s" % (options.tfile),\
169        "# control file = %s" % (options.cfile),\
170        "# effective genome size = %.2e" % (options.gsize),\
171        #"# tag size = %d" % (options.tsize),\
172        "# band width = %d" % (options.bw),\
173        "# model fold = %s\n" % (options.mfold),\
174        ))
175
176    if options.pvalue:
177        if options.broad:
178            options.argtxt +=  "# pvalue cutoff for narrow/strong regions = %.2e\n" % (options.pvalue)
179            options.argtxt +=  "# pvalue cutoff for broad/weak regions = %.2e\n" % (options.broadcutoff)
180            options.argtxt +=  "# qvalue will not be calculated and reported as -1 in the final output.\n"
181        else:
182            options.argtxt +=  "# pvalue cutoff = %.2e\n" % (options.pvalue)
183            options.argtxt +=  "# qvalue will not be calculated and reported as -1 in the final output.\n"
184    else:
185        if options.broad:
186            options.argtxt +=  "# qvalue cutoff for narrow/strong regions = %.2e\n" % (options.qvalue)
187            options.argtxt +=  "# qvalue cutoff for broad/weak regions = %.2e\n" % (options.broadcutoff)
188        else:
189            options.argtxt +=  "# qvalue cutoff = %.2e\n" % (options.qvalue)
190
191    if options.maxgap:
192        options.argtxt += "# The maximum gap between significant sites = %d\n" % options.maxgap
193    else:
194        options.argtxt += "# The maximum gap between significant sites is assigned as the read length/tag size.\n"
195    if options.minlen:
196        options.argtxt += "# The minimum length of peaks = %d\n" % options.minlen
197    else:
198        options.argtxt += "# The minimum length of peaks is assigned as the predicted fragment length \"d\".\n"
199
200    if options.downsample:
201        options.argtxt += "# Larger dataset will be randomly sampled towards smaller dataset.\n"
202        if options.seed >= 0:
203            options.argtxt += "# Random seed has been set as: %d\n" % options.seed
204    else:
205        if options.scaleto == "large":
206            options.argtxt += "# Smaller dataset will be scaled towards larger dataset.\n"
207        else:
208            options.argtxt += "# Larger dataset will be scaled towards smaller dataset.\n"
209
210    if options.ratio != 1.0:
211        options.argtxt += "# Using a custom scaling factor: %.2e\n" % (options.ratio)
212
213    if options.cfile:
214        options.argtxt += "# Range for calculating regional lambda is: %d bps and %d bps\n" % (options.smalllocal,options.largelocal)
215    else:
216        options.argtxt += "# Range for calculating regional lambda is: %d bps\n" % (options.largelocal)
217
218    if options.broad:
219        options.argtxt += "# Broad region calling is on\n"
220    else:
221        options.argtxt += "# Broad region calling is off\n"
222
223    if options.fecutoff != 1.0:
224        options.argtxt += "# Additional cutoff on fold-enrichment is: %.2f\n" % (options.fecutoff)
225
226    if options.format in ["BAMPE", "BEDPE"]:
227        # neutralize SHIFT
228        options.shift = 0
229        options.argtxt += "# Paired-End mode is on\n"
230    else:
231        options.argtxt += "# Paired-End mode is off\n"
232
233    #if options.refine_peaks:
234    #    options.argtxt += "# Refining peak for read balance is on\n"
235    if options.call_summits:
236        options.argtxt += "# Searching for subpeak summits is on\n"
237
238    if options.do_SPMR and options.store_bdg:
239        options.argtxt += "# MACS will save fragment pileup signal per million reads\n"
240
241    return options
242
243def diff_opt_validate ( options ):
244    """Validate options from a OptParser object.
245
246    Ret: Validated options object.
247    """
248    # format
249    options.gzip_flag = False           # if the input is gzip file
250
251#    options.format = options.format.upper()
252    # fox this stuff
253#    if True: pass
254#    elif options.format == "AUTO":
255#        options.parser = guess_parser
256#    else:
257#        logging.error("Format \"%s\" cannot be recognized!" % (options.format))
258#        sys.exit(1)
259
260    if options.peaks_pvalue:
261        # if set, ignore qvalue cutoff
262        options.peaks_log_qvalue = None
263        options.peaks_log_pvalue = log(options.peaks_pvalue,10)*-1
264        options.track_score_method = 'p'
265    else:
266        options.peaks_log_qvalue = log(options.peaks_qvalue,10)*-1
267        options.peaks_log_pvalue = None
268        options.track_score_method = 'q'
269
270    if options.diff_pvalue:
271        # if set, ignore qvalue cutoff
272        options.log_qvalue = None
273        options.log_pvalue = log(options.diff_pvalue,10)*-1
274        options.score_method = 'p'
275    else:
276        options.log_qvalue = log(options.diff_qvalue,10)*-1
277        options.log_pvalue = None
278        options.score_method = 'q'
279
280    # output filenames
281    options.peakxls = options.name+"_diffpeaks.xls"
282    options.peakbed = options.name+"_diffpeaks.bed"
283    options.peak1xls = options.name+"_diffpeaks_by_peaks1.xls"
284    options.peak2xls = options.name+"_diffpeaks_by_peaks2.xls"
285    options.bdglogLR = options.name+"_logLR.bdg"
286    options.bdgpvalue = options.name+"_logLR.bdg"
287    options.bdglogFC = options.name+"_logLR.bdg"
288
289    options.call_peaks = True
290    if not (options.peaks1 == '' or options.peaks2 == ''):
291        if options.peaks1 == '':
292            raise ArgumentError('peaks1', 'Must specify both peaks1 and peaks2, or neither (to call peaks again)')
293        elif options.peaks2 == '':
294            raise ArgumentError('peaks2', 'Must specify both peaks1 and peaks2, or neither (to call peaks again)')
295        options.call_peaks = False
296        options.argtxt = "\n".join((
297            "# ARGUMENTS LIST:",\
298            "# name = %s" % (options.name),\
299#            "# format = %s" % (options.format),\
300            "# ChIP-seq file 1 = %s" % (options.t1bdg),\
301            "# control file 1 = %s" % (options.c1bdg),\
302            "# ChIP-seq file 2 = %s" % (options.t2bdg),\
303            "# control file 2 = %s" % (options.c2bdg),\
304            "# Peaks, condition 1 = %s" % (options.peaks1),\
305            "# Peaks, condition 2 = %s" % (options.peaks2),\
306            ""
307            ))
308    else:
309        options.argtxt = "\n".join((
310            "# ARGUMENTS LIST:",\
311            "# name = %s" % (options.name),\
312#            "# format = %s" % (options.format),\
313            "# ChIP-seq file 1 = %s" % (options.t1bdg),\
314            "# control file 1 = %s" % (options.c1bdg),\
315            "# ChIP-seq file 2 = %s" % (options.t2bdg),\
316            "# control file 2 = %s" % (options.c2bdg),\
317            ""
318            ))
319
320        if options.peaks_pvalue:
321            options.argtxt +=  "# treat/control -log10(pvalue) cutoff = %.2e\n" % (options.peaks_log_pvalue)
322            options.argtxt +=  "# treat/control -log10(qvalue) will not be calculated and reported as -1 in the final output.\n"
323        else:
324            options.argtxt +=  "# treat/control -log10(qvalue) cutoff = %.2e\n" % (options.peaks_log_qvalue)
325
326    if options.diff_pvalue:
327        options.argtxt +=  "# differential pvalue cutoff = %.2e\n" % (options.log_pvalue)
328        options.argtxt +=  "# differential qvalue will not be calculated and reported as -1 in the final output.\n"
329    else:
330        options.argtxt +=  "# differential qvalue cutoff = %.2e\n" % (options.log_qvalue)
331
332    # logging object
333    logging.basicConfig(level=(4-options.verbose)*10,
334                        format='%(levelname)-5s @ %(asctime)s: %(message)s ',
335                        datefmt='%a, %d %b %Y %H:%M:%S',
336                        stream=sys.stderr,
337                        filemode="w"
338                        )
339
340    options.error   = logging.critical        # function alias
341    options.warn    = logging.warning
342    options.debug   = logging.debug
343    options.info    = logging.info
344
345    return options
346
347def opt_validate_filterdup ( options ):
348    """Validate options from a OptParser object.
349
350    Ret: Validated options object.
351    """
352    # gsize
353    try:
354        options.gsize = efgsize[options.gsize]
355    except:
356        try:
357            options.gsize = float(options.gsize)
358        except:
359            logging.error("Error when interpreting --gsize option: %s" % options.gsize)
360            logging.error("Available shortcuts of effective genome sizes are %s" % ",".join(list(efgsize.keys())))
361            sys.exit(1)
362
363    # format
364
365    options.gzip_flag = False           # if the input is gzip file
366
367    options.format = options.format.upper()
368    if options.format == "ELAND":
369        options.parser = ELANDResultParser
370    elif options.format == "BED":
371        options.parser = BEDParser
372    elif options.format == "BEDPE":
373        options.parser = BEDPEParser
374    elif options.format == "ELANDMULTI":
375        options.parser = ELANDMultiParser
376    elif options.format == "ELANDEXPORT":
377        options.parser = ELANDExportParser
378    elif options.format == "SAM":
379        options.parser = SAMParser
380    elif options.format == "BAM":
381        options.parser = BAMParser
382        options.gzip_flag = True
383    elif options.format == "BOWTIE":
384        options.parser = BowtieParser
385    elif options.format == "BAMPE":
386        options.parser = BAMPEParser
387        options.gzip_flag = True
388    elif options.format == "BEDPE":
389        options.parser = BEDPEParser
390    elif options.format == "AUTO":
391        options.parser = guess_parser
392    else:
393        logging.error("Format \"%s\" cannot be recognized!" % (options.format))
394        sys.exit(1)
395
396    # duplicate reads
397    if options.keepduplicates != "auto" and options.keepduplicates != "all":
398        if not options.keepduplicates.isdigit():
399            logging.error("--keep-dup should be 'auto', 'all' or an integer!")
400            sys.exit(1)
401
402    # uppercase the format string
403    options.format = options.format.upper()
404
405    # logging object
406    logging.basicConfig(level=(4-options.verbose)*10,
407                        format='%(levelname)-5s @ %(asctime)s: %(message)s ',
408                        datefmt='%a, %d %b %Y %H:%M:%S',
409                        stream=sys.stderr,
410                        filemode="w"
411                        )
412
413    options.error   = logging.critical        # function alias
414    options.warn    = logging.warning
415    options.debug   = logging.debug
416    options.info    = logging.info
417
418    return options
419
420def opt_validate_randsample ( options ):
421    """Validate options from a OptParser object.
422
423    Ret: Validated options object.
424    """
425    # format
426
427    options.gzip_flag = False           # if the input is gzip file
428
429    options.format = options.format.upper()
430    if options.format == "ELAND":
431        options.parser = ELANDResultParser
432    elif options.format == "BED":
433        options.parser = BEDParser
434    elif options.format == "ELANDMULTI":
435        options.parser = ELANDMultiParser
436    elif options.format == "ELANDEXPORT":
437        options.parser = ELANDExportParser
438    elif options.format == "SAM":
439        options.parser = SAMParser
440    elif options.format == "BAM":
441        options.parser = BAMParser
442        options.gzip_flag = True
443    elif options.format == "BOWTIE":
444        options.parser = BowtieParser
445    elif options.format == "BAMPE":
446        options.parser = BAMPEParser
447        options.gzip_flag = True
448    elif options.format == "BEDPE":
449        options.parser = BEDPEParser
450    elif options.format == "AUTO":
451        options.parser = guess_parser
452    else:
453        logging.error("Format \"%s\" cannot be recognized!" % (options.format))
454        sys.exit(1)
455
456    # uppercase the format string
457    options.format = options.format.upper()
458
459    # percentage or number
460    if options.percentage:
461        if options.percentage > 100.0:
462            logging.error("Percentage can't be bigger than 100.0. Please check your options and retry!")
463            sys.exit(1)
464    elif options.number:
465        if options.number <= 0:
466            logging.error("Number of tags can't be smaller than or equal to 0. Please check your options and retry!")
467            sys.exit(1)
468
469    # logging object
470    logging.basicConfig(level=(4-options.verbose)*10,
471                        format='%(levelname)-5s @ %(asctime)s: %(message)s ',
472                        datefmt='%a, %d %b %Y %H:%M:%S',
473                        stream=sys.stderr,
474                        filemode="w"
475                        )
476
477    options.error   = logging.critical        # function alias
478    options.warn    = logging.warning
479    options.debug   = logging.debug
480    options.info    = logging.info
481
482    return options
483
484def opt_validate_refinepeak ( options ):
485    """Validate options from a OptParser object.
486
487    Ret: Validated options object.
488    """
489    # format
490
491    options.gzip_flag = False           # if the input is gzip file
492
493    options.format = options.format.upper()
494    if options.format == "ELAND":
495        options.parser = ELANDResultParser
496    elif options.format == "BED":
497        options.parser = BEDParser
498    elif options.format == "ELANDMULTI":
499        options.parser = ELANDMultiParser
500    elif options.format == "ELANDEXPORT":
501        options.parser = ELANDExportParser
502    elif options.format == "SAM":
503        options.parser = SAMParser
504    elif options.format == "BAM":
505        options.parser = BAMParser
506        options.gzip_flag = True
507    elif options.format == "BOWTIE":
508        options.parser = BowtieParser
509    elif options.format == "AUTO":
510        options.parser = guess_parser
511    else:
512        logging.error("Format \"%s\" cannot be recognized!" % (options.format))
513        sys.exit(1)
514
515    # uppercase the format string
516    options.format = options.format.upper()
517
518    # logging object
519    logging.basicConfig(level=(4-options.verbose)*10,
520                        format='%(levelname)-5s @ %(asctime)s: %(message)s ',
521                        datefmt='%a, %d %b %Y %H:%M:%S',
522                        stream=sys.stderr,
523                        filemode="w"
524                        )
525
526    options.error   = logging.critical        # function alias
527    options.warn    = logging.warning
528    options.debug   = logging.debug
529    options.info    = logging.info
530
531    return options
532
533def opt_validate_predictd ( options ):
534    """Validate options from a OptParser object.
535
536    Ret: Validated options object.
537    """
538    # gsize
539    try:
540        options.gsize = efgsize[options.gsize]
541    except:
542        try:
543            options.gsize = float(options.gsize)
544        except:
545            logging.error("Error when interpreting --gsize option: %s" % options.gsize)
546            logging.error("Available shortcuts of effective genome sizes are %s" % ",".join(list(efgsize.keys())))
547            sys.exit(1)
548
549    # format
550    options.gzip_flag = False           # if the input is gzip file
551
552    options.format = options.format.upper()
553    if options.format == "ELAND":
554        options.parser = ELANDResultParser
555    elif options.format == "BED":
556        options.parser = BEDParser
557    elif options.format == "ELANDMULTI":
558        options.parser = ELANDMultiParser
559    elif options.format == "ELANDEXPORT":
560        options.parser = ELANDExportParser
561    elif options.format == "SAM":
562        options.parser = SAMParser
563    elif options.format == "BAM":
564        options.parser = BAMParser
565        options.gzip_flag = True
566    elif options.format == "BAMPE":
567        options.parser = BAMPEParser
568        options.gzip_flag = True
569        options.nomodel = True
570    elif options.format == "BEDPE":
571        options.parser = BEDPEParser
572        options.nomodel = True
573    elif options.format == "BOWTIE":
574        options.parser = BowtieParser
575    elif options.format == "AUTO":
576        options.parser = guess_parser
577    else:
578        logging.error("Format \"%s\" cannot be recognized!" % (options.format))
579        sys.exit(1)
580
581    # uppercase the format string
582    options.format = options.format.upper()
583
584    # d_min is non-negative
585    if options.d_min < 0:
586        logging.error("Minimum fragment size shouldn't be negative!" % options.d_min)
587        sys.exit(1)
588
589    # upper and lower mfold
590    options.lmfold = options.mfold[0]
591    options.umfold = options.mfold[1]
592    if options.lmfold > options.umfold:
593        logging.error("Upper limit of mfold should be greater than lower limit!" % options.mfold)
594        sys.exit(1)
595
596    options.modelR  = os.path.join( options.outdir, options.rfile )
597
598    # logging object
599    logging.basicConfig(level=(4-options.verbose)*10,
600                        format='%(levelname)-5s @ %(asctime)s: %(message)s ',
601                        datefmt='%a, %d %b %Y %H:%M:%S',
602                        stream=sys.stderr,
603                        filemode="w"
604                        )
605
606    options.error   = logging.critical        # function alias
607    options.warn    = logging.warning
608    options.debug   = logging.debug
609    options.info    = logging.info
610
611    return options
612
613
614def opt_validate_pileup ( options ):
615    """Validate options from a OptParser object.
616
617    Ret: Validated options object.
618    """
619    # format
620
621    options.gzip_flag = False           # if the input is gzip file
622
623    options.format = options.format.upper()
624    if options.format == "ELAND":
625        options.parser = ELANDResultParser
626    elif options.format == "BED":
627        options.parser = BEDParser
628    elif options.format == "ELANDMULTI":
629        options.parser = ELANDMultiParser
630    elif options.format == "ELANDEXPORT":
631        options.parser = ELANDExportParser
632    elif options.format == "SAM":
633        options.parser = SAMParser
634    elif options.format == "BAM":
635        options.parser = BAMParser
636        options.gzip_flag = True
637    elif options.format == "BOWTIE":
638        options.parser = BowtieParser
639    elif options.format == "BAMPE":
640        options.parser = BAMPEParser
641        options.gzip_flag = True
642    elif options.format == "BEDPE":
643        options.parser = BEDPEParser
644    else:
645        logging.error("Format \"%s\" cannot be recognized!" % (options.format))
646        sys.exit(1)
647
648    # uppercase the format string
649    options.format = options.format.upper()
650
651    # logging object
652    logging.basicConfig(level=(4-options.verbose)*10,
653                        format='%(levelname)-5s @ %(asctime)s: %(message)s ',
654                        datefmt='%a, %d %b %Y %H:%M:%S',
655                        stream=sys.stderr,
656                        filemode="w"
657                        )
658
659    options.error   = logging.critical        # function alias
660    options.warn    = logging.warning
661    options.debug   = logging.debug
662    options.info    = logging.info
663
664    # extsize
665    if options.extsize <= 0 :
666        logging.error("--extsize must > 0!")
667        sys.exit(1)
668
669    return options
670
671def opt_validate_bdgcmp ( options ):
672    """Validate options from a OptParser object.
673
674    Ret: Validated options object.
675    """
676    # logging object
677    logging.basicConfig(level=20,
678                        format='%(levelname)-5s @ %(asctime)s: %(message)s ',
679                        datefmt='%a, %d %b %Y %H:%M:%S',
680                        stream=sys.stderr,
681                        filemode="w"
682                        )
683
684    options.error   = logging.critical        # function alias
685    options.warn    = logging.warning
686    options.debug   = logging.debug
687    options.info    = logging.info
688
689    # methods should be valid:
690
691    for method in set(options.method):
692        if method not in [ 'ppois', 'qpois', 'subtract', 'logFE', 'FE', 'logLR', 'slogLR', 'max' ]:
693            logging.error( "Invalid method: %s" % method )
694            sys.exit( 1 )
695
696    # # of --ofile must == # of -m
697
698    if options.ofile:
699        if len(options.method) != len(options.ofile):
700            logging.error("The number and the order of arguments for --ofile must be the same as for -m.")
701            sys.exit(1)
702
703    return options
704
705
706def opt_validate_cmbreps ( options ):
707    """Validate options from a OptParser object.
708
709    Ret: Validated options object.
710    """
711    # logging object
712    logging.basicConfig(level=20,
713                        format='%(levelname)-5s @ %(asctime)s: %(message)s ',
714                        datefmt='%a, %d %b %Y %H:%M:%S',
715                        stream=sys.stderr,
716                        filemode="w"
717                        )
718
719    options.error   = logging.critical        # function alias
720    options.warn    = logging.warning
721    options.debug   = logging.debug
722    options.info    = logging.info
723
724    # methods should be valid:
725
726
727    if options.method not in [ 'fisher', 'max', 'mean']:
728        logging.error( "Invalid method: %s" % options.method )
729        sys.exit( 1 )
730
731    if len( options.ifile ) < 2:
732        logging.error("Combining replicates needs at least two replicates!")
733        sys.exit( 1 )
734
735    # # of -i must == # of -w
736
737    # if not options.weights:
738    #     options.weights = [ 1.0 ] * len( options.ifile )
739
740    # if len( options.ifile ) != len( options.weights ):
741    #     logging.error("Must provide same number of weights as number of input files.")
742    #     sys.exit( 1 )
743
744    # if options.method == "fisher" and len( options.ifile ) > 3:
745    #     logging.error("NOT IMPLEMENTED! Can't combine more than 3 replicates using Fisher's method.")
746    #     sys.exit( 1 )
747
748    return options
749
750
751def opt_validate_bdgopt ( options ):
752    """Validate options from a OptParser object.
753
754    Ret: Validated options object.
755    """
756    # logging object
757    logging.basicConfig(level=20,
758                        format='%(levelname)-5s @ %(asctime)s: %(message)s ',
759                        datefmt='%a, %d %b %Y %H:%M:%S',
760                        stream=sys.stderr,
761                        filemode="w"
762                        )
763
764    options.error   = logging.critical        # function alias
765    options.warn    = logging.warning
766    options.debug   = logging.debug
767    options.info    = logging.info
768
769    # methods should be valid:
770
771    if options.method.lower() not in [ 'multiply', 'add', 'p2q', 'max', 'min']:
772        logging.error( "Invalid method: %s" % options.method )
773        sys.exit( 1 )
774
775    if options.method.lower() in [ 'multiply', 'add' ] and not options.extraparam:
776        logging.error( "Need EXTRAPARAM for method multiply or add!")
777        sys.exit( 1 )
778
779    return options
780
781