deepTools-2.5.0/0000750000201600010240000000000013067420417012621 5ustar ryanbioinfodeepTools-2.5.0/bin/0000750000201600010240000000000013067415117013372 5ustar ryanbioinfodeepTools-2.5.0/bin/bamCompare0000750000201600010240000000031713006372703015363 0ustar ryanbioinfo#!/usr/bin/env python #-*- coding: utf-8 -*- from deeptools.bamCompare import main import sys if __name__ == "__main__": args = None if len(sys.argv) == 1: args = ["--help"] main(args) deepTools-2.5.0/bin/bamCoverage0000750000201600010240000000032013006372703015522 0ustar ryanbioinfo#!/usr/bin/env python #-*- coding: utf-8 -*- from deeptools.bamCoverage import main import sys if __name__ == "__main__": args = None if len(sys.argv) == 1: args = ["--help"] main(args) deepTools-2.5.0/bin/bamPEFragmentSize0000750000201600010240000000032613006372703016620 0ustar ryanbioinfo#!/usr/bin/env python #-*- coding: utf-8 -*- from deeptools.bamPEFragmentSize import main import sys if __name__ == "__main__": args = None if len(sys.argv) == 1: args = ["--help"] main(args) deepTools-2.5.0/bin/bigwigCompare0000750000201600010240000000032213006372703016070 0ustar ryanbioinfo#!/usr/bin/env python #-*- coding: utf-8 -*- from deeptools.bigwigCompare import main import sys if __name__ == "__main__": args = None if len(sys.argv) == 1: args = ["--help"] main(args) deepTools-2.5.0/bin/computeGCBias0000750000201600010240000000032213006372703015776 0ustar ryanbioinfo#!/usr/bin/env python #-*- coding: utf-8 -*- from deeptools.computeGCBias import main import sys if __name__ == "__main__": args = None if len(sys.argv) == 1: args = ["--help"] main(args) deepTools-2.5.0/bin/computeMatrix0000750000201600010240000000032213006372703016152 0ustar ryanbioinfo#!/usr/bin/env python #-*- coding: utf-8 -*- from deeptools.computeMatrix import main import sys if __name__ == "__main__": args = None if len(sys.argv) == 1: args = ["--help"] main(args) deepTools-2.5.0/bin/computeMatrixOperations0000750000201600010240000000033413006372703020221 0ustar ryanbioinfo#!/usr/bin/env python #-*- coding: utf-8 -*- from deeptools.computeMatrixOperations import main import sys if __name__ == "__main__": args = None if len(sys.argv) == 1: args = ["--help"] main(args) deepTools-2.5.0/bin/correctGCBias0000750000201600010240000000032213006372703015763 0ustar ryanbioinfo#!/usr/bin/env python #-*- coding: utf-8 -*- from deeptools.correctGCBias import main import sys if __name__ == "__main__": args = None if len(sys.argv) == 1: args = ["--help"] main(args) deepTools-2.5.0/bin/deeptools0000750000201600010240000000033113006372703015307 0ustar ryanbioinfo#!/usr/bin/env python #-*- coding: utf-8 -*- from deeptools.deeptools_list_tools import main import sys if __name__ == "__main__": args = None if len(sys.argv) == 1: args = ["--help"] main(args) deepTools-2.5.0/bin/estimateScaleFactor0000750000201600010240000001127112763774077017263 0ustar ryanbioinfo#!/usr/bin/env python #-*- coding: utf-8 -*- import argparse import sys from deeptools.SES_scaleFactor import estimateScaleFactor from deeptools.parserCommon import numberOfProcessors from deeptools._version import __version__ debug = 0 def fileType(string): try: open( string, 'r').close() except IOError as detail: print detail exit() return string def parseArguments(args=None): parser = argparse.ArgumentParser( formatter_class=argparse.ArgumentDefaultsHelpFormatter, description='Given two BAM files, this estimates scaling factors ' '(bigger to smaller).') # define the arguments parser.add_argument('--bamfiles', '-b', metavar='list of bam files', help='List of indexed BAM files, space delineated', nargs='+', required=True) parser.add_argument('--ignoreForNormalization', '-ignore', help='A comma-separated list of chromosome names, ' 'limited by quotes, ' 'containing those ' 'chromosomes that should be excluded ' 'during normalization computations. For example, ' '--ignoreForNormalization "chrX, chrM" ') parser.add_argument('--sampleWindowLength', '-l', help='Length in bases for a window used to ' 'sample the genome and compute the size or scaling ' 'factors', default=1000, type=int) parser.add_argument('--numberOfSamples', '-n', help='Number of samplings taken from the genome ' 'to compute the scaling factors', default=100000, type=int) parser.add_argument('--normalizationLength', '-nl', help='By default, data is normalized to 1 ' 'fragment per 100 bases. The expected value is an ' 'integer. For example, if normalizationLength ' 'is 1000, then the resulting scaling factor ' 'will cause the average coverage of the BAM file to ' 'have on average 1 fragment per kilobase', type=int, default=10) parser.add_argument('--skipZeros', help='If set, then zero counts that happen for *all* ' 'BAM files given are ignored. This will result in a ' 'reduced number of read counts than that specified ' 'in --numberOfSamples', action='store_true', required=False) parser.add_argument('--numberOfProcessors', '-p', help='Number of processors to use. The default is ' 'to use half the maximum number of processors.', metavar="INT", type=numberOfProcessors, default="max/2", required=False) parser.add_argument('--verbose', '-v', help='Set to see processing messages.', action='store_true') parser.add_argument('--version', action='version', version='%(prog)s {}'.format(__version__)) args=parser.parse_args(args) if args.ignoreForNormalization: args.ignoreForNormalization=[x.strip() for x in args.ignoreForNormalization.split(',')] else: args.ignoreForNormalization = [] return(args) def main(args): """ The algorithm samples the genome a number of times as specified by the --numberOfSamples parameter to estimate scaling factors of betweeen to samples """ if len(args.bamfiles) > 2: print "SES method to stimate scale factors only works for two samples" exit(0) sys.stderr.write("{:,} number of samples will be computed.\n".format(args.numberOfSamples)) sizeFactorsDict = estimateScaleFactor(args.bamfiles, args.sampleWindowLength, args.numberOfSamples, args.normalizationLength, numberOfProcessors=args.numberOfProcessors, chrsToSkip=args.ignoreForNormalization, verbose=args.verbose) for k, v in sizeFactorsDict.iteritems(): print "{}: {}".format(k, v) if __name__ == "__main__": args = parseArguments() main(args) deepTools-2.5.0/bin/multiBamSummary0000750000201600010240000000032413006372703016443 0ustar ryanbioinfo#!/usr/bin/env python #-*- coding: utf-8 -*- from deeptools.multiBamSummary import main import sys if __name__ == "__main__": args = None if len(sys.argv) == 1: args = ["--help"] main(args) deepTools-2.5.0/bin/multiBigwigSummary0000750000201600010240000000032713006372703017157 0ustar ryanbioinfo#!/usr/bin/env python #-*- coding: utf-8 -*- from deeptools.multiBigwigSummary import main import sys if __name__ == "__main__": args = None if len(sys.argv) == 1: args = ["--help"] main(args) deepTools-2.5.0/bin/plotCorrelation0000750000201600010240000000032413006372703016473 0ustar ryanbioinfo#!/usr/bin/env python #-*- coding: utf-8 -*- from deeptools.plotCorrelation import main import sys if __name__ == "__main__": args = None if len(sys.argv) == 1: args = ["--help"] main(args) deepTools-2.5.0/bin/plotCoverage0000750000201600010240000000032213006372703015743 0ustar ryanbioinfo#!/usr/bin/env python # -*- coding: utf-8 -*- from deeptools.plotCoverage import main import sys if __name__ == "__main__": args = None if len(sys.argv) == 1: args = ["--help"] main(args) deepTools-2.5.0/bin/plotEnrichment0000750000201600010240000000032413006372703016306 0ustar ryanbioinfo#!/usr/bin/env python # -*- coding: utf-8 -*- from deeptools.plotEnrichment import main import sys if __name__ == "__main__": args = None if len(sys.argv) == 1: args = ["--help"] main(args) deepTools-2.5.0/bin/plotFingerprint0000750000201600010240000000032413006372703016501 0ustar ryanbioinfo#!/usr/bin/env python #-*- coding: utf-8 -*- from deeptools.plotFingerprint import main import sys if __name__ == "__main__": args = None if len(sys.argv) == 1: args = ["--help"] main(args) deepTools-2.5.0/bin/plotHeatmap0000750000201600010240000000032013006372703015565 0ustar ryanbioinfo#!/usr/bin/env python #-*- coding: utf-8 -*- from deeptools.plotHeatmap import main import sys if __name__ == "__main__": args = None if len(sys.argv) == 1: args = ["--help"] main(args) deepTools-2.5.0/bin/plotPCA0000750000201600010240000000031413006372703014614 0ustar ryanbioinfo#!/usr/bin/env python #-*- coding: utf-8 -*- from deeptools.plotPCA import main import sys if __name__ == "__main__": args = None if len(sys.argv) == 1: args = ["--help"] main(args) deepTools-2.5.0/bin/plotProfile0000750000201600010240000000032013006372703015606 0ustar ryanbioinfo#!/usr/bin/env python #-*- coding: utf-8 -*- from deeptools.plotProfile import main import sys if __name__ == "__main__": args = None if len(sys.argv) == 1: args = ["--help"] main(args) deepTools-2.5.0/deepTools.egg-info/0000750000201600010240000000000013067415120016244 5ustar ryanbioinfodeepTools-2.5.0/deepTools.egg-info/SOURCES.txt0000640000201600010240000001636513067415116020151 0ustar ryanbioinfoCHANGES.txt LICENSE.txt MANIFEST.in README.md README.rst requirements.txt setup.py bin/bamCompare bin/bamCoverage bin/bamPEFragmentSize bin/bigwigCompare bin/computeGCBias bin/computeMatrix bin/computeMatrixOperations bin/correctGCBias bin/deeptools bin/estimateScaleFactor bin/multiBamSummary bin/multiBigwigSummary bin/plotCorrelation bin/plotCoverage bin/plotEnrichment bin/plotFingerprint bin/plotHeatmap bin/plotPCA bin/plotProfile deeptools/SES_scaleFactor.py deeptools/__init__.py deeptools/_version.py deeptools/bamCompare.py deeptools/bamCoverage.py deeptools/bamHandler.py deeptools/bamPEFragmentSize.py deeptools/bigwigCompare.py deeptools/computeGCBias.py deeptools/computeMatrix.py deeptools/computeMatrixOperations.py deeptools/correctGCBias.py deeptools/correctReadCounts.py deeptools/correlation.py deeptools/correlation_heatmap.py deeptools/countReadsPerBin.py deeptools/deepBlue.py deeptools/deeptools_list_tools.py deeptools/getFragmentAndReadSize.py deeptools/getRatio.py deeptools/getScaleFactor.py deeptools/getScorePerBigWigBin.py deeptools/heatmapper.py deeptools/heatmapper_utilities.py deeptools/mapReduce.py deeptools/multiBamSummary.py deeptools/multiBigwigSummary.py deeptools/parserCommon.py deeptools/plotCorrelation.py deeptools/plotCoverage.py deeptools/plotEnrichment.py deeptools/plotFingerprint.py deeptools/plotHeatmap.py deeptools/plotPCA.py deeptools/plotProfile.py deeptools/sumCoveragePerBin.py deeptools/utilities.py deeptools/writeBedGraph.py deeptools/writeBedGraph_bam_and_bw.py deeptools/config/__init__.py deeptools/config/deeptools.cfg deeptools/test/__init__.py deeptools/test/test_bamCoverage_and_bamCompare.py deeptools/test/test_bigwigCompare_and_multiBigwigSummary.py deeptools/test/test_computeMatrixOperations.py deeptools/test/test_countReadsPerBin.py deeptools/test/test_heatmapper.py deeptools/test/test_multiBamSummary.py deeptools/test/test_plotCoverage.py deeptools/test/test_tools.py deeptools/test/test_writeBedGraph.py deeptools/test/test_corrGC/R_gc deeptools/test/test_corrGC/R_gc_paired.txt deeptools/test/test_corrGC/extra_sampling.bed deeptools/test/test_corrGC/filter_out.bed deeptools/test/test_corrGC/frequencies_data.txt deeptools/test/test_corrGC/mappability.bg deeptools/test/test_corrGC/mappability.bw deeptools/test/test_corrGC/paired.bam deeptools/test/test_corrGC/paired.bam.bai deeptools/test/test_corrGC/sequence.2bit deeptools/test/test_corrGC/sequence.fa deeptools/test/test_corrGC/sequence.fa.fai deeptools/test/test_corrGC/sizes deeptools/test/test_corrGC/test.bam deeptools/test/test_corrGC/test.bam.bai deeptools/test/test_corrGC/test.sam deeptools/test/test_corrGC/test_paired.bam deeptools/test/test_corrGC/test_paired.bam.bai deeptools/test/test_corrGC/test_paired.sam deeptools/test/test_data/computeMatrixOperations.bed deeptools/test/test_data/computeMatrixOperations.mat.gz deeptools/test/test_data/make_test_data.sh deeptools/test/test_data/test.bed3 deeptools/test/test_data/test.gtf deeptools/test/test_data/test1.bam deeptools/test/test_data/test1.bam.bai deeptools/test/test_data/test1.bg deeptools/test/test_data/test1.bw.bw deeptools/test/test_data/test1.sam deeptools/test/test_data/test2.bam deeptools/test/test_data/test2.bam.bai deeptools/test/test_data/test2.bg deeptools/test/test_data/test2.sam deeptools/test/test_data/testA.bam deeptools/test/test_data/testA.bam.bai deeptools/test/test_data/testA.bw deeptools/test/test_data/testA.sam deeptools/test/test_data/testA_offset-1.bw deeptools/test/test_data/testA_offset1.bw deeptools/test/test_data/testA_offset1_10.bw deeptools/test/test_data/testA_offset20_-4.bw deeptools/test/test_data/testA_skipNAs.bw deeptools/test/test_data/testB.bam deeptools/test/test_data/testB.bam.bai deeptools/test/test_data/testB.bw deeptools/test/test_data/testB.sam deeptools/test/test_data/testB_skipNAs.bw deeptools/test/test_data/test_filtering.bam deeptools/test/test_data/test_filtering.bam.bai deeptools/test/test_data/test_filtering.blacklist.bed deeptools/test/test_data/test_filtering2.bam deeptools/test/test_data/test_filtering2.bam.bai deeptools/test/test_data/test_paired.bam deeptools/test/test_data/test_paired.bam.bai deeptools/test/test_data/test_paired.sam deeptools/test/test_data/test_paired2.bam deeptools/test/test_data/test_paired2.bam.bai deeptools/test/test_data/test_paired2.bw deeptools/test/test_data/test_paired2.sam deeptools/test/test_data/test_proper_pair_filtering.bam deeptools/test/test_data/test_proper_pair_filtering.bam.bai deeptools/test/test_heatmapper/#test.bg# deeptools/test/test_heatmapper/group1.bed deeptools/test/test_heatmapper/group2.bed deeptools/test/test_heatmapper/heatmap_master_multi_color.svg deeptools/test/test_heatmapper/heatmap_master_multi_colormap_no_box.svg deeptools/test/test_heatmapper/heatmap_master_multi_pergroup.svg deeptools/test/test_heatmapper/make_test_data.sh deeptools/test/test_heatmapper/master.mat deeptools/test/test_heatmapper/master.mat.gz deeptools/test/test_heatmapper/master.svg deeptools/test/test_heatmapper/master.tab deeptools/test/test_heatmapper/master_TES.mat deeptools/test/test_heatmapper/master_center.mat deeptools/test/test_heatmapper/master_extend_beyond_chr_size.mat deeptools/test/test_heatmapper/master_gtf.mat deeptools/test/test_heatmapper/master_metagene.mat deeptools/test/test_heatmapper/master_multi.mat deeptools/test/test_heatmapper/master_multi.mat.gz deeptools/test/test_heatmapper/master_multibed.mat deeptools/test/test_heatmapper/master_nan_to_zero.mat deeptools/test/test_heatmapper/master_relabeled.svg deeptools/test/test_heatmapper/master_scale_reg.mat deeptools/test/test_heatmapper/master_scale_reg.mat.gz deeptools/test/test_heatmapper/master_scale_reg.svg deeptools/test/test_heatmapper/master_unscaled.mat deeptools/test/test_heatmapper/out.bed deeptools/test/test_heatmapper/profile_master.png deeptools/test/test_heatmapper/profile_master.svg deeptools/test/test_heatmapper/profile_master_heatmap.svg deeptools/test/test_heatmapper/profile_master_multi.svg deeptools/test/test_heatmapper/profile_master_multi_pergroup.svg deeptools/test/test_heatmapper/profile_master_overlap_lines.svg deeptools/test/test_heatmapper/test.bed deeptools/test/test_heatmapper/test.bg deeptools/test/test_heatmapper/test.bw deeptools/test/test_heatmapper/test.sizes deeptools/test/test_heatmapper/test2.bed deeptools/test/test_heatmapper/unscaled.bed deeptools/test/test_heatmapper/unscaled.bigWig deeptools/test/test_plotCoverage/make_test_files.sh deeptools/test/test_plotCoverage/outRawCounts_default.tabular deeptools/test/test_plotCoverage/plotCoverage_default.svg deeptoolsintervals/__init__.py deeptoolsintervals/enrichment.py deeptoolsintervals/parse.py deeptoolsintervals/test/GRCh38.84.2.gtf.gz deeptoolsintervals/test/GRCh38.84.bed deeptoolsintervals/test/GRCh38.84.bed12.bz2 deeptoolsintervals/test/GRCh38.84.bed2 deeptoolsintervals/test/GRCh38.84.bed6 deeptoolsintervals/test/GRCh38.84.gtf.gz deeptoolsintervals/test/GRCh38.84.labels.bed deeptoolsintervals/tree/findOverlaps.c deeptoolsintervals/tree/gtf.c deeptoolsintervals/tree/gtf.h deeptoolsintervals/tree/hashTable.c deeptoolsintervals/tree/kseq.h deeptoolsintervals/tree/kstring.h deeptoolsintervals/tree/murmur3.c deeptoolsintervals/tree/murmur3.h deeptoolsintervals/tree/tree.c deeptoolsintervals/tree/tree.h scripts/mappabilityBigWig_to_unmappableBed.sh scripts/split_bed_into_multiple_files.pydeepTools-2.5.0/deeptools/0000750000201600010240000000000013067415117014620 5ustar ryanbioinfodeepTools-2.5.0/deeptools/config/0000750000201600010240000000000013067415117016065 5ustar ryanbioinfodeepTools-2.5.0/deeptools/config/__init__.py0000640000201600010240000000456512757050135020211 0ustar ryanbioinfoimport os import sys try: import configparser except: import ConfigParser as configparser import subprocess import tempfile def checkProgram(program, args, where_to_download): """ deeptools relies on some command line programs to work properly. This is a generic routine that will check for such programs """ if os.environ.get('DEEP_TOOLS_NO_CONFIG', False): return True try: subprocess.Popen([program, args], stderr=subprocess.PIPE, stdout=subprocess.PIPE) return True except EnvironmentError: # handle file not found error. # the config file is installed in: msg = "\n######################################################\n"\ "\nThe program *{}* was not found in your PATH. In\n" \ "order for deeptools to work properly this program needs\n"\ "to be installed. If you already have a copy of this\n"\ "program please be sure that it is found in your PATH or\n"\ "that is referred to in the configuration file of deepTools\n"\ "located at:\n\n{}\n\n" \ "The program can be downloaded from here:\n " \ " {}\n\n" \ "\n########################################################"\ "\n\n".format(program, config_file, where_to_download) sys.stderr.write(msg) except Exception as e: sys.stderr.write("Error: {}".format(e)) return False """ If the environment variable DEEP_TOOLS_NO_CONFIG is set the binaries from the PATH will be taken. That is used in the Galaxy Tool Shed integration """ if os.environ.get('DEEP_TOOLS_NO_CONFIG', False): config = configparser.ConfigParser() config.add_section('general') config.set('general', 'default_proc_number', 'max/2') # N.B., the TMPDIR variable can be used! config.set('general', 'tmp_dir', tempfile.gettempdir()) config.add_section('external_tools') config.set('external_tools', 'sort', 'sort') else: import pkg_resources # load the deepTools configuration file # that should be located under the root folder # of the deepTools instalation config_file = pkg_resources.resource_filename(__name__, 'deeptools.cfg') config = configparser.ConfigParser() config.readfp(open(config_file, 'r')) deepTools-2.5.0/deeptools/config/deeptools.cfg0000750000201600010240000000133212757050135020546 0ustar ryanbioinfo[external_tools] sort: sort [general] # if set to max/2 (no quotes around) # half the available processors will # be used default_proc_number: max/2 # temporary dir: # deepTools bamCoverage, bamCompare and correctGCbias # write files to a temporary dir before merging them # and creating a final file. This can be speed up # by writting to /dev/shm but for this a large # physical memory of the server is required. If # this is the case in your system, uncomment # the following line. Otherwise, setting the # variable to 'default', deepTools will use the # temporary file configured in the system. # Any other path that wants to be used for temporary # files can by given as well (ie, /tmp) #tmp_dir: /dev/shm tmp_dir: default deepTools-2.5.0/deeptools/test/0000750000201600010240000000000013067415117015577 5ustar ryanbioinfodeepTools-2.5.0/deeptools/test/test_corrGC/0000750000201600010240000000000013067415117020015 5ustar ryanbioinfodeepTools-2.5.0/deeptools/test/test_corrGC/R_gc0000640000201600010240000001164112757050135020616 0ustar ryanbioinfo1.000000000000000000e+00 1.000000000000000000e+00 1.000000000000000000e+00 1.000000000000000000e+00 1.000000000000000000e+00 1.000000000000000000e+00 1.000000000000000000e+00 1.000000000000000000e+00 1.000000000000000000e+00 1.000000000000000000e+00 1.000000000000000000e+00 1.000000000000000000e+00 1.000000000000000000e+00 1.000000000000000000e+00 1.000000000000000000e+00 1.000000000000000000e+00 1.000000000000000000e+00 1.000000000000000000e+00 1.000000000000000000e+00 1.000000000000000000e+00 1.000000000000000000e+00 1.000000000000000000e+00 1.000000000000000000e+00 1.000000000000000000e+00 1.000000000000000000e+00 3.307656666280550661e-02 1.000000000000000000e+00 1.000000000000000000e+00 1.000000000000000000e+00 4.410208888374068242e-02 1.323062666512220265e-01 1.000000000000000000e+00 3.307656666280550661e-02 1.653828333140275331e-02 6.615313332561101323e-02 6.615313332561101323e-02 3.307656666280550661e-02 2.205104444187034121e-02 4.134570832850689021e-02 4.134570832850689021e-02 3.307656666280550661e-02 7.560358094355544567e-02 3.113088627087577664e-02 7.028770415846170849e-02 5.292250666048881752e-02 5.197746189869437150e-02 6.339675277037723489e-02 1.036995062942010770e-01 8.820417776748137872e-02 1.035983031325606596e-01 1.033178149692127318e-01 1.504450290146960578e-01 1.947324628880662545e-01 1.609302185709576005e-01 1.740871929621342629e-01 2.137790729575008708e-01 2.485379401579031200e-01 2.669751452069302200e-01 2.805382876215726795e-01 2.961386359029306026e-01 3.090365352437303703e-01 3.312250633872607652e-01 3.799211198630577657e-01 3.649828045550952971e-01 4.913611021356240061e-01 4.709473062942309274e-01 5.058536003401513659e-01 5.815793868441754277e-01 6.173010406256145277e-01 6.081702422862803603e-01 7.693364394163653142e-01 8.164577035606058741e-01 8.815917563596734619e-01 9.460360674886332255e-01 9.823026416119507997e-01 9.144433123649089445e-01 1.051462126168338562e+00 1.176055703566418309e+00 1.455368933163442513e+00 1.183844878468770512e+00 1.445746659225171982e+00 1.509884015255844369e+00 1.584432399161448402e+00 1.626152022259152785e+00 2.090608636508092033e+00 1.675879377582145890e+00 2.215676862755054266e+00 2.345517712471297145e+00 2.070960590498989617e+00 2.173893735130848270e+00 2.361992203002964086e+00 2.245898876404494704e+00 2.871647378452660160e+00 2.895853411328622506e+00 2.284394369946100234e+00 2.596510483030232574e+00 3.175350399629329523e+00 3.018787984092050181e+00 4.022110506197150492e+00 3.322691469309099421e+00 3.175350399629329079e+00 6.805503590872233666e+00 2.590417431276558435e+00 3.969187999536661682e+00 3.340733232943356779e+00 4.041355054073691555e+00 3.170625175820356745e+00 4.308222807830418333e+00 5.634041854897872348e+00 7.822608015753503174e+00 3.327502606278234243e+00 3.274580099617745876e+00 7.298895710259083458e+00 3.517141588478319481e+00 6.830311015869337865e+00 6.400315649252866557e+00 3.929496119541294963e+00 7.839146299084906566e+00 2.037516506428819429e+00 1.000000000000000000e+00 1.000000000000000000e+00 1.000000000000000000e+00 1.000000000000000000e+00 1.488445499826248186e+00 1.000000000000000000e+00 2.249206533070774672e+00 1.000000000000000000e+00 1.000000000000000000e+00 1.000000000000000000e+00 1.000000000000000000e+00 1.000000000000000000e+00 1.000000000000000000e+00 1.000000000000000000e+00 1.000000000000000000e+00 1.000000000000000000e+00 1.000000000000000000e+00 1.000000000000000000e+00 1.000000000000000000e+00 1.000000000000000000e+00 1.000000000000000000e+00 1.000000000000000000e+00 1.000000000000000000e+00 1.000000000000000000e+00 1.000000000000000000e+00 1.000000000000000000e+00 1.000000000000000000e+00 1.000000000000000000e+00 1.000000000000000000e+00 1.000000000000000000e+00 1.000000000000000000e+00 1.000000000000000000e+00 1.000000000000000000e+00 1.000000000000000000e+00 1.000000000000000000e+00 1.000000000000000000e+00 1.000000000000000000e+00 1.000000000000000000e+00 1.000000000000000000e+00 1.000000000000000000e+00 1.000000000000000000e+00 1.000000000000000000e+00 1.000000000000000000e+00 1.000000000000000000e+00 1.000000000000000000e+00 1.000000000000000000e+00 1.000000000000000000e+00 1.000000000000000000e+00 1.000000000000000000e+00 1.000000000000000000e+00 1.000000000000000000e+00 1.000000000000000000e+00 1.000000000000000000e+00 1.000000000000000000e+00 1.000000000000000000e+00 1.000000000000000000e+00 1.000000000000000000e+00 1.000000000000000000e+00 1.000000000000000000e+00 1.000000000000000000e+00 1.000000000000000000e+00 1.000000000000000000e+00 1.000000000000000000e+00 1.000000000000000000e+00 1.000000000000000000e+00 1.000000000000000000e+00 1.000000000000000000e+00 1.000000000000000000e+00 1.000000000000000000e+00 1.000000000000000000e+00 1.000000000000000000e+00 1.000000000000000000e+00 1.000000000000000000e+00 1.000000000000000000e+00 1.000000000000000000e+00 1.000000000000000000e+00 1.000000000000000000e+00 1.000000000000000000e+00 1.000000000000000000e+00 1.000000000000000000e+00 1.000000000000000000e+00 1.000000000000000000e+00 deepTools-2.5.0/deeptools/test/test_corrGC/R_gc_paired.txt0000640000201600010240000001654512757050136022771 0ustar ryanbioinfo1.000000000000000000e+00 1.000000000000000000e+00 1.000000000000000000e+00 1.000000000000000000e+00 1.000000000000000000e+00 1.000000000000000000e+00 1.000000000000000000e+00 1.000000000000000000e+00 9.999910797344536695e-01 9.999881063479697518e-01 9.999960354178876187e-01 9.999986784691363706e-01 9.999995594893240636e-01 9.999998531630649445e-01 9.999999510543501335e-01 9.999910634195275927e-01 9.999881009096933671e-01 9.999960336051001430e-01 9.999986778648706220e-01 9.999906390302180093e-01 9.999790393966496715e-01 9.999751729119278343e-01 9.999828040490971182e-01 9.999853477873693608e-01 9.999683558235907821e-01 9.999626919639887923e-01 9.999429650515958556e-01 9.998917955244356337e-01 9.999014952266391809e-01 9.999404043573286716e-01 9.998998605246807170e-01 9.998774284063762785e-01 9.998610333117045057e-01 9.997396508489226896e-01 9.996546236674602737e-01 9.996084574474356499e-01 9.995039467350594897e-01 9.994334724531075409e-01 9.993832544833378684e-01 9.992952489888378143e-01 9.992124766060953567e-01 9.991937947471972725e-01 9.991341353337095388e-01 9.989361911898771984e-01 9.985677120637509452e-01 9.981249142589175838e-01 9.978708020679103452e-01 9.976973257405287177e-01 9.972845087879461667e-01 9.967037002953756941e-01 9.959790394434188121e-01 9.951101586761411655e-01 9.941062991879133781e-01 9.924612331344023763e-01 9.904680476116898280e-01 9.885747079662892123e-01 9.864643712263454489e-01 9.833182778577946870e-01 9.775190664032900045e-01 9.700848144057120370e-01 9.672094029191796727e-01 9.615246458671455887e-01 9.508348296088652285e-01 9.391160320609912571e-01 9.242509022112956885e-01 9.066909222689595316e-01 8.882577371730345783e-01 8.671542759947431511e-01 8.484839583712968647e-01 8.326341029616983747e-01 8.143221578913033554e-01 7.888729155613086741e-01 7.605389670367882493e-01 7.393839281847264244e-01 7.186395445767683743e-01 6.932633298695518587e-01 6.675563656468179730e-01 6.557166368114221155e-01 6.504490236624866917e-01 6.351631261409090845e-01 6.094480944384946808e-01 5.959239597618474216e-01 6.062711267642100221e-01 6.096765092929627983e-01 6.012419563708105708e-01 5.950445568540655428e-01 5.915286238538426389e-01 5.945652918963458822e-01 6.066585583688769434e-01 6.232366849715897938e-01 6.207735893523381732e-01 6.174292194441698411e-01 6.219755658323700143e-01 6.333643704897149451e-01 6.462121265298644834e-01 6.507620909354857597e-01 6.567693207017699653e-01 6.666917142803674423e-01 6.720857286686742205e-01 6.809026098441173236e-01 6.978556999377046877e-01 7.049648706604161319e-01 7.127873732353485758e-01 7.296378668166592085e-01 7.403554022845679761e-01 7.463937996388737561e-01 7.554663302694013538e-01 7.613302447567783515e-01 7.725250193054987724e-01 7.874507966249127966e-01 7.950448485277744615e-01 8.123925157445656131e-01 8.351176112325804368e-01 8.448163899633056584e-01 8.486626022941238245e-01 8.518629775517951863e-01 8.673459557442074752e-01 8.867932780337125509e-01 8.970672882946463256e-01 9.121570405649662705e-01 9.252104843400752454e-01 9.347096521350021225e-01 9.511757790014061520e-01 9.749130560843786153e-01 9.871340056274372499e-01 9.861327645317359281e-01 9.956404917161891799e-01 1.013828711491180368e+00 1.030610357269147626e+00 1.044959547295003288e+00 1.069485810055249120e+00 1.085347970221164804e+00 1.089971470505272988e+00 1.102264255644627378e+00 1.118238256270866371e+00 1.139355768843890893e+00 1.156758081791598780e+00 1.169924492290504325e+00 1.173819244193573974e+00 1.171493467719889825e+00 1.184597612914873865e+00 1.200345579387997130e+00 1.211459832379051527e+00 1.238295300414279598e+00 1.247966504099611296e+00 1.240167911695359004e+00 1.246792585479475024e+00 1.262948060117081939e+00 1.276655219603586966e+00 1.275103640549761330e+00 1.281133866408310507e+00 1.296069180560731615e+00 1.299133483576072612e+00 1.300451108519138810e+00 1.301216709707966990e+00 1.304273174129296997e+00 1.310916470284052782e+00 1.318653145359068635e+00 1.326424179836547923e+00 1.332809104899952857e+00 1.330874322483974304e+00 1.331227188570605735e+00 1.320629859072630419e+00 1.310655178935595355e+00 1.324967409044265132e+00 1.305711227011654652e+00 1.300056688446822761e+00 1.325284998407550541e+00 1.314578390711100164e+00 1.286193460421670043e+00 1.286803733181254294e+00 1.280205307605654985e+00 1.260356435274226472e+00 1.237936479140162138e+00 1.216672030278138861e+00 1.213736531974581645e+00 1.187420877435089617e+00 1.163243401233964081e+00 1.154202888945774275e+00 1.138357408768514656e+00 1.138048286269977227e+00 1.128822718258669422e+00 1.092812688452169168e+00 1.074694290821570641e+00 1.087005990409082079e+00 1.067480924916803131e+00 1.031726291161634945e+00 1.023230841280303949e+00 1.013539088603025107e+00 1.016605799520342357e+00 1.023192913724467523e+00 1.026343655721627224e+00 1.032122198652947631e+00 1.027953032235908948e+00 1.024294852853029569e+00 1.013620755330080891e+00 1.008819214784733242e+00 1.018096662438548350e+00 1.021338264269237017e+00 1.022289328406943865e+00 1.022615666885497099e+00 1.037514057530589895e+00 1.033582667958585999e+00 1.004774416770266354e+00 9.954468909407750976e-01 1.001248555328404288e+00 1.017317615127176555e+00 1.008286166216193047e+00 9.931907316083085080e-01 1.003277482727201075e+00 9.987250406848885431e-01 9.882493937498659786e-01 9.847709265094811704e-01 9.876623465877873986e-01 9.931650085164636099e-01 9.888285353549343126e-01 9.871859278030299389e-01 9.873418023156780299e-01 9.862213970957208753e-01 9.804238547456385344e-01 9.770518017386508047e-01 9.838955984354510464e-01 9.842054715700987444e-01 9.822685046843998569e-01 9.852919858875200942e-01 9.870299766344043935e-01 9.890557790764858970e-01 9.893290115293941200e-01 9.846980430143793539e-01 9.821084715098751250e-01 9.823189389533665272e-01 9.848355849484369262e-01 9.883068206567093839e-01 9.866950501930423778e-01 9.844581038612434387e-01 9.876883213054056254e-01 9.901331292641196713e-01 9.898927843589159226e-01 9.915692829348887738e-01 9.940747967543506203e-01 9.938446205266897593e-01 9.934512733871044832e-01 9.942493761614623615e-01 9.952191479438154964e-01 9.954819871703829426e-01 9.938617138262522133e-01 9.938404117603623078e-01 9.945385622671887305e-01 9.952572980347597076e-01 9.966992800530753982e-01 9.976503126506753860e-01 9.976504786622593102e-01 9.980590675708043147e-01 9.983731660360567473e-01 9.984779194266618640e-01 9.986551642616506852e-01 9.990079613462254926e-01 9.993393758732639354e-01 9.995033624355047497e-01 9.996026008989237210e-01 9.997070006299922929e-01 9.997685533215920906e-01 9.998336574703498014e-01 9.998999515503660396e-01 9.999220515307329915e-01 9.999204994015705728e-01 9.999556589695512976e-01 9.999852192195868295e-01 9.999950730246457420e-01 9.999894374332408686e-01 9.999786388732953002e-01 9.999839593845165631e-01 9.999857329008385864e-01 9.999863240743439574e-01 9.999954413165518252e-01 9.999984804342324507e-01 9.999994934775644495e-01 9.999998311591312694e-01 9.999999437197039098e-01 9.999999812399005261e-01 9.999999937466335087e-01 9.999999979155446139e-01 9.999999993051814640e-01 9.999999997683938213e-01 9.999999999227978664e-01 9.999999999742660295e-01 9.999999999914219728e-01 9.999999999971407316e-01 9.999999999990469846e-01 9.999999999996823652e-01 9.999999999998941957e-01 9.999999999999646949e-01 9.999999999999883427e-01 9.999999999999961142e-01 9.999999999999986677e-01 9.999999999999995559e-01 9.999999999999997780e-01 1.000000000000000000e+00 1.000000000000000000e+00 1.000000000000000000e+00 1.000000000000000000e+00 deepTools-2.5.0/deeptools/test/test_corrGC/extra_sampling.bed0000640000201600010240000000002112757050136023501 0ustar ryanbioinfochr2L 1 4 In1 0 +deepTools-2.5.0/deeptools/test/test_corrGC/filter_out.bed0000640000201600010240000000002312757050136022642 0ustar ryanbioinfochr2L 4 8 OUT1 0 + deepTools-2.5.0/deeptools/test/test_corrGC/frequencies_data.txt0000640000201600010240000000147112757050136024065 0ustar ryanbioinfo0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 3.000000000000000000e+00 2.500000000000000000e+01 6.848780487804877470e-01 4.000000000000000000e+00 3.700000000000000000e+01 6.170072511535926729e-01 1.900000000000000000e+01 9.400000000000000000e+01 1.153606642449403141e+00 2.300000000000000000e+01 1.020000000000000000e+02 1.286944045911047274e+00 1.600000000000000000e+01 1.240000000000000000e+02 7.364280094413846456e-01 9.000000000000000000e+00 5.900000000000000000e+01 8.706076891277387819e-01 7.000000000000000000e+00 1.700000000000000000e+01 2.350071736011477341e+00 1.000000000000000000e+00 1.000000000000000000e+01 5.707317073170731225e-01 0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 deepTools-2.5.0/deeptools/test/test_corrGC/mappability.bg0000640000201600010240000000006112757050136022641 0ustar ryanbioinfochr2L 0 100 1 chr2L 100 110 0.5 chr2L 110 1000 1 deepTools-2.5.0/deeptools/test/test_corrGC/mappability.bw0000640000201600010240000003112112757050136022662 0ustar ryanbioinfo&X0??@@xchr2Lxc` pᤀ{σmsO!,3;9?a4;m{A Ogir^kAN.f$8$a3@'I3F]N҂1s=@YXC4_8{(Կ_K,ݕTsbM]؊jy7O_V2zVcYEM+PY_ohxBC6}eY]_̢y~s{^RWgtE +BdEPW$F$51*(S1KGReI,5TP 9xs{7fzPOn.};[[.om9qp*oܾ(a8>$7GG;#rx|v|xv9;c 5cKS7nY~ nl= ~~s?߲|/waJ `0E"ʒ((NsCw㳝sr2>;9 qߌ <c˱'ER-ʈM,œ-]b@E"LX_0ZĠA(==t.|_)?ƽ5 S(2OJF\%g&m;i@ǝ9^!(l5kc,E-4CKg<>>yxxvǮSٶɞM<;=޵Ǟ5}}gu]`*k =۾em[߰ƷNΎGhxg{3μkW>}j]^%i- ߺK&Փ-$1Xp5O\5efw̎ zfb$E ܞq=&3O0 t|dO#aP=h" _P%-n=o0_Ͼ7-`\j0\|+:ˇ"8UFn@OY_I\'})xkršd 0Ȁ%Km]gt-|T0pLNb,pwT *10]$s`t gErI@G) =+@]gH Da>aag~K˲@ealx;;Ƿl7u =2qvkt2'4-gZB0w6ղ=e}H-O9A!<)EeqATRj>|qU*p cV1 {vxI@2Li !Aoߧ>Ƃ !2`3UPM2:4[y<1GvN d&p'D 5m"p<qJ|%Ӄ!00^xY>E2zkhqm4\71lJiׁpHzq&5ƒc$h0yc :qQ#~^Cu< Ki$qnۗb94جU] ]\²4[ Cx x1!(,걊0\plo4 opðXiF@bkg fDB\S2`cTw ;聴<1G[@?L0~)XE Q󟝎NR\5 pnkfk2՝/x?rF EO(4UM 魛vCT5dYmg[N5^i6Q 7-rP8zT9d4yzdM]|8`0B l yi= m7K8U᝭~`\,0e% 3 nm0`7oXLaZm1^ ƿ,χ`"3, }B0>><\I9A0!xyMg00/| |Z6uT0bNz\RAPp;=oQ1x1EltmE\u&RxfX7ʊEʼJEG ZY F?j@b\isxK' Kc,LfrgY& "vW-ۻڝ}\TΧoQ]8eQ`@(H 1Y"(rFvκȳ:KyS( 81*_ M"+\ 2>:uԕVVR9|䟆7ɇy@1YB19ߊak] b?Tt ancy#_sQSQm&:b;lm^C7+<ĬG0(5ONن0;΀hB.+GghɤL|MCۛ^ԛj~*پ%Ė%e:Iu koZ"#űFXף⑕, lVZ_(sL\"EI?WLg]ltƣ"VeX`Dt <2" aPtޭ0{;Y#A/<\5` eaEVXOzyaF4>F ,oM,Avzo9}G1~ΈTmcjaY˥b3vuƀ.^:.?wߚe|e zg>'SE^JQJֲ,Q>1NzOsZ/D>Z^5w_W̥.y4 cr='S}xRB06bg"3-PO`bu:zIs;a!(L:ZّʒSb+&هME7UU$`y*yJ#L-\J>ƿVP%^b,7ajI.# `MՌV fv3 1'Z0z0R q0+P_+\,(FQBlVhx%xglJhQd+6uS'R쒰<X=pyR?M,Ց 9{ji-0r^ t^. ? &x =+8iASo"P&(@#p˓EUqnn#uymUG*ruU{K gn[܂7F{5RtF0"#YT>D4FC*T `S+Jl-"3=F|d<߶'Mǖ[N0ǹ{=vܻ;l b|hW17a!P4 vĠ儠T|;1b|H+Fy`z"dI]bE+"6kD27P$ ¦ :\Fnf书teqc&7e;oM Fq5r^Eg4Ԑ("G8LtcٷUc_![X/5@Q?.LC3ȘPb-uB}abXM eF0TCd\S(3#Gi^(|7|9PVSǨk |T̾q|̽N V?__0pB Y†+.1Mm Dyy1>0౾dAM%q\',LJ"jq6gU/AƯAqg-a||GqTQ]UO{+XH .8)Hz* 09#2Tب}+l!0>PnaT",si=ݣS@tBlǭtF9֮;=b0{j 9C PPyJ;Tȶ2GF%4}\#(&UV J.v& 0C El27DJ6:Բe>}JAf<:(`cXa^Se*2 :',*-;<;L6l_`oUmJfYs MmN$I@%W;- 1;0>(/KiANj 󴌥'Dtug\wN&rw'3]݅H|J(D2߻Fa,훿On0ƨWTH89ۇQ>f)ce]s@\ػ$XwkXwU(\EFW5U"Ldx<'؛^8Î\Q5 "؅8_+4UtŰ!Mì^J,n1lXΊкrG%^E_12d* qduYdr?,gbEU1p4.)SFUĺn醥'[(zEK gZGmFyy j#זhEZj؋<C̔nF E6DŸBGLY@oo={dmcBl˞ڶOwwm#89 =0q{E HRfhoG@ }UjzX)/9{dj]u}=w^Z8ğispo|y0QYDYCþG!\B1Fo\,`_F?!W6a6>h- ԪuR ~kW-? #P襛v+~p8!np:CflQp+~pEԎFY-_7 ZhT &$4)uQp Gi\{ p65ceF /0Ԟa37"mځQcs%A xʞ۩9Љw{tqwy/_HYQ];L 2;Iٴ(~!xޙ;o=Mf UBӬ_Y"#Lvt#T``|<ֳLϥ'a&;=׃*O]YOVO`tuz#~ZpO˻pw Bغp'Cd\LFVC>PעޔdZqXP /1׵rK=fJ' b,+V:ZDIZ Sm #3A/5t<5>;0=VR4(&0 "TJ7^揮5v~йߵ)㳓mxxFÐ[٬zZ Eޯ vSx" P[Nuĸ7ĸ_AgY* q=Vlz0B(A@=æ(P8Y@N|Uy)mViQ@ =RZw:?؜ǚ}š=hJWU1vQ˘T┴/N#Z&P"AbN9m* gC 3uK;Lk7z7[t8c| APSXo XO_,qR{ݢTRy[0z;lg[ [DHN]z>7"tOT۸jQxi:톊W%k:vUqB4~ >;6VS0O6AQ{T2Ѡxà/1OsߌBփY}\$XO=ejC7?0j'Z_`?@gti`aI) 8+z^Ou5&obc ܒ8w. B?RA[=퇨Po (ϱ뢙w<Fx6X2x"ÏүT{b ݀m3b֔\ ~{kX'rfS/SD}؃Et Wa>ms ےA/SHٴU#Dֿ<3Qz.ÀOK{P 1Ӵz.S!$[8>w0D wb sSOXo\q11-XJ;6|~m+jNi@ E3;XdI:7سkAO67v6 XK7p# a=Gi8KKR1)) ҬY+kGiB:g]8ŕnBY6Ea"odܕc6`YXQe"k5{2$De",4-Q5]rϰmO^ݖK ,=;޾<,UT\' \ DvbUR"{u|WoPPezQנe2hr~' S}”2XO7TTbaĒuQ@ qeVhw[-UU+ hP cDQ,Y*ZO(QX_Mq-X]Q\c6e͚#Xan$GLK%JKa5&Pnukp<{+͇0 -_lv#Oq_H 3GLeuQ00|c-F2_DyfvN)pM]a""j?oTj K^ w⨏H=WY^ºcX]%舘v68Ż|նUr 1u(b-G|>_dk(Zu&#`[f=MBEdk,nlS6NNoFltvzԻ&+Wk\ A<[4Vk4_QW7_lu^Wk#Dž% E XZnXAsu|FtXA }%uE%"WC=O7OGF}gx7eI`Yl';6l_^2n_i0}QX' l=>qlW zSSrqk[. j\yB2~XXR V 仡6.f(G?$oO뻌OCki O,wvr`cLT m|CIe;isٷ~tnp PU*o_ukDRmmwa*83vXHBaXsff]A^"ǯf8Ի(|>BC6=nR߼VIFB~0X]J"G )!rQ1K_ \kvq=(" 2obb ^PN.U8,Ph0ZצFƺkM}dwL,kJ{q={N +hi.N팜[}_t`~[ӘMl~.>\pu% p+U|7W5HTsOGiF}T%.A&Y{6O<5ğ:T040 f%0[$ z0PQ#sՐ%SIu556l)zł^ay'o4~#q_xay{ĸd,*ve y%Ұ`YmM'po#EQڬT9ʎh,Dׯd89Th6=^{[gG7oTvGsn~RaϮ \"![DE*D3׫qX5DdV"~Tˢ7GVj.`P60+)K *T^m.YFA jR^T^W-*oDfj;բ"JpB XK%h]^:gԺnJoaPg |cZKټ9٦"Gɨ]([b SSRfs.b_p+61EpRDҰ)^Rhr dޙ ȰP(`F/FPpMG8ttΩ-.q->a2pϏXٯ@% jĐmFֶ_ۊ,kL9K7GG;#_*q4DsޞQ79cJ߇ pE<6jZWѿ#ơ iΛQ1>Y )Yz%GȆUާp _ 6#Ms 04 )Wi = B %;Z/P.|lK=ѥIY.>pC%Lq4%?!:g-ZPкGv&S(ļ, ai58q,qVy!,EڈNtq-4 ƩݬY݂8k1d7?VDKwݵjX,?2 ׁ6O)fU,DQږB(%㛇bNJ?NV$P^'01y!}lssgd&E:d S8VY2|jZZZןb2A/Y)w11˛ 2j3ܠZ_*\]ny8 #8 Z|˼^:[ϗS1 Y1URLmQf`jatN6Aq/A׿TXWU(&3]KC-< .GC;Jce{u ;+ j>B1h)Ƚ7عhz!F /W VxFM2}}lB7@uFumɲRuրA;3Ȭs؆Y+Rz5w17fu%fjExʇyfl5: MAb ҶXH/6)R6t(# $ݝؔNw$ cvpx+HL)Fw]:70+U-˦Z_FWb/}.-PϱMW&#MX6b8 \wvѵ*b`+UZ>&:Y>1)x@ǚ$"AA/\,OQiO,*Y/|`)dahzؾxӺ,5Ѣoj;&{3ww= o.8ij%1~T?ޔFsu}6)kblK\V7.E#A2_8ZK]Þ[:(`~o3j.0}?W#8x] Z}@ple(-Ѹ/o7%+]48>ZgunOW889_*7uǣ66(syy~~ˆ|J{JP: 1C'޿o)\<Ga~)@o3m%y8/b3 BuV ۜ1aKg Q񵦨)eh S4Z&^O2/{8H5/kxBC 7}{dy]ߝY\g,>N~({gta_QDAV7(a W Y5h1TJƘ]hXa?,*0]{ۧ4=wz|~fԋvO'߽i3._'/$!W<,b9g:ɹ|݂jVqUIk8@ x jP?X ?[ƭOq xV aU'@2_xVϗE8?-% [1Oz02fA`~D}+rRQ*OJ4*.NӃۇק/q&51hR챁lFIR'` NR}bܯ >zQ,&i^¿Dei1ω$ܚy(˦TP10b Id8̐ʴJ2O95ND-JOJ!SI=_ `j&h䩝o?pC ^4d(t nezP/(6> c ,xoD+N ;;b0mT[i?گ>1f rgDk4J4+&(?)pԼEECw4I*U⼌5(`sbҵ5B"Z\3hٴ*,͹ڻs[!Ӻ ~a&fǠcVyYU"QjBL.ݎVZρyV4ϊ*-:<x(𖔢3~- }?Q໷i(00t,5m[@\mFjPSOO}dcԵ #~0^sxmz(-,E_k OIyE2T *_$KVܙRC=8XeSQ?R|IAP5cX*YAiű*C+.Vf虷@zm-~'P5Į 4TeIIy+;ׯyw&ũe;[Xrg9wzݹ?pv//S&z@ۂxUQ$efFѶt9xA~(!%L(~V[AXim ~9Pn;j$}[8X wP(*%sbZK|* gL0VEe7jJ'wx 2Сs =.. D|:`1TZg:RYkfH2⎡E0hM*ۨ(܌ =Km$ŗ*P3zF;+0Edr5{:>9d~Xglk=u61r7an8 0ɍF\& eWI /.Gv= \6*Y =@NMv@1B,9֗X>+qg8"Z% a%t\5R!ʒj W("q)*Z; ?6)5 b 5U3QF?ԀNx?ˎM0`0FWix&B*Y fB*&GcyUb76¿9p{(/o<M Hk<{cgG~qTo2Fgg^wvh29>:b9>yYU_ZzTpSyC I- 0B_A\%y{z+6qa.Sz.eyDV'pl `|Μ CVQ,-0!CYxw V4Eѡ8]cj7iKޠpQ{/1zEUeQe(2 ];=cX\n;Zø2ߥOJ,$*HE]Itb_!l)ߛK e9ڔ@%FEở15eq P]P GYoR |a fpXXXv1ӲuIFT}Ea1pQڲwD0nzCUD|V&K5~bxO`Z`U M(s |9e0ֳ7񭎥 >p3|I&zMIh ]Hf0=:*-ڐz|c?nZ@PL5TVFEߤz_琉!xUb4ц߈qM0SZTȪQZ6J$ 8a=wFR} <&ϐ)b4Fɓ G\rsƛ0qǘeٴȓ*-œwP \eۘ%!d{Ub5ٛ9Yc.o s=k#? ڃ' Vo l<ş?)hu͊3ƃ`C1PEAeHnpa v?ѢhE%-SOwO,BVU\Ƶݝ1q9QdnYfQC)ܩ5(Xgtd)>dj X%:O~wmQ8wGqaǂx]8S~=\ƾQ15&Z,yҙMc%a 26¨0 h)|S PCJEWK-~654)+|t ~IT,˫"I\$5ZjzT>w8cHcnB(UQ^h"Cmַ{e"FF QOcbtk*O,/ 2n,<E!B[iҶ*bA,b#k0̣x*` [Q!EI-L]L iJ: vܦu!; z^ֻ6*5J8w̕9BdpF~Pa1f&V3g64G|:󜴣[[V4<ֿһ!,K0(Ԕ綂X> Q~^26$3Flzg  0،uZ`o2Yn  a<ӂBе}^KE(KEf~AL8&ߣ(޿n,Fӂ/Ufg)5vQYeߝ ݠ誩ơ+KVC*P>gJ&@B C!h$M2[\0pNB%˃B2~䄰 $*\uq}Ω `Q09k?^^4 Fd*Wy"qج`3,vsqY; 6.C){V}5Td ccrݶ{oClEsmnz(߳ b8MhF1{`;(z1݆RR>SAF_Ke-w(@0Xz ؈9܆7s,LY (&Y{NuFWc?PT;h Ix"OE/d^/#~/8o|՚Z_= |zyģ-P~Q t 컗 Q^Vy,ʹ ,ksgqg̞*q}&]~E!zldU*VO$h$63L<|ӟز <0u csmZWo1G΄s 2Aqq ?./Aq=\eYT@q=En߾s˶{fM&f{} 79ws{hY{/YدsonøPt# Z",RpB$M H$'9, CJW} 06fᄄP(]NUWao[3Тr؆Κt؎;]r<}B eMYޜn(62NUg,~w+߻EϚ|(p]n2\¶B|EjS"V~`xGyFɕEg6D.>aAsq$S9& 1/MW'+M@v@%qdu o4p \(}ޕ /!$<x-BRPQQ˨n#JHD S0T ,eqכ,!}Uj_S#ASbFJ'4aԷ iQSZ*g[-b`UmqTȚ(R "ogMmbKO93B(c겏1;jT'6X 8CQLW`خ '*r83A&*l!S{8=rٱK o 'q.×{|FW%1>I%ҔJp >\ mCawwI:.k\'U{ ZK>$@l^Nl hjĮw)}PSqRfi$b?&ۻWMƩ`!rd e?՟wFWMkq_ P#Z`r=#4 )UeCu#uXy(B^j/w`i)qZ]6?Ѹр8jGpjTw z_mM "Lkqpmv",09U)󆗭Lߧy)&,nU-;R^d/ESZéDVϬ[V |,5(p Y!}ZY7.d[v71bt0gqyTQo"2#8Sӥ5u ih ~(u`qTd'FA[gf)|x%-jۣ:"o0>d,o&u'R|'3zdhd/,2;k}2S2%oj8j[B4.1/g6DSXËeY5wݽ?q8^Z/;lv0j` ˌl}`Z3@2 O{\iuT3 {_n1nעxU-{vbBݺud!vøvuEqwKr[ Nn)(uv-;4ޠXAzٶ,5-#c-`Iw )+K {#O50.ۍ* <'CCT_?ԭou[}\ U>cRmyš;:>:8>d))N _uP507M$цgۗs; Ch4Z6IyCH_]>__Qj:k Gu_[+S{D珈H%%[cQ0RQ؉00D mq.TO˦ |$Y2O“?]lkC~Jo(XZ\axJxUZ>I Oz.zXl}yUG:>#[ Nu:5%BEbZmgjYuAO=lk8Ve/G2 ) P5T a! -;0:ͅV=k*eճvM/Fi [=a@`6}wҙ]s tFP] uyFڰ.3&iV#K1!p2_8 <*q*z^יR-1"'4Y}}C0^q,Rrϊ8Ȇܮ/ v=E$y1IS8U ) M]m=`0KXsR:>d.);O@Vo5bl-%%X%\rڿw.fN}`ϱgljdY??aZSqU$@(uS 3N.͉Z5ǫuҲ=8-tn!z2wq_[3uSkԙ@># ϩfaURM)AMN6O5$]Vc]T Kt!J!įa8qt \+=c۠ƪuQ֋ ٘ŧec^v|Fu7골JK-B`,6bMU@GbVhZSTb<`= >c+aѱsҨF06hǫ(E#8 lٲDz p6[3AW E^T8*xm[>^go$̐0D+hZSRԋҭ:P/Q/%=o 22`}U>Ų٩aW`idV,Ϧ'*}d|SdO%y1&yy#b4}0ixhxS8 ,&y!Om ؘ鲻SkAZ@70hیX[ c>!N|!U8i)ɚj12ʳUӫ.8[$bY̪_8x'da`~1m;ɳ5%D߾?gvC].$9-)pha˗m2'M|Y S5͞7݅m JQl*cX *7ǬXFŷ%["9JW umZ}SWqBg'3^Ncw#i{3ZŦ0d[B棄QQ @\mN&RJ=|'E/<{.+m}kMI#F(xr!GV5U\6GA .}6ݫbłl Y8}fW:-{8[}Т (vq`EdjwA3 \Ɠ22T\u&a`l$F 0s3h+L߾}$ 8h2 "LQXx;[U\5.ShQ,¢.K.`lf;s\U5nEe&-=1:V7kT7߬'67m- עA5'oHncM#a=T8y"dZ.ns%o40FXEG(ֳTv*kke"xȘE.yLQj v0C(R"=c8'}IƥhSyk? %b-Y¶HEDA2̝|5R9(\#M[MEGɸ#7Ig `75bNo"aZ>dn+f_8=e+k^owS=bbT}ua>J.I ˺H (EGA1U'** )jD&jAipKLOP/! bQ?K<x \ǙD䁊!?B<,}`sNO56"]%<²G߃>㨜'@u& CMgxɶA% ,kԲ OWh0+KEM 4%7aUDE8 JpGUU0^yΰLqj%DC c._>ͪ^ N.TSqE)l*&b; 纞"vf 6/x.jVՍT5p *0EÊ5uv?EՊwS1 cWO(B a 6bq/űc5x,l{E9E^hp%q,c/_t#-* Qs6{ aH}Kxa>RY64tYt5&kE' c93nQã_-ÍZu۲AY$,J}cyjgWMm/h$+йbZ3{@cVj+b_<''+faQI!<5}6;OA֟7-_v`FWWAPPr5R!Թ, ‹q,NJGts=fl$&L6ٲ9Dx a\dd>~Om؀(aDþL 2 OQ,TNbZ,e(6xw U*.3Sx&X\1u㱒Nc )ULʪLVb0EE4Ƶ&=P Qf⼹ﮤbCn>L dG*+`*H 9*A' =(I(7:=$(B.֠D1E)PO    NnbYfaęwZs`+@u, ~,[5D"t5]gP]ezX# ҳ<6;'nm۴jD%!(}* P8A'`Ъ-m:ss%~6Q!*Sa2>K|A0iE1 6JȿV!X|fy `jb[iX|`e0ʥ `c!0^ nK:'UĄBʫL %}Hd -\F?"W0Zv~o(c"S Ȇv맔UURbC)܎=}`4V}3gZ`? M(8a[ķPF9=1fj)#><$o[_8{vϺp xdv]L,o1{`{ٗ0g҃0z( IG.TB@YI,5i Kx"0wt #vCLCh@تZ941.d5?- mG@)`7#qϪEqw߭Fpr?l*.#̶ 煈eնLUϟTO}ҪXEEQ((U8>u6Cz[Q) Obdq(ܵM_WjQKJqaghވ-vZz'Eg ˵5}vŸɴP1>؆~et E?._AH }"WRKF9GI2T Yh -lx80\J X3ױ--a4^ӶWo>EA]*Gg B hBrY3͸*øNsDagCj3-w7. [*h΄)szA ]'0*B\0Lv(`\ۯ5KBGAJq{.Pc/QBq/ϗF09oDVcҜpS 2u]zxSܔKɕ98Ro1\*.e8*]\YyF̛rGXAW>F9* ܭ=$xkC%TxݚЯ7a10UFcw8 a Xi5h4@}̜ŦyC 2I+ǶL׵uQ1OienU MRvkTŖhXs/ؐE%5BC3}yeWy_kId1=ZowsKs3CyA#S#0 B R6 "`A PPr\N98Gp`}g9g* 66u36"쪍>q8yfL7;/]Z0 Jdɲؘ[N2wNM&&{֕++WX_, }u\ײg߸_7Si7nzYiq+[oyo׃ Ưlq,$JC= X_,:O;  C+`0Bjq," YiP+~BGAa hYqax}} Hb ~9 rXĨa\gdYfQo=x=b~l~mڮ;J2e 8 .YMZ RxvYMY*2`|uM3%ڶgձҡLAEP;6ϝ4wvwwCPH-d"oRی(be|(v/8H U%$O| I$5}Z(,MQc)bbۏx-.`\%b0j `NxxvF0$jieI>G߾vUGIt }-z⭺`#W)UaYr+'Ť%-cm}h*ZQ2IbAQR+dOBc5Т(ecTlԒcyQ ull^-Rcea x5*h6>ST z _≠ŐqfvNzg롨y< 5OŨ [iPBaK XDK/  ERm%|Rڵg% ipE2Ll!ՋC Aܳm{O<{) Y2 P!mraY >'ѵ]{Y')e^ Qe6rj44(1DIWtmܗHR"@ah\% t8d3hPolbY#QRO%%^MylQ[23g3KnH;6nIb %dTA x.ac0xԇ:{ k1u Üm= =홾Z3k۰Qs6ptEVxvP,% cx4鰶~堷.zjde,,) PY#|_D7pd¿Jr 3pC=gҰ8F|B0|L5h1b0(.E`2Skх`|E|P #}y\R%Gղvv.ڳ6ͅpDʝ!L12ԣ)Y9 ֡E(BTYO2}w<+ =[Mȧm qS:RUE>:0*#j`j_%L%7 ޚT'!_h~-˗h`#p-ߐx?ٺP#tU1RcG\?Ke24 * ;Mg85򍀍97fC33ʿ8*ŞNyUr.4]J \PWc|֣G?? EaZ X|qWaYUE$P$i%kBhq_ZGS6#6GIt Į{椋:N<%Ǚ]B ],+N AbWqEYJb&٦m*WQ4D[~0xDsy0U` #'`?fRr a{~ɳ-I)!I#r3K`b9-S&[^QԢSTSӞ6QWQI%\u@v -,Hig('"B\ g4?R&]qZd0~I00ɏ e@7kLL[& 2UV9&1؈10Ň@Ee:+`j`Nu4Gᄬ1z65d00F];$N#"NbIfW3s}h>,nM~*T\VsyYaTt}\>FQ@4ޫk FL!Wh󎂹fD (Ң(bA5 jДxT8ݪaKsALx'+=> F$!;SRd6w7sZ0M+j(ĸt- 5n2w52ҳ~c0-X˗Q,x* Rא icO$^$LdE05B8:3OÙ9{2#κ,Y!9}3G% 9ڥ1]J] κ8HC/B0!SP[w7wYۇ,vg Kx ;U( eEJ\BU?ncOg$nNLU(L0M6l3OC7;,>}CĞc IRnzd\2Z . xϣF&, DENK =^^a+lB IPd}$a$l'z(oS`DXHѡ DImNND YUu(^kġUCecu]Rn Ct@qA1Ɋre7wKO?e L*Qҋ\O$5򧺃IO}A- 1}0C ޸57IBe /4A2҈CTbZkutV CHo_w?r61GIS?ѩ•9i,;50pLݹI>By6C;qB K팓_acf@)BX1@I;̊01UŁYjQڹ{ؾ[5[igz"eq—.b*LB|n&Ǝc`i]P%'iiW)³kMxNٲ,^" R,Z!x.xF5Gb?VQXT#l1Y6R`mxu-6~Ozi(V&;ucm~^}}LR9e$ Cg $Q(VQ(Vtv4Hyi;QT *W ԗ0K;_fq Jq¼o5󧮍qx)[iLL}DC H =9P1]M }c+.H?&i4V &KEmɛvh[_/Ű[ㅄOSxV!5-pMvϴnXo.Iw/e uazÚ5GzOm8JlXV2?V /he#V?T< <'Aʉ?1:6#WiRY4;(.V0\aʫ;n.oF4( V8•ԩF i;»$q7B'%hi)K S`KY{Ʊ#YP~<R RIɒlxpI]DίQƞD6^Y#,eZNFO$ÔaGuh-Z&0 %)f@ d@*؟LZo:uNXty_E7HW慨ny.mee-ܤ[ĩA"X5O=mZG,bT"K5³7:E2= kT[KAV+֏,1 `]L5\˩7 h5 Vp恬 ytQ=|Jb=6 ϢӯiM(b=*2QB t/Qbҳ߲ڴe<{F׆ɲH愨@vpHQ5n2oX/⡥eJBk وR_KʋdJL4<{9,Zb43:5RmՂ? ϢSL%_=ZX*,"St1kx+lnC:H)ܡBm/AO gkܔN}(-e0K$vbŭ.:b (/bM_]f%61K{ :nhbͭTўڔX|a3Vx{K2^00هD3 ў 2|IV. KaځQ )FoN(~Oрs8>z+  a!Ь'w-5߼jc㿩 TM(E0 k)۷ւCF'F-8&a`ɀFKUV_(!!z Cȸ-)2hܳ)tj'ukcR?]e(Fs[)g;JYQ$ze6Wݢ~@ېh/ؘvI/0ddZ&\_AY"aC ):R !\ASâ10VެA؇gY̓ )K.Vo" \06tDOw4{D:0e̓lmNYޢ܄opQAgSg!\.7Z``[]![QM- I"Oj"6EH߈"saN ǽ֞M-\4tk\I 50ZƩ\BTq(Ij@oH` 0K"x<57{dϹSfEoQ JP{"Ǫ@: #κX8HڃYwޭ£cy8D3B__07ڻBEU(r=2߆׶O>a,qLeat׹9\|.3 Qɧ~$}fg `@T`Ŋ'GhJw4Kz p]Hj2=՚4rzxlQRpӡÃ{&,͖E.比0f3i!X pO8|guG{a5{aG1q#e{Z| 1|$ņ76 ,\E'z.˯Uƛ]W&7F [-[1f*!II6"?SkGK2¥;&<{0Do戌!}"3EAZ+/ua|^Ua鈥jLAPᑖ6S}^T8p'Ynק4~kgYT+Dy[ekR9!Aa̷8?vŊ؀ѕR%S;r3sf\}Ʋ3pp-rɉRb"ƣ>lQ"]/I*aH N{7cEizv'C\4/A.}G.} PvC Na2Fׇm|mbD4\жa5(e|<#yXo+~ܖ#Vb.ߥp֏^dnHݑ8!<WkQ6*bǡiUe?2rZ|@XҍMY;>LUm#wT}m-<$zkB!Da6t ]OdF2رQF=Xq+plhD4Nzt OfQ:E}h]Zq@ h0`4.8+~fC?Pwi ]8iF)>k[p v?^sF;iw&yT,_]括E{0dSZ'm"~`o)\dggh7zM Ym]ڳ!Q#Ews+z@87M`>w""kgF"["rA0蝿H;Kreצ 1GۣXl}ikkkK5A3Zeb [;,ҧ}Ve_LsPzYOiQa)EvVgp<l%v0^GD8pJ(juͯUYYs.MI@ogaȌd::?㻺EbMP#(⃖*};}lS(.ԹTÒ ]TJW` %at`^EEx}(4j/_[=Hs#WI_h8 ZxLU]3u|}[' Q^A\:vv-q˜?#ԚӛyJqk?FQk59.<\y'=W(̶*h)Fڔ|J2;wr+< z@8,$PTX]t%K@7jg:Sxv=D5{mH&Wmǧml|[;!Da):T.04oD&z0.dcG{g \_n`۔eF=mq,ooRkX,$Rx{1=r8biD='D`A"Xf r"j㊄VM&J7տ@'LǩVFPL`}[~A{\GaſQjz◴':{(tgۓz׽#W_H(/p! kV1Fuklfd*Xθ)Ǒҷ *-`Z(kNHPG$` ?"ŤcߵJ8(pqb߿[o:^M07K3V׸Shk5n AG!S5Sޕ k|vMg;" 0.K/?hVGMPI垖,~C7,P,Ӏ7o/W6V:`\,{ZU;-uJH9;ye[aԚ*xhxW*vDiVa0͈a[{2M,R"8O#jT1v I^p۝uĮa!vjxg= arm0o!\4WUBN$]T/*Mۜuf;qcS-!76jIqhva2W+p1G'Ԟ3ѐRbkfJ Y6гUc qA51.q*˔nH)Ŷ;P'Io[ሰ2 , B#Áed-bg ?ket},BQhL8Jm@/Ż IXdA`8.ܘ7p0]UDU=h/oaWF?ljkPK50K_ y=S/1a8I iE2rp\\=iĻ2dC GpzmHC\ <>8"')qzJF;(ĸp'YfAʏ E!)hB!zX`y"S͠zX<nģzf׌>|p[f#>dx \/X%qwknX;ϞDgsN <π /M]\.)r] ~^sE"ؤ.'Ikf| Z6PbXƤ4d0*x˚6FjdaT9`)0h-Z ƥE GA8‘)09*K[729fܘpPL z\" z40CL+wUHT(C"3CR$@jbH"V!DM3TaIZ6hI(ڹYP; <4@WytIR= 2Mݚ|^1̕-S *x*$U9I`m˜ʳP@|&.)Z @t̐`DyhUɉ~X s4tHa$5,πJ󢨒 `(u .:lGy` -MGq`[Sě-c{X)@rM؞wSLl:cL 1 >&5"@"SpN"GYC)a>FZ;F4~]]G$<4 `ȰspkR^g"G()j+Q^A0b\JR!\!hQjQU'eG3W=*'G`RRϗ8!Wóh*LaֻLc{j>=kc Fy*\LLkL OW#*JR=ri-R,u'K̋$@p,s=Ub$J䄥It-5wbB 06w-boL7[dj*.I []qKLEd"zrup/$jJ͝з@cD8/זE\yVJX,8dg%O56ډ2$^) $1xЂߥs3!Ns)b= nxi[c;嘠\Ě"P `nSc`BSOgDxa(DUR\Fs У?¼i=^!~.\ *+ +M#= ^b'9syZgUۑާuR#U 51x{?UB _vɪ<(Hs E܁#BֵlJ5~ y*f K1J0^//o3UGҚN%9\]xY** OE 7ogo1hW[cœgUoVN=l咱,OxX_l6ܪT5!&L: ھWk}}FyE: VY6vaPA(N6 QZRO3m2Xҿ`FRYUc8 Z_31Qq&ƶxq<8PlOɔJLnXNQɻ=51_h`t6 ^zHST0Ȕ{U˭J&<;#Q%k)wjNTԮ2 t=rGZ,,OatST 4ؘ'9Ea9;,D2X[jxѫA :DAR@I&GMv:O]oT@|±/{ ,.1~MSHk ,EJzJF'g[C'xUu3~c-} eBMH }e 5R;;|$)zbP#ʣ vN J͓WMLJ 3~% FX-2O&;{g5--o%Ɣ.|}hM>Xq`(ɄVl#t#"ƾmɬ}D1 M2A6:lhGLx U@涋}*bǔ2 aGn QQ{$ĸ^rx@$vKw:0b1 VE kT? EI2t) ' c$[S׀00M{kbSvtv zé r閹iQ3~hOkR8QUĩD9yrM_h`,u$CX2 Wbӯ?wL 6NJĨa)kݩ%-<Ht{iqrǚìuq*-9d(zF3ӶH1q`pqA vۯiyL`?նsc^ʲ!ˤĤI,5V)żZ!䴱Z_^]b&l`= Nʴ@@+{ݳ媩cG#m.g'(@X5nNNϨG$n߇zv_"]P0gRJZrduӴbzA̔$$bc2W}]u?ugU;kHo{6^ͫ2KЏЁfCޑ񾗪=B",M`J d=nE鶻i6&$Jɢ#1zH[ 1VUQr~l:eyuE7JdGY ˪ȢH$%c=-b?޹Ұյ`6>Vi 1xZDYD<.#8F}Zl{ BTARrQ !8؟X`X՜&2{$<*Na=7"b]-[GqDYݶt?{~ÄhDb>KxtEG$`hke+0%"`Ri۹됇x()(HAOuE=`I #iN)D zfaL:$F0MAHޒDMYmbN{Q`<8XqˑoH⥛AKFK!$N" ~tp<źR.-qLj7$&=׫+d;Y,c)L:ae#(6Mx5A4?$5(M; gbV Y] d֟ U@AUEāc;幧=jQsնklVx>1Cs.J=ifvaoom4֧2 i'CEߠ<2Mƙ| ԰uxPݩEd=}H7,;R}RltW\ҩm\|sݼhm72,˰N7O8qjk}b<,!>+8Pn9% 7ʵX]gݻ(OjkK)% ǭS&0 ٠ؑiF2o`ko4Nը;~{ 9QR/k(|6"͋+] ŗ>goVe^u%c1g@6kzlnE\֩NVސC1xkiVEQEbLb^lM:_%^x!iRAzWN& 80φ[oOA,es(YsK" 9+3"lʂL *qtxASLc9C)|_`q`)ᖒb>g%*Vt|Uh-^.-a"!Ʒ>50EeyPxAhwJp%!O%lyXuDiTiTl 0ky0)2aߜnnc kc~Ͱ |.=آ^f:Վ3w*ͲzGLl\]ߵr{U;vlїz<{E0OzyVJɆFKI1ĸb!%=:<΁iKY0d`;Z,p7XcF>X8]"p0߸m01H]aVMY;>.Y2gR4 +X\ |=,B-`3Ԣ3Jԛj&POE( ʰ0fmn籽3l)vfϒ $F♀-Lge m}S #pQzQjz7aRAQ˴7B-CWUQqP&U2( ʶ~i"DѸ!wg% ۴ dB][Y(b@< `U;|}D>]R&vBqNBz[k%G6Չp8FSoSKB,~|KS:IuqAFfI8B1Ƽǜvxe qrq|kuβyVÐrR-+~WI$$}=/N Įk9ܡ;O['Rc!bRd0l8Vmxf6,{Xl$<}xJF&.`PoT!$=ǘ9}S dmN505nXѻE}n;@$SkWq]ag_4(_WtiTDy0ޠZB_*/J* `u;I='1ؔ(t ##d$45 !GbmڇgViȄЁ 407ˍfK [B dzvԒFifo$fjK|QC?bXyA (7Hqj>% 3~31|AR&r$3Ğ)Z$Dð\{I\%5Ǧ=ִkN1ΰLmѕ>O=R톰kDIPH&]{\5BYltqL[t_%i`YA6<6|٧P`ό\I _TYVy 2:J !_Y:G6ٸ{TL" sXdOʼndf]': %jlzMXB1^+@2EX׿%KH٫zĻx>#(-a1`$u_-wj>[x5d N!ơ^(]It-O;Wg272=1~^S³?h)>{mۉ2 g-l4SPw=neƎ劍Gl^a-Z][VEc\?46G󿲟ưԎD27q1_Z\|l7yO=SJ]T3ZzӾ3j?ᎄ́V`]v`N.nhh},k5Jl?wa$E_E ٞ{dp-WᨽxKӣ$匫8"',5glq[NV`ѧ?MA]n*@nby՗ mLN{y-!: Z(dR1Y6$ .caL:0 1t|}_mseźDȌFgl+Fqc5=M"gnM2AS"j``{,u(NsJr- 51~IN(,*+B/ݨ޵zQx$hVO ib=ka28D &Vw\ nT{u0ly=gQɨkGnhpUo¡qDOw֌Ki\88CTiU+>|c::8W /O;ʳdX%dsE?jz-:yW`4tU,X6hPLKEl´ ^}FKF=DL|?P[g!yY1D㜣Z ub#5m,=~z3Qr<_5BL&YYȬekґLI x @ 4V8#׻n[|6vMG6يm,h]gs %326'óMoSʲ>su.osZ1aG\.KR/(m,Ԧfr:s lƶiAl'%ԜڞxP8֊^"&?م"p%U$Zr0\~1ՍS:t G_hQfJ PkVOPpxxD6>L(``RobAh(]R6w*4"sQ0O,bȲE~$N=j*u4^0 μz,S3ǧq0@ ~tL{Jgyq\:Y,1 +I)\J0tĸ]_aHʥE _1o$EVcKGH jX{OTJKJ*Nڛ?RjQ4Džޡ F()jK`뙤{sYR%^4'9ݜK7B8ϋј@e{Ju/1vI 'A+d^]-;!/pkm;jNIN`?ݧ58ǃ(spsl6\=>uUߨ awJ#_?.8#A`<`*\(G$wJ_Jz~v-KYYX뛊uwv#Ν,f ,  U0Źd,zD)3 ENev)Lp*(c2JO= xg}TѲ{b"p( U@񂁅ePI%Ep4| EE8 ,#= K-5@bK- &?.3̳qjoJl5 #sb}F bdŚY-wKۻ[z{ۍA(0:>ZQ+(l\}EAW&U-|m<ߗ`Uġ" E!r!혀r )8MǭD.p74 @R|YUS1A9 pfJV [A.-*R'͚nyAj; &KO/nbvSQ4w l9[}֯?_YݷZJ}w`RFmYQM2:.=$?/`BY*@ _I njjwW]6)a()欲(ѬkhtHQ5/4ge&zf{&Yp|-PD]",,J!Z3}-[hahO5/m[˿זC9 sm{0_JI:[t_ E e=iawq ֱ)m[b/9)~.O}K"WB BzQ l\uK- aq-JMӺYiWZ(Wkf HB_%SݳأUcӱwlvtC mjӲTm7O<}d ےEiU;m%،.(Y~nƕ*i+@KUݡWӣ䮗ePt` <ϪȣdIBqUl{.?zǴP<P$2q\gzTH@,$zr?<A%.h`4 <{  9/r:2\zJ* QaTiP)E+WL.6JG }D;_X֞p0(0DcAv-0b\i518AUq8CPi׿U-bo+;_8"I^BgqeխmSA:3eEȘG`# QQ%aG `vn\H5{*8TҺ1jB4WJ1؍IT@4ó8*C= LiXiXػ𩁓nK615IgwYWE pͩm~@ij<:}q `m|mK+4+€2X )Է0םYԀQ;^Q %q/vBԶim\ Į\sĜԜx-16$詛t 0Eʊ*ΓøQ7q.B xO߆Dfÿ.bSCUyG "նPvpeՄ3zp%\ep4eU\feI P6qQƠDկj8(C/ fet6I XWWKR!͉1W J쬫&C1~qV2 2GʴVCA<7%$-8´H"d!V#FjRk5* 28]HP<,X+^*xeXP@RP`DE4У0(Nŏc5ht[Ϫ)" 0yҜST(FꯌTߒ(1ޯ#F|#RDQr"*BըaSߒ=(a((%PH,>[J2Wm O}K١Z*_$@hu(cz6|J 2yE@TmHuWɊ~GB QU1x_qij"RR_(>=-R@\`xX⊠_LF8MsV0'S CSTsQ;LI.}ӣ7FU=MФ@&UeUzUE|?èQ#깠pߢRI*4HQ~X3j7-/ P<U}@i@a-fa&X/a{@D Lzf""QpTe5F7E8"ĒFa<h@ango{+h`<[-QE`V``nzilMV3j-SQvHP`3u4nqpmL1!Mρ7 (;[0h UGi}.6岚x#ĸ PW"-*)$_Z¥FF!gGHFTZBGIΩb0S 4xI0/%3s, i]*+oe(KiStJ5FW]}b;um@8N2aSWR?dgc۬9 쟟UOnGi]>TeK.%ɓۼ嘙 ߨS&"CIxx1/ǢHYU4$w5 O]}86HB`{T.RS,ØW,{߿EWe ;A 4Z5h{v9qd HDy*#PPVצHQ /:/ia`v'70\^t hFrЏOjk gN:P0݄"ug%f@F`2pp/bܝ89)0hrR@aEƜ3oA($(h< 3@".5 fX|eZLXP70gK#JBIdw  q`#P!pb=T Zk`pǗ4NI+yRaFE$l2B쟜a gĸCCTTԡHxr{[YZazn]Bł^AQɈN-YUoZ- f)i,D(H%`?iSBTY3T*k8`6M*Ԏ \YS $d^`~x,-a) ʊwNIȰ?9ytl-ݏFc(~W 7$ H5᷌yUZny[MO;dzšLםTsqSa/A>7M&Wv.Y9jױ#7I~AhDZ0|0:$~E `:*I@ۆY.%-5|Ӹ+j[ tC~Dce+u0ڕda4'Ytcp SG0,5]bOlǵqRlolz|扙}f9]Y 0 d#)/omŒꟺE2%x{js AVidMA . _%bڣ7g6 SVgkE ;b?=|` ax9ečq3$) < \OI!JE†WiWb(êWH]Ir稍 yu=CBd ͆6< $$ B4, ?z%ÿOjWqD@23ILz߶;HSiAFnxjj<(KJp,o>M|{Ŏv9xAӸƗ,ѣ\o,\1;e}uAWIٿӰYX98V)@u.ITԑx_>=ZFV*q _~t0,kչ][Gc_B?"Mag^D90VƇ`ۚi{a]80LtB&F؉Mc$}oȱ bEB<9xu"1R$c -l;Aɼ'Еcl9s~a>m`HDwX)u_W8K c⚧\5 Myĵ&f3i77O\tf *gz%e^^/aLɰdR=/o=%0 0՞F0 p-_BVT?7^0M[F#01Ԉ"5 76a "hu}* ߫[o&ɷ)am"&=a3Ɗ[0C@}# "A<@1;;AڒKKx5y( 3Ƕm/"~s h4g}2d%5N5|]PWiƉN|8Yg0N^ڍBM|.#nV)7iWKHݿu,VahxSӆlNQz+ hxڥ(.ld2$E0ޠ}6b3g& <,У]ڻt0hSX4; /z~x*Bu⋴ e>$1 ݬX^nR°vԂ`yLhƮ>b&!,nE]}×YKqlN|aA9M}s_ڋwb6sz@/٣dܸ0L=nzlsssꞞL :>ΚQcQ$q?Xw4Π*PS %o7YԌ)ӃL }^b}6x+, yv֝m+ovH[ /Yᆰn9@A]^ BɲQj5s>mQȯd134*eG6mEv9eC0yd5Lqbm5=qI[׏-=56v{8J3RCw`|Qk/}Pki3.TU(Q t4hq${CjR4?(K{WqP"듍َ1XAŘWB4%:`<$m5?8UJ-c!p?=;8y".Q"lq gީ Cޫ5K_yU?Q(ۤVd(i'n% a'Xԯz~;;hd)֑c^쓰.mbA<ާ<G4@&܉8iI6뢄&8O>Yڌc1ٸ[3a38 ЂLqr5 x~BÁ GV5bh2<H: yaOC(*- 0AKs"[FХr肥FyYUqVzt_4J̞ C<*$CVf TSx($U0Z-6^u1ώ':oK-kWM(j G]H,|ObP*kd|cRU@ˤh ƗR6-n^99ð7U4IKu6xvgGv([{v{SP eORq/GN(17!WT K ;g9ѹX•TY?SGVjN z唸rvDl,|Akb:"M9#OHWJBnb'c;hų@MRW5D93⼆2(ܐKQ-<_Eh]YRj7q}-ad{P3#0]t -э$%8 kqQky2%W50fK+Mm]|XM;J0a2bj =zꘛK6mٴ<"c'9NSƨۉDݢxvHе|bgtǻ6V}q=g6yc:K2ƟjSYV9,% {:1O\묽ELc6 X]gz8 377S cSqhVEW˜nnNq?is:u3ؐd§J%l8uE<`qe6l[4ޱ؎Fd6|SkKV1~O;уoRckZtlB8{ PÝkӣ ]5 pqK^f'oX=(Z|"Qѐú.Cx6x.@M$y\QC?% d~uvu1fc*1oҵ?Rx,=D l7q&8#8v<'6H{챍3'_||#`,;˴9OLe\9<O8'#%V+J'xiUqTZ\- Bqhty$Y>0*RE,C ^숆.ae{v -,IcRijQ6^"[NcSxf6Wihde(Q-[ ƛtm B.<0 뇴M_(ٓ4 mF͚  EA.2tQO[4h%<ѫ y 1jFFk5d#o³r%H0Lqאm0i].m  ͖aY@aޢ %fJ>~Fϯ]_ Obm9')φōIȁ iAE<0z D?wٕ _t[nC*ۅD:"Il"\g uF[Xj[kcq&=K{xYUpjmAgϞzΌYԝ%tBIJUT}%_ܞ$1%|Ӻ|am)<@gq+,_tW}Ƕm%C1ٙdgt`tBؾw!r 45#ITE j*=B)E^3(Jt`X|p&x@M\1Hnof*{*]L%ݺ6ɂuĸ,Ŋ]~o->6rzғsgTZt+H,($/AWtJocX*򞼎@Ihܗ{&1f$4 ͌p60>#% ML1yd֖M=eq,:d[j?.OG 8jYP U : *nj:ˏt+>aq*SX03r,i41\?ЍyKʃ+ %dcc[A~ OL/D(~PQ+t}VEp6M'&Cԓ% 8~Pk)LzmȣAՄw&+K`nbD^~3xՖ z8?GalYQgZ5}1HԉI l=¥O9f%Y%$ѸY"XfGNXp'iQ,ZpoVl''KQ4] ᚝xF M\w꘮iu&cMp Z*&yK [;lUCɨ)ޤKQWIF=MV', bImA t"6sH >kr$` Aĸ|K89ٳ dӼѓEA[Đ@FC52n(S: H09rm~I"Iޮw% `^["VL ;ۗ$z =ÇthK7XMTU0D3i; `dBs6 255؎<xJ  gx'#a*^wƬF V0%oXKoq}&Uuh;$(j.h pY9*мlgdLvA5ak=;s.VS6sA!F/8yģPahHݳڬ'F5@bu]"47!"4I9;/lb+t7w Jj;=1KVE'~ESlj?:LgtlF{t+~I48ݧ eJM8D击q"SD{u(_9FgBC3}{dWy_#;%YٞsOr_̮RZH`#"2l 8L$pz cFBƑ,, `~ƀH]Ebb\XBm* e )wιs=Nafz~_ޓ& GaP1|D17cPBqB뮚L(<"ϓ0c(>#礁9Z:(%@iWE oK)P~{'mbcV 1gn& ?" ␣88K{[{S۷O;8>pkKkQd6tnL&Ѡ@H//(L=KUp_[RoXc:ZHqsVqپdT,TqC"FFMg!F, @a5Y8U0F %L*[`'HP%WK%'L{wlb3~Ab3@O]V)`:~XAx MMEi[EqZ>;ס,,?'iR.Q<@Y E:腀Y 1ܠm;+Ԓ..gQ'7<ՇQót0^Eo:X8tjJ`5 / >Ø?͙[. י13kq0֚^&`6#BߏVm9,u[Sc՞EBp  GEķ !?W+* D#M SahKu%.G=ghm\qZ1oHõrkaYj9_00FO*1~<{ldy HDC(;vpAڄ۵8(K扬S'G+A2>6O1^ʤ(W( e/ZRڲ$]ɸKN?gM6_1_E塞K*OڲNȆ.Zgvʏea=Š+R"J Pg6vB'7!Blj&^,䜆8HQ)-~dUeyya H8b[]aM|"Gk S8UʕނO_t# mQQH~̳ ҥfTV#xB)AAɦqޮ 6" " L)<%#@j8" 8A+_P$Ҁ1FMó; $<8Me NNsjbrc\˚Yb mNzEfQ0H M*p[ɄZ9hO2;h$q$q#UU`W;zKxK%E!#8=Tvδ52n˱ZVdTݒ7;U(XrC qꌔ-|{v 6ƙm-v cUՙ 8J\ 㠄H2{*ङN(Y^/[W LnQUhXb?4K2nU .[qa'LW2X]hb8Diĩc ,DP:7["521ך04`J4wűIEeBQ S7(|lךBAqDY Kt~Xc7dD:I.ܑRª,[`00Lcᣐaz _HKfk[Frl&XC"00k5".Mp&T,uڠL6aB!ȁ&w.Ax.=y2JȒ<4 ˱3y>0v0@=3`+& +wwwI0FcY)"$+cܩܰ]46BrH|kD`!ESE\cYBBZ^.+-:<z %;%0>AY98Qq90廔p֭<:W]i;3("Np`+%pKqP>tG#+wJtdq X O`Q6m#Ĩ ԥmHjkxPC1NWyu󓬋E³t+Gݥ!D[@f/1$GAc-ⶈ!2e>d;HtmxvN[f W!\5b'^qL(ʱ+ == Թ 넀$ EMρ|ܬ5dž@ KZNXi֙9! Ǟ6 !aaϝDf|(X:zdE0-(r- lS!"t:t Ħ$+.&8Xq歇!8yI0Ъ'lln+6ފ%!ԋ`8Qq]Cj 1/srcz!NN 9CtgfZ80 <bjC Hםca.v bk5>؀!h`0E"?oCa4<ߦ$~ Xq?:+#x|?a0YQ'[Wd91!x 83G{zudMt0,mC- ]gqd8.u(<)lH76͂1I}ۇ&@c8"6U|g$*²X˖M/Tve3hg UHw Q@v~nV2--(/ċc= sâym9%A8H 4Ĝ5AD.>3[-EBq|CO)R#!d!O@q#ϖ ~&#܏2e̮*3KؖG:xfm n|I(hL0{% ;y8>xo@KP[5}V] _ chNjk2|~8t53fc-JY='$2Hqɐ֥]>*z-Kz'n+Ǘꍒ$~U!)A,(%T,IHeد Zk`߃]{V0|qh :Y\[tpK]-iɍA(%?f*?!,"IUUT`OR^ѣ{20r*IzY81}ЩF곊&@^Qb2 T~ ޘM)W?պx8|QPb^:p=uDWUXx,0%ma9 ɱi9>?I FlʬENX9 SEV*`{ĦMr}׺(hS| c]&6A{#~sb=;I jP)qiCcYujnwY$yۻ@ީM?||t &Rgs e˒cfch"xA@V94y9(;:|]G(U‘J/J{@d,:Hæ%1,!&KLR_bؽf ?-aFJ,$ kQ+q3H'^TdL>X%>~UK A?$,Ih*JK%Y*[\]]}TpW^QCmtśT`!fY:%B ؞,˰͙}Y|iYS̶gO3S'O>} ^c$'~q`3$A?$ׂxPHd&(tӫaIx!EfG Cl sAbMMO+ uE`Sa jL&B{Ĕ0ѵ'oc9ՕJ-(e q۝GVbo͵`)#, N-G xW2Rw6?-p{p~=0isG@FQ7řJJF#ٙ]0sk41h_ xJ: D ?4y&A PlR6 \!\<)hVʖRu?X(& %Bm]AqqQ#M @&9m 2%(WHTHMYXb,b+"">Y]B).]jOWV\&pz~%G}[QeZ; W >n ]g2p/iвYx&C R BbqK =u^=hvuhTIol 6&v0:ljca ކ1_l[X)(,}jb5'린ĂR K{#ZE9*ɶhQݛzZ6:pQ}͖bw<B/ao Cc)ܓr]{H'fr#Xz&$ݨ{$Z 0 RBKڦQTvc~L"o 5yqɜv8HhrxL)[ s v+`í<4r~,K,im1tĸC/ҭ&8?=H6V\B I$cFln㞩%IQ$ 4q,TddtS2b| Xk[CMqKBdPe\X 3K[ᬕ5|2b>Uk³ IFSKѶx3t C}h4MK `Wٲ05> D슬ucg]7&FRW}dm<t,_ 1dcb@h $,R3}/j`z[ejSedulX$Wjp+Ĵ.P!p{H(*.j am j㼔!!Ż!siJD|*kn7D4R֮ʅvȔ8ϴ<՟J72_lL H^ QAxP  HK6Qc:s*/jgD}`ayAJgfG2ݘT"Xx6Ã9qy0@8 7pXz-)$<#H(`0.Qq=bm;Dk:DjZ%UݦaYB.;qə1MMJc&NinGg6qvv :? $ȻٻTk9 %Vy{ x?[[nHF5Fwm5tj N5]i = ru;Z(cq K)VrE7JNb-觼d,›sp X9g:s@0'eÒ/kEZ3(]O+(&J;5 E"aN"'Kl,eJX fZF*Z Ka(<- ].opIt+56`W}>@_K:D47&ĜN!gytL5}-GxDM6$5 g)PݪZwn9As@p5]"Տ;_cPp\)lo[^P ,mk8}w35-ng?Av$p5-lL6TIԫًt(0 hKRЈ'O&_4D_qKCH֢uA1()Aq~AM<` 2!/a4JU$(_E%l;a,q*Q0jTv;rD0z}ċEFC0ZGzRG FFK})i[tBtҴHF9>B[G':o*1Ӟxe; *¨\fۖ5ge-ˆ`svs 0pZg T2\rj8}4qak;Ŏ4¶AÌr:a1^gbƺTq[ņ(j2OHR! &_$~(s%F;QS"vN9seMj{k64(dtƂc50< G1D~Iػ[`Nňi 1~L"hީ 6<$/wQM/,..]uQ'j_*|-Zqd"/R0YsUl1^*a? Ζzl(׃)ɠQ'U j=:b~L880e!VT^⡡x1DB>{E˙ZVH'fa۶kK-݃"Tآ:|B!17q=^ @^7Nd۵A5U4@eux#@M[0\kw.QLRPLe0s {..7E)˾hF'BN/mT6>,UDE"ߏ{$}҉:Ntko8єoqe[vYϯ eytCrOή7X90)JUQ 5>~6 ޫ!;D@c qڼYq]:>YS$Hz- 5x(2ALc^7W.Rb>]F.J55; }aWf+y؄7Ts:[.- cտH2&#30%YH\W7M 1:2-KuGeA_b3zD t ud{"0WT(p+մU6` G}Rzlqa]?T.U3dR"HnR0$~:n?]akoE꺍G(!ovg0ݚ^7i6VRJP>)ntH}D0nx@G^axZnV> օ1*Ma1׎+!D\*ɥ40@. l}bmUuPKE7m(Q|hإᝎ=,*CR0npk"6c=q aX˦D 0[i٫oxX+T Θ$b߆F+}5F);%ŀ³'îa1#Eg4Zb.Q:"9ѵi:S_Y!p yh" qFVm~c. [MN&!nGaB42;*O-| [ᅜ(0 +xY\*VkN|NBёey »vsZ<,D\cZ:c!e1.Cez"!Z4KzVX[Z՘R3DT4bڀSR[⢣ aݶy瑨)at w9&1j>"ף%e d\~Aq:z3۶LǶ# ~=%bY&}DqL3x,S#U!'5Ca;qFsJPHU^L>;ٴ+;j ]@{\gk4#?rVG:6ִp2`/:z+Q2R#HQ&P2T(t "-[e@x9 rB. `]Xkٽ50qDh n 5N:iH~dPvo/9t(>zL{\red@a0$_sv8J) I]"Q2c٠ p:֎E׏gnlg 9mYӧcb\dK(0ƀfN[,G gvqq)p6m/رq ;)߭pf28S*]upʖ:Uej<P|IIWbK0ť#r}CMpW牽jze]'TSu9x>Iʓp) % a x䎡 ΎōS :W`|mՊJ,uَBc$A@ 7$6㦣ɟ`." </ILwϟose8݌=蘲X@(>+ ``_g(fOUV!;iYgYTft]56$䨦Ȓ( H=TݪXB(Ah\. FL_RO37YXt;](XJ`L]G5 (V(:.mKL+ d5^VUli{esE: "TΡdYhԾ&cOJzY,l6F}g\O$:XmZ߳zBQ//~9zlߟJ` 61C_ک$%dUBIK5;c]3XO1IG=$S&봋+|B(%lC1 M>2Z.srMk`\=uƈlT[5 9%*z~:g8(k-$˂"3?գPh̊DQaI6n|0ѢrbF%矺 `F\Ubi6q3ba]˚O% 7kxP^;wuF[50 a`sEwo|_mލ͆ &?[[k`,0I a<"aSgn$ST.U(B@8EqN˵9Ad܍nyD_;gc ;F?W irxEBf6ޖ/$)*rlSP?%h1&&f,uA9$ G!ѵ(èqD1ѫj}S2_蘠RP8J"c1hކ[Ќ2\<7K0 Eܦ9/9RaAfh l&iMTyCʶopToD#*"l @,$JŞyvf[ͪH o7٨"_Ix WĔ(1=O%yJFRcmeۋtŎi8sٙ8g/%RKw_)p H0qAG>ٺUꬎwrXxh7im#e[^ļ%V1ZP0j 1pCީX0ـt3dJ5%Oݡ vz)d$I3Kw{=,)j!SR$ o6a;[S$~17Yůy_D:5i4F~Kmmh`.|x$ 1D8"VI]RcXj,%$#ʽZ-I^(* $8]XET^? ?/ʊ4ĥZt8.XXm`)]Q@r0xnܶ5QCPr2y a:H%65K%%(j⹩<"/*{pӞm\,7R控QG˗ /f¡_8c1D!0 B̈́A2ӣ 窫ցcqDBC4}ieW}8k4Rn3ᄏ{_$wwbA"fI%Yb3 66iPc, q'HJR ğR1IGرAι9q=~&ĹM.N,r2d/ Eo̷w/\("/$MG&ctg쬭kkk{ar_͟O~~_φw'7Ͼ؛~n}ė]1+!U"- ? HO)  m|tA߸20o\Q=OJ#- (\:tấڶ>]_߆C?.}nױ !߬Q:xExi᧙gd(tؚE4 pb.q,bKeȜ _ahc`\Yxo?:|nC % N mQtSN5l}9%Om\p DcG.~GEfqeqSB;a>xi4نfѯLd$|9] . 8Jw955mKm ^wg,Rd1(HA9}8;R&2JLm6 9# ͙IM_[xR."DzdyHI@ýÝqu% )f.~- nPAQRyjC/PvuiХ ǵ "brqk H$P4 r,U*MV"4U(%1b>[T7~K0e@&7ނFv̒8\GSH0Ԓ;'$7YzC0M?x O-Tc#Je |[CHMAm4_KfM8spY:,W)Qg>kΌ*gq`uxYjbhsj)jM] O*%* Ј@Rm`;,=-TS,ſ_b&~(/X݊FU1\*&Tu@\ǜZ10^k\MG:s %Fa& 61,A>>Pc(ާDt`ᗥ)esŠʘulWrx6`A흊AgE%b٨iIZA<@<W9h_5 툰k'$4Ih jc0ޯFEx^Ai2PgGxk:,m y@Q{Gz,u@BQp( j䶯Ni)r iÛ,MS5(4C cC5 [벎MmýY 7 1a`âu4h)2/ k=b0RP:Ta.88qℭ3EfR wUmG 1ڌw(iink2fw5Vӂաw} .հcB^/VIFYQ@QE!$Dހ[&`ۋc^HZusm`Hʟ0Q|U1$̓,Po.Mz/9>[x*lX0T Z((XPڦ"_UA,Nޢ5U,Qo10b_ՠE)"Ń0*I Vbf?#{&$X?lmدP{pϱZqPG~:AU ]?e0b`\\/.XMMkt&- +ce$qr?V">b;zT +JI8CD=GBBvƲ)fdjU0Ġ#UZ~+MYZY#EGR6-bT2Y6.XjB) '}DYV$AqeGq(1jj6GLi[RS$.bJ$햅 \vG0oļALHΔU[)S=*cC/1Gg&n&!m]*Knh/hEHj8Po6o˶.X:a*8kT?wOM&_L!89vC(ڴ T>Z-a$,kr1}WY!qݚANhC<{$ p=s5`Ne8n1F%xn%t<=j`;8<>%6XE`V:US~roJb`Z q-JNB~=ɣ&0㟅go0q$EFj cKM7]T(Чzl"8Gq0쪝2=b'QpLA,/ "5 ~+qZ 6^DѰ))Ҽl}QZBo}˚D&ә 8R0|Ώ 21'yJFTw `<m+X"g\abf+l NTaku&ES:s-!rL? cKs.;dyXi6V&E@F³O)m8Xoݪ(N9[ }B\a̡}LJe"݋1n-и_W"l3 c\ 'jzϻ en(vn'rzVY-*ӈ^*f915KK*T5' ^ƞ9*!J_ajU|k:& ve}caK}}Bn@.C!kiQ cP#ss>#״," M7=\ӋcfkEiΗE)'*4VB-8)1)h-`EVGCAwj_h 5<FeʹO_:J0 S~%q9S9jmjH5F4^xrwE7l:l1l: IB}ڡ}BѸO998Jyh'AfzknODuw B^e-"-r1+GhIFa`7.Pt OIRt!Mo[fa]V4.5Pt%{-4Q)2U+~GQ>A}wLN{ }.ػ8laUѨ\S)zFiL}fF>.J"~E6Ãn% -Dѩx\0`3' ݅Rݩfjx/PT;0"cw]@Xm$zݭ>n|jä^xS窼>6m+_{@|X}b"%J,ȕ-G: rv2U.{edB40:KQto{|9 HdEJ jU51MJ܏'ER\WjUƩe| WسXo~ڋCm8o\L$߿1UIA$͏p+bKc?.nTFu  \G(&Cʂz{bd~x}gj1(d Q9'=s!~:qkrnj!ܱ(=G?G䴀,F6.8 `-u) {T ^3Mu'e ENlqPHxXQמR2FbW~ JJT1xTjѵUoiRf` GGv%})~Ay-RBPY1 aZ΄KQ8`73gdCqjE˖GX MV$KdRxU7!.:,Վ]P !j ¼,`)tfU7 _S@e>m CwE("ei|O^/IcE}TP3%K(\Uޫ|0J4pE؝fr 'HKi=6 W2d냜VsauAa<<+ 0xu׺'eJ^Yw (Ilߚ$VF{]_ZZRZ҉&5HQɮTmcKy.GKӲuUjGSYd]l<&(OW&HB9[-/"Z`6 F:?<[(h*|rA1Aeub 0 E'05Dh4@w?~0 ozJϺwTkZ@X(mGLEOCs4 Sbka[̴̶fS 6ޫ04xpԟbkgLmvf KpmJ?] ilꬭ5>VvDdh!Z6NV=x4G 7nLuy<>P&婾H*=(ɊFa0˘ ~8ݸ~׶p4%T:3 Zk{/5tȯ+]L)1$S"H*aHإUo'I`HZv9([8jo8rx)bh؍U˖5&w1bW) ZvKS= k1>P(WN&PN[⍩`$A+~"Ƙv\0n>5|n9Eϣr70ܦwЬ mnV6 08Ġ:.W<ە.UA FWvo &F)I=1*P伯^Bh40d ?U`R1ldy9l)z#\e ^O$N?Rlya!!v'άc9٦1L& - 4% q$c^֊nPOj5 Ί8ˈ;ZF-]S@NhVa ,ϓ֙HV+ 9 1 ugHIm0֙~I1ĭx7ȼBg'd+pԑ$MwȽdgjCpŝ`C㋪ue 0P âM$n\p{1 lܤfҷR.((9_|jT|21jrN'c`4>8Pfxia WƓ:.LGaq% Lnz 'XTGQ9?VTO B?ܛ[ 8E;(ABjU@]h6n FYp[R)A2b5 ϥR]H1}"O 1~rdTiyoZIu-gt9jA|>2Q!X>|:N9 tCM^Dt૙휣VGс ? 1,njjkoc19O<6)/d;b!ojZ67]d4jOZxާn) зrG 不?~QCN%W)eDYi&; I1tS se34@6fS}Kݘ\_qd[o+h,z&|RaurU$[l]sK5`t%aժ ЉsF ]ek16N&KٛAI|{e޶sIxz}@5I5Ҍ(ڷ+t-zRQ9DJQP'a[(ܺx\rC~ J Ri&)1luujCѐau<#";S᥵5}4SgO7^\V昽MS.A`kFڶ`*wQ@1;&@TT\ĉ$ zZ^spu e:c/:)̀NL`ܻBЬ^8) e?lBd0*6 ldF{Ǖ}RN=m:F;as23IG5%G5lj/c]yb^c1 ^ Ko6n{~DEGڝ vS6dXEpVeK}ob5kcnZs]OĮ}wn\Y0vb m}cݻ֏EPq$SΥ(NسkYvWg-d<2gY;\)1 ιJ53";R61!`1>y`,@W -;7w,wmc%lU+3 b`$8 $ Tt_Tn"~ hvq[4h74Rڲ/Y /+-8bmEL8w-\Xɀ_Ze ?//#rj}MY༨ k遦:/OlT#mԨƻ y" paS o/US?5UOu%E= F`Y۳Ԫ+驒7Kw)誀޺yV;kV-ϜZȦ7)7>0,u%O"PUI;~Lv9j|E(jrzDn hiڊ[r ,ȕJa=psI  iܷ+k"L,j_K9 ʛQ)g^WjPF)4X7(-YQ]xY-Vk!.jԙ wB6wbEKOimQt;"FFM?gh=sWVHaTn=wHFyQuMާ6ٚQg lNۦp` M1q5)K?GaAVI/ŢIWr k6{WTv42IY@8:itK5<@%]~3-a`jՏy/qӧ"mP,m iObBJE d%h vWTv(d$C>ۗ :x(1%MBw0R/9ںTRTSx˹aTafa73aGs9k~en<؀O/\i3j}ZX#iDQH1 ?*pPђ1K!O=?5q8nGP= d!/2?緋1>,^ͺɓAhNs(8((Z,=MQxE%qFѡE৺uNSXʾR2K"RR0%L9eofv`|B\0O}q7ؖ;)?9#M t@jUxAE0Uy0j/wvòN&Zhf<[4"/ϰ{SaJT~9saSJ/Ö08JҪL8~ s/lm/}g:ݳ^st=<ߟω>!sׇ3ϟyğ?"~=_? _O=?z:|g?}߃goUFZEU8S.3w˗ˀҥ 95g}uM"3ݞp,.4ϚY۝ ƃ ƋF|00 Wi߈seYb|&ƽ57U022Kfi\1_}O(nb0u`b_ƱkG{TT4(Sҥ˦eяgShrl #f(kFQP (βPP8 9:F!,uD'S* (" = KXg;{>$ߏƋ00H[ 31!/g&FHYQHcw`ܭ 4ͪTR(7>!8; `ERh0i "ԟT1 ʤDϸ:uٔHt:E|">X  K$=$y78q gy%MKxT^zBSHܥ5DW Ԯ!AUq!\ AOI1n2U* s:qgmDx*u)DX!AU: ,*2LB1R~s7|*U*"?SѠʋsBض+OJpL7: ]/7'D4>+ D_kD#D_$ҼJϥ񄦚 * tU$ˁޯ6Nm\eHL "&qj?}l4#MA NmY!;;ssq^DMdS$Nf@&QJwQMwӮAf16\4 c;sumc:m״&lrfv4ϜYN&5 1>(ާ)# ,91 s8TpY 97$0޷B 28OA a_X;L/J:b:^Ϥo /R"hţ8Ǟws󩸦b=ȺVCԷ%zQQ5xf"HEl$<5xFݲUa_^ZLJMAM- *bl.+DċhuNi-"61V*A;2m=i$s3XTg8aC߂=YD }-`~!8A3mJ#V4C4vJ {Ht LtMn ҰMts|=H`\ghAN`GvƗ+Kƒ6`t=i;@wWģ{:Q\k=v(D"{bZ7j79HYj|{ eؠ3-0Y'Šǟ9=3͹/ ወfA8r|#ȅC=%1vKCO$@ rgei* lOA? Do}m)v?)cLGQ  XDznH_Mn4I \J Q7j.A$J>2̼'; bx_#ؗ RC,:fkySp83zTdc!xszxX䀉noIw_9\q|>zb4? d<*PUE|\]ҹF/%|xgXbb1>L}xv\ib[5R&Λn3 ),Rw[qI?ZCl\?u|9zg%J#A*;}M:]8!yCMXtˑ?b`&PUXr"4y$ 5RqB[Uȍ!b/(Ţ8 vƭD\1O``B}ڨo9AUԼEee=k);? szaAZ17*c ִbאKW[b YMo% b< (׎e?))Q\ i"+5ds$O׆8@'+WJ 9\ |v,O(EYi22.[`,hct&Dov6tբ 2 q$"~j &Ui)oTLˡ|ϵ3byӧΘ/v뮁3wj; f5q8qT<#pqC-@meJ J,<>= LmytԘ݊aVF*^Ȋ#+2.1DDU-Co,z DY)dx/؍>S8YA8č}WB0s8#Xd֥K$^-2B1O(Hq0ǖ<~lɧwjK`[9A5IJf³Rm=QatpbD0gq1/!0ѣCm%L{<]Wb2v7( .SBzW v ҡBAQkoն*RZ JmݵcExj3goе%vt'eѢ.kU ~זs1D/- >1<a̙X?ׇUY(W-3,6,ri-[ԭAFVR =!Ӥi3ֆuj:J,^,$@mCs8=q to %}⤊\$Th4 l/n1',ZmJ$"?VI 뺙Vϰ}5~=ן9U4~JUuKdA+"È!ȱ uv-Q ESq~CDJt WGMx:n_+(J3ARLMU'CaU`\ـq%·HQ]*!9"ឡ"t:g}zwc> o8;'xG{֛}zĎO@΍*LI[ |W .* C b`KQ d)˴\ꢐV~TExotlG$q ԘX㺦I F=uMbcts6׋ÿ)ޮ@c4.$rk@J ZvD8VO4?p<]ra'2x0u}wW @B4[K 3Ґw'='-`,43Y{ccAt6mb[RMqU MK;WlF=&08'/lL =HаM:]:A'&9o%VX0zKRRT1>Ubj=(h],Ya}UA l 1ީBڷSa^Yx^D*֥Kx~rJ>q@)'),yZ$tv, oشFcNJԥU!nK]c')D]tNցnsyO݊tŢK:U_( !5%l7ߴrÛ+AcclD3hZD18w%;Zmy~DLJ58h^У2ɓ*)<3_v5}Xi`|%mgBBvY$|(8pAl복qw T"~Q'B]/Xg[]klz7oҾPZѐ{cXVY< |UE=ǰZoy> CW!Wu{N(ÒR>G=GmDT$PC㓺j,Bh *{Эn]UNd>ohȾ:КBJ߼7F"&|ݯE,` =Hݟ$s=g `REwK{|x`TDGD!{y9^`8t'1 ǵ"pP~5GW"A,qqLR:$gE-AԷ}cWޯ]/pեh4lukn*OoPE]+:d,wXʼ~knmoom_}[Wv-|mO'c?]?{̸S~*7JD^p)S iĻmuZ WI&e*&7lw<ݪl6!h_5<;*Z}:yG=0,Oݕ)G%Ik{,*2b%}`%+sp]Er%EqYKㄈ۩[g+Z~ ^2[xSB4\H8(wA-ӫw2Et .!`qǃ $KFo\ɰg2 \OJw 0v&gI까 9(k91AN1p۱P`kzfc̊! A!JtzEѽ| ,/Nr}IT`teK!0~^QE&ɬjxYeEgT(бe`K|I9|}/P@_F ո#.2e9 Mao|* +[ H}YOaeL -ǵi,Sf9u5!Pb&礫QLBdn=!2᭞R:ocp@fq0NW]#sd>k؞=;3Zsw@J kTYnH}k =ځ2tC A &k77~T0y\b9qUe ˙E(Ƞ^ޯ+8Jpj,xj%/P'E'znUG~Iq't0$H1ovJy< \=w[%aؾ?9sw/4Pt-nxdƜ{^}E-mbt<ˈuz52 z̓НZ\,kjލxOu_qOebepboSS|* < &lp wI*߃gSpḤ* x_7ӭ3=3NN 5w ~̙g!ژ'A}K%+eDhO=V4 \4TTd}Ϗ"9eř(,7[}ҥΞ_z (*i lI("n5T@>ɖXDnɌ%]~7" du-q!TR!,s1_'sNsk2EAslanI>F}"A:֠aƉc'Ʀcy.q!϶kw{vKl{سg'Μ F>xeeMw\%q$) ̢k6 H`NTGվ)`N'Zj0,ĝ2% Jp >빦vqbl( ضg-1THqHx k}hƜEPXvkڳϔ騁YHɆU[Nn>myXeQKxrT_/mbͶG,Jv2u" utzUi!<88p OJcFt6GR/ҞZMQTU^rk~d؈C+3,gqTj w1Z}J>R-6LqW]/R"1Yl fqL{tlXBjX/9l1]EwXJ)K+˵ 0:1󝙃7fؙpuwo}X+(=_ 1xR8RX>Af(qx ٠XU{k˳2In[upp>Wp[1N; +([ӶoJ3gxA_ ᚫ HT-J'̊ Q_&3{ml6䧵 BGF%5+@'iHdwX! \ƻ %lttW뮉BHlM),hoV $|Rbuc~[}E5%w oOm eU%60M%a'zI,^H[Oy2PJJ) tXj%]S$Q}!Kv?)Ι<sS:7Z9U6H7?Oa[61o T?#p,VgXO$].JuYK0şHX@בY*8*θ`(b>a<\8.[GhxSQy|Z]7yj)5z~b{cZ|V| j-543*ջCZp|*&vɺ΅x^Q;e;iWEE,VslL$,'o.ZIv5Flk, e#2~UJܓ>e<Řj#tC,LjfmTPg]oP]J2D i`殭?wh6{sǤ@td0kKaHw$QPea&zv؂NOOrCH%T&RNA%Fa3ֽi75G:jʖ{ >wEK"',=!)Hb;W+q Pb"CIt"_ѝ:;Sϓ Nֆ~;*ncR`+|Ӗal߶OB)OYGI h58Dcy>cfT-IVF7ڼĝ'sG*F" #ȼ)m}c4w݃)}X_?}ʚCl˲ǦtGs]X:e붉Mӆ +w(B?,,0 󈢐b 0 |ia'3uЇZE{AxyP$Ilc6\uO(AZ0qL0(r C$yQBn_>6MxMG;i3Џ-x@&R iZa\-7x@ ~y~QXJFYSB "fS˲ ƻe2bqdEprzqױ[?RXz "̓H F ZL6)EWSԵ{K=RԽ ҵAG~y0EA}jS5\ g?-RR>Z?O"D bKM u*Ӊb'@J{['e9m6^GjZ\ NE #R.2tSuqN o 8Zl_'I'I-0:&+`Q |xK :x v/"_ X@WYKP#MRWy)]:: ?k* tSNni "b(y _&/W*D }VgvVC^Z$ o$JsPǪvów(Tm)o?ιv@j[̂(7zSIB3r5PIFw[ELQ}1Fv/q1VR'XLbꎩk,lt3oh]AxF^Hq2e+ź=j2dYY2JbKv J_  xPpF鞚rNѐ (B<l)mF!k;cOB0`R |wD#KPy.ɠAFq&y!V°kb@wҶPd/ )a<~³!ed~ܛ ~@֡0@߼n[e8&A"KI.+`>v&@*ʐJe[sve5bppnx*IB#}mnnNmO@B 2Mp mƺ _ɕ' 4~MvWn5|a˲x<m];- w۹st kU e~YaބQErS]5{T-8TEt)@׭Ӈ+ ԫ}¹H гxƯGa)c)3AO\O1hǃ$b!ihn[qȊ%s@>E1$0Zun[0VU@00p2KN)QLkűM(@" ,}XQ zØC2[g>·lrl`D0]e x? (~]M|8hx~>_I>6G#$!&i;EıXlb)/|~8OBjmy%6cDBI " :ST <̡Qui6RgV~CYt0ܾw.TSTSD7A4ޥJB_H8aL˸N c%H͊~qKyKࠡN4cUԅ'5 pk̮;38|@;a81cQx5AC Bj6X!+t/+@nۗYelaɑ!I[6c&):<( ¿ig1=2jd$)$%E!,kmW蘦'!-kIq. C ].xGx*PDY.Da(y%6M0ߢB];ƫ0B2YB0L,1b@-KeaȩQ;~KT0šr E}BhhW|E9g(Za],due*GUu?y WSsPM1gU^&m-|@ ],5Z.s\P2~ SYz-;vIud 5vST ?}) \DWn'+bXo<,B~g8]M;U(3B$c5E$bW2&br049y9CbGU-)KM]8܀,~[[%Nxv\3LO"0X L0 PҴac#ts`4\JӮ;-e?_i#kkO?O G^hf ¾uXW4.XN;;tR,ǷI3%;A"` ) 殲.bs^bp!lojh`psV`EaEYOc;@enme7AVfGb?⿜[q!%whQsvp߲kF@RHc,Ȣt?/K]tl ,8FU'f^J8vp S~:ztY̌wT1{`3ZB_h c#^ኧ(- xd#躭cc>a[-g8&/4k&۔yA `,]C]tmM mVk!!=h]%`0WC_+PܬDeHYa!SXhs"lv\!} yo mĻ eaSImIrXelJUrl_ :93 `H3/0~HQvxndyb\/ Yeְ7+(VA"0I1Rث! )lƇ6mС09nƈMoN0RmE`2k)1݃ZxEy`1)T(+CP,@aU>!,*MsE; RJy ix+ %E;)a SݱԤpqw5b;_RLe^C{pbhx5-:<{PV."7bu:l. jеG,u>Z6@-F\^F ߞ7ۡLt l: 3'p qPKU eX%>uR,Wr)//óWJ/XbGB]:Th|qd2˰ikby Ȳ,C#Π @>]Y(sa\ aI4}jhCPD@ 7G<ìW$]@a."h)ڎw<—@U!M{[DI*w'SQӌR6>ox B0HARnMK> +3 \` uCS$Cݐg+j* R%ށAU]*𯩚=3 I2 %G v:@n)K/+rA/<("NfH9:Z? 0\SW}tv4l`=.!0nPa\lxk|yÁjox1mYYс"Eh. ?@0ìsH齽rƼry:K]XmwZv1#iZ8a
‏Khw3Y*h8eyJ_ф*! Kt\_锧L|cqXgA LN nsS $- nHCrIrXuX ~ }.x"C[قblV1|> =zߕ8; 0}yƱumMVx+5>.ިyIeMLVU -8Ơv@!7;~a7?|=Ms#bmܵ5U tD8{h\opF9xׄNҜrFu%8P6QzkQ(*Gej&Wz]`ߧSaVdAd sng B'sV~YsP}G0L:KxF ::h_;$4F.M#wP襮5Oͱ1A@$hYabh9Td`ղ;k>``/+KL箽ml|%{Lp`㗁-Heš` {,u!_SSi{yγOk~Z^HD=!ęXP)YKᮁ8 y eTݑe*9l a"׳KE :)RMQ0`8FpR0h[lKwzh 7TR#|H$f,yZm>Sh[- <)*<+GvF OLSAˮ@s>zf)n°OʸNck.!dCC j#B ne5:hC܇j˚eјؗ_>~肱n06 ?8 % pUݠ:rPCfVQGٝ*Dunj,hb=H2D00Jb;B8<N} f|̇q};Fc iÈ|=H~Tp=;FUR?M?F2&bIOjlu,\miv*}/ .b}tYIG$rmMmI'Wߜa ?RCL1F]teѳldX6!d=14[4c2l{DBe'wf%)P\aڼ  ,@ A)A>`+ `C `wvͫFFĞ m>CS6)zR X yHAW-ޤZ˧0(4&5.-h Q3G{;J | Q&] ]r8 hUh](MtZn9 ̙%0j3dL!M8~T)OKbq_3w$ vDvoV~aTR_QWЫ1Cq%Q!cWiēA+KUaG Sث*)=(8 !- %TV0ENGb8H 4X.ŘFQʪJ;^PU)d) 6?^,Mǒ2%Cxu-gcG^>Nt9ztph^#?TEK #F &bl9~D~[s9Crc8XF~ns(M6 n lu G$ `#>mX n`d@ȨQ x1rh-C`|F@Qo/MrbdLMO޶ ЄX5qtzfom/mg%9@@{ez[u .r !) 3͆T溆| *~BaMQM͟Ϝ\sM+kOX[{P@OSn nHh|LػI5ңm3 Ȣ$ުw;MJFY1 ?o)ble@NӦ@h%7?72hCcVs("ebE vx-IhW,|?UK \\(N,ۺ:ZG<9Rr"0OoOoxB S6L˱2S*Φm-oS^Qy EsPvz7ꔹN9j GR FuJz$_  'p ӘC1)6FG7Zl "uqRh+fp/^ѵͱi `K5b5p 'BYN)0:_+"`EYmEpn{/[ArtS=? !( AYP]ES?gY3 l-֎*b2aEDFQ;RoK lφ DE_~Hjůh\?!$8QGt0l+bRH Cj-t@^$:@A[rjhU.[T]%W _Ɏ(-y_ybꮺݯJ IC:@`ֺ.xH}uN( MqJ$v'y{nY(A *D=ۃ0ҩ[W,oػ&oU;!ܢzlo׭j)l]#'MPd*0J~/g0Gx1>)* W30:Ylf|MA|"cyuF]f %"D4"&Q30SiWkdz{zRaFB&'hEsl.>벍N ,;Z<"1w}V9 1Ftk9' B]e;lM:ݲ`rkVUۙx)xhb7UUH nb`N ȁ[muba'9M#cRgA)_ޭ|-viZ_v[sL!{lOX7s`<Q%~]vW%ub fLyh/EyD@~U،$ 2_QHw(7+7 Rg(Iʾi [KjD,]or5OfU2q 6DA@ k7sj N. ƇĎSl:D*p&C= rj0Cv|A[u(O &I2GrZ.`kZ3X)#9X892n0f͈R ~q#oV^;D~O y`+ "=2qӻd*6P<*H{_T@ {3E%6:]J@Á-;nݚ/?~D 3G$>/jH@U+> ;YDT:x7| *bRNdblHJhҭD}ZM}Pa$?@.o\ST(+WP VMa@5n!1訽m+]uݖLFBJ[߭0U( e8X%;>wfᯬ_$ .bzrTS26-pS\* DufLyF  /OJc %38Ee]b]QZ*?҅qH?{^U^oO蠽,qL*`Эi҉h&!mKYFs/ogIE \W CӸ"v: xP|$'t+Dlk.}`dTY3i_7NqPfMtDep==JY6# LXIzSKۚr> o5TTcZM 1%zKn._W.8 qzhAۺȼXVгuAaqHH./nob 1L"xV3"4IŔYӲ~W.,¨q>Ȃ3Aܳs`1k %f "; ]y=gj.-֭\妓5Pܩ9Na:ϳIaTߒ"-%T$󉡄gb/&؋砀`[hlBbR'4 EB}xTgk;Rn2(^ylPp N9Um"p[;U]XȒœrWb=f? ex1;SQ#c|疷 ^<FCo [(O:2=Ȣ,ȗ1mU"0jM-pf1Kxa d { *cW ֕WDgV&ࠖInuEjĻQ{˳(( кKiUo6qh0' h* rwTWF}HvI' *, 1pI=m' q- <@XWѝTyg9oΓ5ml^6-f vce<>ֶxRmoa=j*h@TAwؠC x `7N6-|.MT`2J0[ĕfC$x)mQ@?u];Ef8QX8rZ.<"ޑݯ4|x(&"bޕ'%<2;gm4ޤĭgdl:tvu'N$0@zrĬ^ AxF0oĤD(O37Wg,nye嵷AUbV^:SSޖ0d/F9 vXΨS Y+_{r\Pme'.] |u`4`t?`AeNkpC"ARMS M-]`@0P0! 1YޙYY{8 HE!%FӛirP!Rq6@Ҟ)KW{V%!9 ڠխ>S6+vE `>- O5K=KRT+[6Fդ"c_\B7X./ՋpU)V7hsQ LJ[IlCwԄ\-fe`=Y 4m .so$X5cIe"eyqǽlc}^8com&#,ًt{NrUkXW?![.VJ㢁8.W20۔~vƍ'Q|l= gd(z69*Џl湄q91_-CwYY/@.BCC5}yeWy_K#aF-uwνwbgbR,FBn15aA,&`lfIL$!l'$v*WQ,vU*NHl }眻s{5ynobv]CwLw/[q/_x~~<> Gz| ֓OOغá0`<~A)"K(L.!5\Y8&~K ^nk{(+"!brc/\Ǿ~Fq1Gw]G zخmkAo MoF^srqI,p%g)-r,e X""c(QtZ*,`OX*+|#`0K|5 vA]!S0\XւXi.lC7禦KDF |S^^ QP+ٳ988&vbj*x !ȲO~2SaELQ@LAп3}0?g93YME2Z@IiaE v,h@* T#XIOZߵ61+T:MA8ezJ ag7T]۟ ԶPOC OA2b!"~:pp@Aз9Сkp4Zo?&xڮ%}5O%@*ATlFTܠ/ѹ  gr @Da%aanYEb)aLE& 2YL4&]-[Rɇ0/ƷA6.)[<[ cRy]~[ ! $$oxYm,ԡaQ(5Fo_\[+_gG *I ~ѕ359 3~"F<>+CAy $< R𧼀+* {"WǠ_?0BlW*ZPƃ0JGNH3R)0Jb.SDL4(OE~aP@\14mH~"Rj 1^! t _}LH+b)&]=\>8=<_h{{~joo_{zwnNbdwgwO ھBDRDB5 dY?[:#.̀U$'2^!5Ԡ¬ hg5}ϧ{}viS|A4Gwo, iQW 4<{-O^&AL ϰTm*eUγ})7#(04#s՞|w"kt\t3+7\>|Qa*g 9x;ˮju{l^PPS yYvzua0xtp)ԏc5 K'GyU1˝@jyV.XjE b0""\䡲 w #Uˌ%8I4 "5zx_M@?V 8" IiV1aӀuk!MCBF6꩒nnɦ(SUV,E$ZL|г3{n89 1&!mYDߎ5}2OA|JQg4dUZ,e1ڪiJUqYFlz (iBqqJ=`DYyEYS"&V oe #Ử,@;oO@IukoUR "1!zF06AB[Ҩ n/=3^RNqfʓf3u|?W|c$aT0:/լcee:5p/g+`І$eD><Se ~]؄Q[ aIQ㳘^1Qw.Usf[ q)LZ0ȓ>z~*Icof>s&L2S`u0 tvCvp߽bw epx֩4"B)=tNka M:Vf)9RJGZ,Q<[GW$m g9M勿jM/Ձr F}D];-~J|,1*;:xxY`6jH6͆X6Pt9Ax^s6щ\Zk:)b)"B`n0~M5<{L,o 0<8 "F !+c+HU9OZ6ct@ KI@μ< ̙2+r-ӕի!V\G/8}!UR&'Kp3$ u/!'&V˦ ) ]00޳a[2e-~NUԇa~*HF>5%ꥠR j7(YȲ:2흄d˱_VO,Ǖt JJ3fqx$x|Do ج~<.=lS*p TPKrr{cbg)-8HD0&5]3MsqXCô.h&N6mpuCe;^Rd^g)1馽ص})}tmG7]\8:lK3 cTĸPM\w$~S`#،O>,yI*Х(eڹq%+&ߣ'me(8[ 7#~RbNJg1D! ~6"IJd(sM)5V @_%j(=yš4.컵8`M0gt(y6vɱ~|8'3;:ў 0#C1~AcU ~FW%btR67#F-X?-@s"),) i]2IOf0EW0if(ɵ(1aU4[ W :jԶTITI6YuA߱XՍGwmZ8{QC,AeY$^ܧHEO±@YwT:1:SV2{W ul+g :HGl}V972b#bHtH4/Qjdy˰ICS_cDAB X9:1O(HQR Dń{T;Ы!+0 s5 " 8n~r0pO(7aHfUT)x ?UNjE@ fJPmb X=*b&7@8U' ~P ıi|DN5P`RQ4 {=$^0k...Ny྄raMZt$E1 ;UpD Fg]% zjYM1+. v_0xrTT V#wgFZj:4 pspy'0,^ll0َdV;.S4¤H L0tmfpq NЩJ 1nV,X UQ7so\;7)8kĸM5rBmH8y7 d⨻SlnjlqaU8 "3)Բ0|(iF%z+'rH7) c8jgMaNe_e K:`2q+vnO1^8[g!] 6G7^vLRbh]"9OF^>(Β$*! v23 R[oDEmq>ʑ`E9:vٜari&ᬀ^ ,neIe)H+QWɨɳ8_(cWlgC]YFӎ/fIpcbLTOU6pj!QR͑6}a6Y{&MWSOݮJ~tI}\.8) |B.u>x]qꕾmxʌeyjw_Ǵb-3eiDeM_Ru"!Kд#%xrb[B/(zի0ÎYDb |WcE//(D\$@sSt&DO\v L t?^[MaPug0)P CNѨ]ec=%1\1ޯ$hdXTl(٥kv&m?o i9)Tyj} !xmt(;$}a⡫iƂ,v c.:tO>1j,.HIFxy7˳&WQo 楲bϱ< ` `tFA7qQ6 Y6h`10ѸVa4"r#t˝q˻}hw/h\jz`#)u´v-6g>5*%LKa-1.Y7K!O[$}Ԩl\w~}N_SO%8fRs gR~:Ixg?*[~E#_U]A^No{9 G c1'z< B_@#w S4K@@h`:Xim` ^ m`t!Yed I=NLUf_,awm&?%BNmJy>Ig|Eq @usnV{[R{ߦ.@fr013ʜa]Z Hy~3eqf/OGFAXr6Fd%%?¸Z1#޹vbl`mrꚆu4]in ̰L;*KDx M;Q) {c~֜oo:iS%MÙ{nک\ϮuӲ$ƍd)rEPIJt N ű6p(ˋ@mѝzNK;vp-.0-q}~/lG`9DeqaK!\ " XyfAQEx•AlԺtp65MG$NѶr4@(hױOfg;^e*{T I3v`0*i!\4' {ʭi&iXy+_-AqSrV?k{<θ ɤ> 2JS+peo(. P`/+vd  x6?b^{N/ĪN:fܥ0hƶ똴6⒃U}m-P65ɉ40l6|mZ"b&Fެ `<ឺ8k'&,Yq5f75rܤ3]*4yd Qllkn#1bn< /|`V`ZK8⫆#[v!iXQWCkc`ZTUQPnbaU/ƿgoOpnspCTnvΧg:@7|-˛K&8 d4֛H.h^&@55 z ! 0.pR %?b2@H4nnA+\ Fb )$e2 D6\5!15zE ՇUmm:'L[5`L0̽ ~֞brmjsǮsg>.SHnl%ߨܷ/M)oC޻6C=m8҇f?xziRop% "RN*(/V Ke*'п*Ual!?*FI 7mE1X>03FE(Z:_ɛimT16 qi0WAJb4di-X`mU6~bULkPCVOjPSRG =]~RdAgf:+ X2k*X$A_EYV!XSFrƲG0oMMf#͊Z{+G+boetrܚ.]>lۋE5)V+- r%bk}Te}2l} cucĒ+l_t_.кʾ 98Wca\_dyQſ xgA?\Y(ɣ,dV ^AyK3t`'nA›W+\mBo/ Ute;ūN F|F8bUoŔPb*iMoZ>M8AjIM5`o,K)dB&_YE)ݯ>s`=Ƙ7 2.BLJ6yWc%`q_/ \4?) uBg}3hvY6`w\=A *2 gq«~ؙ^1;v[6WRw7Pt5-RR!,!p ߥ m22TGu=@~hմqdf).ڔ U&>G002iz؟Σp91Ip3`ݾ H.¥ "ʓh| @1g$L:|@a@٨hW)7rY]&tHiNLU^g'y 0xYn+9VW]5W50vwwd'#+mP'gp=,rrX-{}0jj`ܥ0Q 2C0K8RTu{[4$B4A[#ah_(ŠBZ4We ?gd8֪3с%-8V~-Oz֯6l=?h:p`2N /4r,a'Z [|lC7D"ߏ\sL>9srG;q[O c!9t!onvx3*2 َO- /) _%(5ѸN?LL|r|RVJ_$)k)ke2kin]UBрS8} ksl1f»j"|FǠ'F-= +Slx^5$A!"7"Кt wQUO ⍯G+Q`>!Lv)oح%GX5ؠz[XN ƷTkREFqI5/qD08RH4/";144)5Vre^#P\XVe+.E(;.0oETX2?^+e^ Eܳ˗4ngE߳@ihܼfw7S4̨Y,yu{]/yUI-ɱ)K%|(/jlk*֮u7rCT0#}J0,h) STFۓ[ƇF"Lyt:ZǢP%3S!)_H!N LX tM?;S|BA98l s> h]@3IrB#-K ::"am&Mh 'ӥ`1$MY8hu Y|[YQX%Ƥ ?+0 *9O \.&*oMH`hƞY/+.^pL25ެA$I{mށC?@f?q6}p7cPu4J]Tn_~N@ lm\me:vteA473pQYڎ2W.R0 >[fAy*0B5P6a$R乣eprfk늲[!NQVXd7Ds=Uֵ :}I9P52<Œ(#G򇁟I ~d=dV{0E@i~Z Ie\En05~)B-u ֖wգںg9\O'e>?wRaeg_Fy[kv̉qx|ʕwyX㸎ZxKo .0t !Lsb%_EB Kp]ڮެM(x$͵ݎg0rFĨa<jg$(%IAB.GcPܯ!o³7Q1ъJu`$a G^LV q l!؎4({1e)5۳s]\Ƕ T ̰fAޠ" < 0N|FW (!%tL#RVdR 8nk"US*e⦤̣<+cO#BN6Dq{m"A7&`"JVDT .4 7f˒ MOk|(@SiZFE2bȥQ7d.U%C( "_.8R{"am$e:0dwqS oAӼ,Ҵ`zԐ#h#ج3 ]- `*?و,B1oZTcHSȋy\IEnx(TM.GW$I IƦ0jmTxvIcBC n2/0`|9mo4ڝz<{ֽDa&y6³\9чljLb~ @M &h9(nJ9YvUrC"C~0Tp`L@ c3NZ(=_5 ||&<{XJQ-5E$\| 0.nߺ aQ[[?9dr8Oo;;LXV8,uA2;)||\րdG{|m瘏u0uyL͝36)s:<~y_ 영vk蒋 ƣ&S*&`͒ Ϣ#=IFlHUK5fAǼru<'J.AG\d07#pW(),Qo~\T(1*!"J(ԎHRm9G^ OKGlC%. "$΅ĔM̓I;M'$*Ut4V+Ҭ@+86p- _rQv5 0k̷(zD; 0jZ\"PAfaYda04h4uj|wY0oԎ]sGE_~~)(_nz @00f rlǩbR"Oل`3kzi͝QIK" `Fk޿_FaR(Х@5*op<E #(ZǣB(~F"F<֊Ck*:0")RYQ5:D}`G),? |.\eC8dY \\pR) ~ݦMeA-'#Sޒeg/q(ZUxv6-, N 9!&W=ށ{f865q#АԲȌaSgoE=N#2)a,YK B3 k 2#a/ b +GQXA?:5~ǞZxJs|SBPS/pLAQżIMbjϜ1f3:8=ٝ,Lb.Lgq ($?d-E dAM~[q$='G4fH`b|KB Cs axQ&ist S`'E;ޢf0 x5bP_V*F xFMwi` M70 2K/u5YJTZ^< >=@#M @ L+)% ϳMݩg˳†7l;c͉m?3ku4R"/ն'XЇǁT0%SFٟ,w.Op[_''+IEЁ`}}(Ue~cL Smݰym3_f9pV&<=!(gN{2Q Mh30dk}DM}#4f_&~Fzv)cvʱfgg\{1۳C(`ݴ8stnB1B㖇001Ech$ 7QTJx^ <, ޙk1CZ$ڎk`3o` baTM>yA$@' hNQ0wJEC:tM#n(DO} JS$QyvA% 1r0xш966~;O%,M@'i ,5=HF J).O=LS^׀*V tb^zí} /D.Sr5 < >ϛ| |osq=qMk~C;sNϜu8}jwj6ЗBU2 k!% K1* D=ٸ+3]WB ǹ1v-0.zŖͺXGNq\B 5~Qf%y'Q"kHM/9ę́oӻsg1]0V-w&Ě7fKD|G<-Ta,p)ē[Yó7n:pnW_;igJ{Mk:Q%ũ~omom=mp+B Mi* diQ.n-6~gw ,|.'&*bAaHjTa=0a̕J.X; S`0 ϭZ{Ubou$3U:GY4`*ph1O9¸CmXjϾ/#MkQj|wi'q{GQ#yKS&[h՘i`ķHVf w`(o$p%I4;5NP[8 u0 2HYC0弆 {͞h#4#9'ne\b !قt g:uR5p!2>t+DuR( wdA~IkbQfC+qUx Kw#Vhf[.%U xa7'*R ]턩񖕩!x8$:u+1` OcX4Ee|O_1+5댎0j"0 spBdej(axU+hPK9SLFWQ9{ Ǯ(;Q(@A6"QC&G1Y 1 Y  2nX=mp Tn gxX3Y42>Y[״3*{F6o$l@:~["˸":h1%~To4OHr#Xlz./K5_R:Ow8ƴ%(Ј5RNI) 'Qpu[B:'*8D 2Y\6]׶{vIc.~3(_v;X |b #3?"ڡdy +8Zjcme]e.N(b Fx42U׻cHSX}V23sZtLd]\>dd_ƯWpK#uGc᜞r=bn fZʢ6BM$<ؖnmE $_gӝU|-?BB ,%?i`䲳Zl`8#$Z oZo0pp\$0MahʈlZZ:x25K68"(>jԶMe3Cw}ڂx^HU g/Vs"!ˉ1[-Uk=Hc;4z5 /J/h'p0LeQ1C֮Cvq39 1n\o ƁO̓8hoHցʁ9^׀p)uJƼ9 5cuXX8j2R4Y #uojKex|L,YE۹\0Z[$e})h8 CHC?ݡgkW?H 7.%epUh ۰sB/nu>oUG1u@ 46t&F _/ .gSpTCcgg_B\w*%Eb`}GI&8p㖒hz, ]O׆o0P&Htxc eTP<i j_Ju1LjO$_/KM+Ԇ/xA$[>3K\B]ۡ_xA[MCfIJ?-f9n ,LLdXwX5iʳoSϔֺ!`b FܱUĨ4^bI:۸ʈ RFki8@ lnDl_ (z;Wt*.H %bRabgfvSz3m ڥuGJJ2MК܌rqMϗPs:jdgӬL 9:꼱mN{\f0j x5LE;!表Xc`%4kH&MFD5j 3THw~*=\g: ܜk[5uufvI@]b,L;73nU|-*?9p'lֈ/yUN#Փ}˽^Lu#Kk|8K a1v+%6,:d%W% wL mψhƁpz>j5Sut ZEG|P)I齵ajdkj*p!γOA% Ք̀YQ2\2 Jim1F4^- P5dCJ~le9 < Ou(qDR]u4wYjHIwN v'yREo+*F-gIEbC .\Ǡ<<$6{2 $y5bEXj `]Җ(s y gƱneB 2|f{ufPw``\eu6>Y㜔v 1vWp>-:%97xk]8g/l۾y̚jN6<~tZ15#OܪQNrwks69{0xQ hY{ȅIBo]iɗQe!cJ2_ݤ.KaF yTKVDFOp9V̈́UI҃AgE%|s/"I2x=յDQx aE$/Y0KhUi bpN&@3r?d:='|3g1w fL%y kALZ{H)%`FD8d Im(*QT،ܺjnkuEK3>K;#ɣ2/Uؙ3>V -gsգ`#afb}OkM3 ad /[-]mH%zAGm]G\O=1G/$ĸ`W#g k.5P(׾@P b|Cb2-솕1)8=j3XC<8n{q^+vVx(KpJ.iy}UfmN I_ \:)k"!ʕ#!ݦc ͇g/8V֯ tc^'!0HP]"m.v}ACDT;&F PUGgaa,~ٮ2nrU~mb\;'1%[8:UK`\(jd|ݷ*5GAӜ>hةQi+sr=Ix+3Pmh Sؑ]R|{S,[lng"O{l\?Lr|jdwìnڍ_ ;noe0`G[`BPF^06پ 0>m-ĕX0Ld a_n D<{J΄DBpy>A}ҮtTT.}VGY4*Mqc'yhMнƸ{E xv~˂23~SBmۘbDVI%mYڵ Ec<<©8UP:.&x9<)Z`F]=cܳ#V&ة5$Qf(.J7F~IG.:tYnj ւBǰ ۼrEk;qV" hԀH2<=;6'8`q\,f=ݞ!8JX [5,<)J!Уhmvi\'J(HPUבZOp>!ޙCZKh-FF-ؕ6?H)ac%m'AvbES7Xi{Sb!v~!V 8Y[mN%ղqc7;'1)Oa&cy65zݓf-1!]m'8SiY~08<>]&YX=6g9(|Aj&[g 4Q%(pualDup׵x ]ژ2{[^3ՃDQ P𷊝?7PtMXyn MExA,p80XuE5v)F@g~~)˒@6yrDQ97wS$F >Ojrpxo4Zą@h-V7jW%C+.[nVwH)j}s1=ޙjyh0;$q3ԛ< zdn8q3֘qpP`?wˆ 9{~0 n`_=Bw"\S*0dx>$Q3 ]a䈊2 "Y:D,K&JSt.#Y eUTVE= wJhI*F,G!JȬ;\jyy,vh(&boAڭ`yE*[ݪ{d_Ab\&.MY@8+`f'SAW?$0ւ4ȈyF- nVoe0:HۇB"Ί2 4uUTQAӳ6 tEveE܈wZu钁{kX0?\wBCm5}ydWy_Iؚi1U^۷'9q ;!Ȧ[OK [1`l o2'9 69l w}U)虞ϬM5!?7nd??ay}\'yaqGn%ksp|sFGc<8276.^;ǙwmXu}_[C_[{|O =w7=S~jn/[[A 4| \7Gh<9ܽ8ٹq~9Hq{ñVñ8:_(5nS @I՟N6aJ6<%/r/P oZD¾-aONSO$aa8 jojVck05[q'@ ?HC?96(2(n,Q|ڋZ[FZ$ ^m" xlNlG>dpm@| E&90OЋ-ө]k!CYgi;D9_b0H<AzgVA ?Azp(/q= xw#8QWT+bk@Y[|cR(1*6{M@:qЦI؆g?@1({^Fa ,M.+,7 -/IYj6!36mSuGs'DoвۥuR@Jw1Sa/PwNitW:ꩀJDq=U }]%FP{.pB%׋b R- =5mz<{2i>zFi"BqDfv/T " /SI8F~`0Z+U(W=zYBz`4Cx+"ƃ ?roтH{Rs\Sjw;AYCwsWEOAqyQR\Ti62̂P<P{k QIj"MUbb3'W>T<44R%irѫ ŏ³Vya$)KQ)ګ}+k{9&v8p y+*wVoޡi` |,7tgbBXXX ԍ?쇁_Q=K]zT b$끲M7Ħl0Am9LGsj0 wԔhY-`g̚E`?7I -5 fu0ϰ 5ZyC=<1ox+]S OΘLԉ۳Mh5MmM//$wR`=*t )+lpi/%Y74m?b|ƱS $}yDDg=>ԗ  ~*Լ"J0 b ó)j0T&qK1dVp,U;UW^bJB(=D0(Kk%5ܽ[\Q_VTi ˘aGDx<괝Š3hɮUNI qzDO|_U%w7- CY d\SQ?,g^S͊x㑊>"cAK6諚a]PxVUF <c[-,ТO-߾U ,I'&zR(P|[Q!OċBbiakl Z-$zq͎_3U.8D^Ix|q@d㫗AHr*``ҳ䪊U08,(J . m-~R0Ԡ*4nA,0 V!Nٲwa45[A$ R*;xHӱ݇ULe?Um)^xMb}s2N䚙~j[жcboXd̙!V[T~*"&CnjV=DNqE* = ?;#PlߎCQ% xKҩGQtF=o|d.g(;&Q8Ks]OZP&iŲ/╗ KHa;0NI -a0N!:6Q!: mT8>O,HQ4nf;Zt,0hĨPP q *1FOq)*NɆcsJhSѷSD_~{"ګ䤈aSV{h |pEeؤYƐP-)Lb^ң~QGiM|*610 km:X$gͦ2mZFVLQ x FW%)^$j5>]AaT Әo7,k`.Cc=40Ů"KVC!ਫޯ( aněp%8<,3#]@hW\/8 mQoOWaBQ`s$?ȣٝ6=[ӸA81hZ oZG/`IP6{ukkaIqXd8Z-Nak[= 2H6﭂Tœn ? ܮCe=QǴLM9 z@Sagرr\ h)6I8Ja9C.pD> sB(ҐEd S/KfzU#.f($SØW# cݐ q=]`OÐqe Ga9-F7K?I|4ᾭHcKw -Ѽ@9&Ӓ@ .zƧa04UCbY;q;Ӫ0O~E[Oq*2]u'm*s yi=|;FAF97B16 ^X%P\Ab)J yC2:x``2=PwCϼ<  ajԟ Av$NGQJڥ CAK2..@eSg ͓8Ƀa4P%#,y/2)9B;sSb^&w cH oHr0$(ðKk! 7^Bb5ÿOUvʹ(i>ONADT>~1WP\/s/P{o oPڍ0 nej:m-Bl?x-{Y=̗&XEpG2Lf6!Sdli`gfg91tcs0ECCkM%־?q%Q0 p֨H,tLvh=*S:Ե>~1?R#H) Un ]©Ŵ_w({kD!Ą;9/`/ڬ[ Ijp>~18y(I>h߬lA^ $2:zc VT@k$ neSWK#(f6b~c\'>9n9-9lNI㗘B@s MzO"x[npub nc*>20 \]SG4 : G) ,yFBhzUKw/?!zΚ&iVshN`h<ˠbM!Ŀf.l=IsEԅ;Pa³ xnWNz53/M{tan>Iw#K4evWGc_\E+T]Tf QX|Pl"i$fLۮꂄ0<KPy }HI3pڹƒG&5h^ Hla.2HC`\`>zS&)1wqC1jIX4&@ )bXWD_.SWis=+<&[EXჵ, /?g5g*xNߗt}$~!OPl,Ol"o?'|JВxxm2UnoMx)p.޽\C)RGIjsʡrABurP8Ȑ@ v}D /*Щ`4wg95pSB\yUsRtLisVSc;HОyۜ} N +'&/a5! !SI^h#$øH HCvM* `:SYŴwj,M",uWk Z/ &|я5:.靕9B5J5{=(,a#->ebM>/91۠R67s}V|^NIi1Pm=l(%Sc~h]?$a+:%(|Bra5pu]#kw$4vȘF> MgűXxi,R$Yjyb|I@ a}-":УWL67Zl9;xAE̝ZDwvG -vyP̙K9Iy.ÙKd+"BNl?fV EQnlUTLW EP(*A7ńK6N`/]@i1Y5E K?S ^!;(ED@I9+ ڌw)QDyfQ8ma+g9.ߓeGpU[VXxT-8ST(ptMxӮ:hIp s,Kz8K#tB=\`-*Zt[(, ~杳TzOcA?Zc^A}Q2ZBp ' b)\sk+r|jx5~ }e>XӏjAC t#!Ab8G^m G~b,Jz3i]-laەW5|K@oSޘInx.T,JqMGie[O%<\,S(9Ǽ7q0An tk)<%x-l Lʰuh:a[ȲGJh[?TU҃ rb!M>1-͂F) DI!"E 8?K5}[>< =,U,yTKm?N+YcA2y >Eq1M{U)0mJ.Fho;oW r !^fPthqe=s S/QṗN.5/M!,A)Ng/+B!SoK[,[DbLu\xO C1H8[olU!BG~N ng{P*$ֲo^=gǸr+ӾM,N + ǭ*GD|@Fqe`i}pKTxa:Jy$4kKq;.$q2L궐 dRO4H&A3;MӀ% dpm)}Nѵp^tHȱVX֯8x[>(zUB xqH,7F:a{p-:UN{)]QWnq, UBS95cw=e]}aMW̴[1;n:Ӂkfv/s=^|)mTU%J|xrCH^부qzvx1=vv{&I qm,3[3!䆻nvy-/0U'uUM0fN6gٖ6g.'n6'DwzWQ(W(ST?L]b:삺"%1&5 u{hSqIF)6 Yيo ĻԄdnd.15T2M+(8 "q#cEdu: 2 g׻NNGRkrf`Roc ~MlܥP7 s0<,`j畕icd/r?މwX "`s=~U s>T,8Cܪ99Gg&MХŚ<٤xQ._c!F3 | yuejJԆۖ>-cɲ6q95pmV˕|D o yOɩWt.ݣ6Z쑘6xv#;^B]Ɯ{$3OTm[Dp 'A0ϞH0o`RڋPwklDzd=D0pS+0|vMoEQ o &tP 2-/sHS7ogT0O[2؆O"Cp{ =2,lÝZ/cjE`1.d\DtYSw{YE*w)[ƬND׻s(osOI=!`Cz\m4Q#sfv"/g~(NJQha]A/Wڗ,+(pI+2u(vI㕣G )Għgc-) Vw9Umbz<{R݆yy . x!s|||~:Ƅj {i0Nhn5h{~ީ0ֻ=ݘ/yr̽aرu}:ӈ6Y0oMuG|-]c`"'G `)ܗf(R]y2J"0segoP7H,1_\@qsFۀ7>8Z r$H}DnʗzQ~%8v)OAw,딿RCfWOrfgg7Ϙ1D^X'|Ogɪ0Z)rl{^:?^l 3\=2=tڢ18陇~8Z ,ў~m=<!<"ē=)B(1lG/n@("&`C5+(oy`]/k昸 4¥7zSXz!£UH&~gc:4:֎wGqiG*)IAAӫO)wxD~ Y;qrpJ.Na8V 0$i\F3R^nA EER!yȍ0 b0) #5Xj5#~އaPX@ E3cVQ&+mb}{Ap=VvD05-Ž4Sa`8msB'SoU$?Bzb0y+r6b泔¥, Z:k8e/L[H^WjWnҲs!h{$33 nH8=Y l<%4{h^ B7HA{F"OK;ΈStZEc#vyi69,"+6rj] [!aQPDxvŸ5N^ 6\ЙԱ#:C`!uzm lx&p!j{le,V7,̙лk0%==AbVBN۰5:ð Km]ev]Db[ |ܥšGPT"C j!W;q~[֙Mcl[3 \Ӭ[6geicY:P.-x킄*'){:."٦q85:Hk.!.P)Iw1ppꒁv*4tUi餯jPbO?G 8hRQ|%Wx6+4v>ծXn}ݞx/frʽRyda| DŪt_'pYyhXzݪ %ULRG n{;'H3mc{$5q-ؿ7|*᛹Ic2Kgljc͝aŐNhdF aO%?*5x'N;&#-reM200nSuxx6Tngr榭[tU+_PV""-zm~'FP =tK@ G!_|&𣂌k{{ 60ϲb:YP' UIrAKmZdfqFllV{Ǫ&{iy̆`sq@Lw:ܤ +M\'bP oSq} ܃|a LqPB5)4O ;IQ^nnY*A뇘UH^ﶭQMq HPѶ Tˆ ")a8Դu8]ME=)˙O Mz\5Zv˟_XLM)+e&LBEO#rR}ԸcSCNlPYv&yToXY\`>jKSIyDE_a,;x3=`+6MWdPyϜR/Tq`U ,&0$&y\Dw*E{JqJnRC܈һ !^kI :|Q' 1ึ@.7":㐟f@.mQ0BpXQ!(&@ZJziw&I-=pCjœZY E:e(@my^m8P=ܤnptԹeWJSC9i@"X׵ӄn3bϙםzlL' Jܹkִ~G;_!NQT@ˆwBzo[3rbTV̿8;sPhUY7Z>b^:WFa<xOS ezaHPt6b/QHz 3~Sac]t9XC}0K֘(jgÚ~fjh cӘm[3s=ضfk({ *1Yo /."Ka(اlLpXEi|S  ) 3j1̖mhFlrJ߄ll >5-@cPxUiM+w)rK <7(fX5 6юgy5w3B¢U]o lz =((XbTt`԰^<$QT$g@#^h:7;Ȥl5x8VcR{;0*b`U=-/Y c^8V׼w}4ugn-0Re b11 u61C]@ qjtEYxKrWNY^Uzmr~txpՖ@^@AIa5P-Oe]y[:˕k:ǻo(0 aҵK:b4C N!cS7Cāe Ɣ KFQY`Kr6,4'8sפ3YB5eT_S5'E?H`Ҍ6\$X~^(ٖөcvqҟXHaXf`1W|;vaDžYaUgeUS2iSk-dNK/  xr6ñ$ȃ(%'9R**:SieUqXtݠPKLB9GUa сpwoӪjm ՃZt L=M剠 F«ZGf x=]P @pM%1ũY}$4vT[nYM,poMqf[l5)g³)=* h~8*&B KSMhQh$D0ƍ|!iQM*ux(jugM?QB~N-q]_jU"Ж˳-qB\mرMޔ׶~]0rNp!8rEĵjM.So/ hBb˱fb?O޻D@=HH@G m.'\Дa<@ #Lky^~a?I[blRƴ7{@ VyށDW%>Ik/&]T؂v;N+fytm P2(q{@ *ݣYq4"lj W} ~AnP6c)!IM%/T!_ 9QH sH k)صpe7 BC5}eY]_"0;tO{}d*)zfdTva$a0 Fl D5X@e$Ī*$Ѳ`)HGs9׽Msn3Ool}u؈{k|n<7\$lxً"bFQR.$ϣ qgW's}sk2zղ,?~#>|}#?cwݸ_w}uٍ;ݕχ>]g~^Waċ8E%Eqպ|9\9s~rUkӼ|xS@yǠl #ƥexR9( EGi("O׀'Ӡ@ FC_Sa=HdGj/}]x|x`\4"4]YC0t׵kTKD1]v=@F<FTó?V@ /"YAF`a>.}g(*2ZiR+ ^KP'7RQ|M6zjkc=2=#OŠI3=%S1m:i{~\Ӂ=y&0k۶Hw(>(n(PEDI".0=Re(̀v5wmnlRbDH (F FX=A9 3-^ #Fxjw,˳@}l%Em?uz:k:^O9@ߐ@h9(l!|c𔅶O%HyR,2[F?=(ր#g)%<]q <|³p5rǧ{U6K߹_ u-8<prlEF_i ÛΩrBYxrcaY(W@W((SeVŵ1JG#95bp;̒E܊nOzXրqag>7# 2)0,& >>Jgzv- ' qf|Y65 `+ aJ5n(]x6Ed(>xq <†*K@/RDYDCf'&g& }CN&v}YI>;R g*PP ` |M< 1GAu z l_pC&;@zF} Ɲgc3/7yWrA|B~:V゠(y˩n!vR#1/ jyմLNwu4w}Z8h\ $-s0a0dUDMy]BsAw(x**C_4]OCuEo 2d?XbK w9J7]E‚i`zjP !bEDL(S2U7__9jr躎 T.A6,JBV4U!4񳒢zi0ˇFHXFCZ`P풖2^ATgd0h4mb躾gadG̬k\mY^ PظF9SB}պr%߮ۦ c4Er@(ɸoPKIe(O%yF0) 6AAZp:660]0~a|6Δh4Ge%`3# ۧlö]{wױlfh5 8LnL ZdE"YEj:*tF)l!9BtWNll>uP#u[YO,%$e"2A ˪4V9E6Qxa&$\|:1A44ec9˵M;־m>[IQ. mnl%.,`#"!š0Z){3L)Y tn!(\ފbU(cli 8?l4 vZ۝X6x̘4n!kB6]?$(;󀧒8/ՐX+uYsbA1y겲8.D߰(  +HSy 9RYQSZPL:4']¬O*rA^(|֑)8er:rIO+7ƮQS+Uxu8{ վP`0Acޤx H>M|f8VC.goa{p:cm >׏=wqg.?)IؼB!4~*y˭l&lMЧ 浸Ǫqro.n9evK~׹qJ]xU|XXK6Ю tJuxQ+yU`,F iG0. <_MU]f(Q `]vZU쯆<) t2mXpĢ=\z@=c713HQFA]n|pb'~ IIMm Z$i- y=%v1|Tzj.@g³A$`)ТdbN؜8[z^u~Q~e;ІkHHH4:0.o^>\ høŋ`<Hm2fp~GRc,9[[ @ ҷFXqQ%",8XMpch2/!ԗ$Y/x g7ml0eD{Jt U5x@`tL8M86կU [`W).E|"W!m|-$vr]Qabn6uZGZ!p8L6 _O?DVngx8܍əMl`a@)dӶ## ߤA[3pˌ,e(LKy.9 M<&0Jv Ha0_^YF56NSRC: zG ôw {߶w q|utgW,s2Nݼcۖiس Úlx"~dIx[!czWRʋ==C]4GqpXq<ֵU>ӂw屟{R@XA(F>W0E^e9@ ,wI^ڪ|D&LtǨnojw<`x_h{k:݇xCsv tM״ub)ӞH8hȆ ‚ctV43 phb }⌥to|5QT60KIKxw):`$ ::THgwű[ՠm-x`J*:.Ukh_Y:iʷ.  UsM?̶4ܧ RS:H2 !Rrj8RU4 y&`)lM,bk"tQEݿCql*ކ=nY&`@e>$XO=!w p{BkW\&Eymj#5-~ PQ"<Qs]th" 7.h,{!88iMy5}`"ay$\ EPYZ[?vxzkJH0v-"j@hMvGZGSLIײ׈HQ(TTq<&(^0h2&,5"שudO_<$e 8<\ [A=zٮH٢1[k)~sG}\טmnm0jE=H ,AT1KIB^K2>. ާ!xQc9w e{`ܺx%@_(ޢ[0K:5zgQHɄm:햶mtCl6׳|ʰ 6O8jBA, 1 l<0Ak?O$ݮ6 E.ؐT+MEsONSK_x祯Hzlt!.pJ9/ȋaY̫].Mf2RcunvΗֆ1 +p.H|3v]f[pOPdm(ր~Bl9kL2ZAU6zik9y"CQ4% dX6@_WfرQ/ P"Rc- _^D b l֣ *UЅeH{aXK"b @kWt@CP.=Ѕg5U|+PgXʫ y!U(M%P }TUb E ۊh`/3($x͎݃V;T"-%(_?(* &H(]q>|oLDku;3Rm A JP[r,먡@dǵ! 7Z)Ú:8D'.,Jp(2Ye*me my kC,ͧ \'´5u ؀)e,p惟+v8z8TeJ.=`鳧C!W% N%UnnvZϖר+$}9eM{LTXlGtܗIhdwl,rTWQ)H`EY=Fκa HXz- wv~Y@ǐ+Y .6(ڶFBR(I~*:H0;qc\+R;z CPV!4>R+⟀Wv`\v0c,FB Ejl.NE^J3sb-jJÇUQYg@Gü6vo<*1 (ZQF BEZ.b q)l/z6E%BI| {Yث*?z蛦 `V'Et(* 8$h3W Tʷ;v2d G}]F <جQަuZsmgzSښX8;a24͵v7ݸcM/%./zP@@@aqi^TJRjwGKߨ@8Ictmy$Ea. >ǽ Jj-?8dC!lHa67B+"?6E``VHĂoShV}%1"OWVaQ1C1 &{tn=_bt`vUP/1., 6LۡR? I;ug J.)JXMU] 2΁ ÿrUn$yѷ u (.h't*+Xk˫xUS;!7F5kl`1"Y# }Ž! .}k.#0ŀx+2Zo%Й^`k;iGާџϺ >| H6', N4|i ) W8<<;yjiI5dՖ& K x5rMG,IQy2l-^_#*?YU5~eZ|ztEUZPh< ) TQ`W6sA\BpT߳=ԧ¨;(k_i;y2;l6N4:ӻe[Ӷgm9>Ssς׉})wW$tK!@c׾67jG[NGxxGQ.Aj}yV_<.8_^TҞ^eMzh.\*Nb dzTQ7T|"M[VD zWl)={7j;VKJuPȥKmF(x%U8C]WQoZ\&>hбǫṙW%TӺ1*RzTKL>z lx 3OMu&uBȾ0k!ن  ^`jJbEF cbN+<лr,EFK*};;\%^<8H,̆ lk&ckY϶P쏔o \F}<Щ땊akBb"_dq t_cc`5 11 8&!ށ3X~ fC%X`Vٰj4M5["Ka*W:ij;DZ?.RSKLe/)2.;JW!l^=A:_Q*Uͱ]b O2ޜ>WqPSYC_eOa4񢨂_)?æ:qrG*(x]&N V5 CO2v k`0lq\f#jeGV0bL3GeʩdFqȒ) 3ysdr?n]Ę/o̐!~r>u>}odsEÚq~JEZrmK*KB'o:džy鴴ue} %vm°-Q:Z2M<bi[+d+:̮  ATZIv~ʵNUwZ+NՇ sR}h9t v4Kh@?1=ޔg X ;[նwpʒ8,'L]1*CtS5A7Hƾ<,$fzN]{9ì^ pxe -Mlcօ宽Dѵ6X%KpF&Abԓ=cGѱ83`@2C7;WHuzA^Ms5nشW$ov-9YBndMxo c07:aװyO`bQ)/C C韴|sl]G]S/V}Dp;.c`xB8JcWmDт.Β$)ˎٷls_V(|L? (ښne>z`9!/eaɅ2 H$OLݙΘZ0.G_Haw'-8'@ĸitTTa`wi\L=OV;ǖFÃ^O-ѣ@,0)`ۆZy+Cn]J}8tO ܃6FG~#9$ւ^7ܗā?(@5X(W5W7FMփc3QMhsמ[%AM $Qj?;A~v]<6J;WM:+ +K/J) nW?bLf0KttS[oeI^UH!KlaD!j 6tP(Q0' \EoQ1'QL Qc|BѿpaSJJV*)A, $i}p^ T !lD]%McVb9. wz1̙Fggvk4] AQF]Mj!1I4v~`0?C 2^S}wa6o `H˄DgMx#_I0s|t2冞ڱf (A[VmvG"6h4 qbyXg]UXBN`?ӴģVwѫ˪W+0V( Af߃'tJ`xx"n0?nh`0FE>lpn ^esRx[[9eMaS*_kr!)tڑ>+6Y{_k.[ =/IR`HnwDp7?4c"ڱؼouzCL}}Rv6: 莮7ETȦNpf31bNf[7Nw4J<4&(/³wQI1iG 0';6ȗg=Gw@IMں+_{HMWe ڢ^jC*w\Ehn2-)h\㎱7N[uŨ&5[GzZLZ%VףP\b_jt$p 1nv&Ju(!(R%XE⛧Q:#, ; kf``ؿo-S `Ycb)L.ήiϐ>^302RP%onE`kAݙa9m۲ 09ҏ  D sf7ONW+EQr|>9=:kT.Ft KQ~; ?Ϡ;HKL/R^G{pr\ekZU( "^\ŪQ/`)K :.u +K0<5ujDɲ1yk :P!dAdjs/䭝:okCX&%Bݤnw`H4AY2mKJH|}Ke~Two Ԋ!d2moPCUU:KUޖRmV *h8E^L׻-m0E`[*X~8?Ѱ|g`|["աm>~E_ֱ,.1]*/P-G7tDR Ω˗[gG9SsG<)" pի%KqHvx/޻>Md;OܻeojN'Sp ǕqvƂޭ>Tl}(GA/O\qQI >ͺnS?pru&N.!@e#,+$C|Xk\üQN ÅJS6=[^@+@.˽T#!VuAj7ueiyqYz,~.Rysɿ*ȿ!l-r4A]j8WW$n@Գsluhulk $:F&%h,8TVߦ>T%$p,wUזиcO`q Ԓ!h\ hO1cULG@&F^Tk`0|y].閞y_}7۝Oj~:yyӯ]niJpyP5'ً*S}֊k@}ZvaD X s>q<Ϥ_~sؠ?FvqWaZ4뚣H T{9"I_4A(Q^kJ alDH,?c0G1EIw- o8i ݞ19 s<ړ]y&QvO> ],seqįvd$_:/][B*_W\e"i7j/jGB`F g9gmʳ~FAtfꍛONz^!:GPi2ivr%3=v*z&Ur~u1~,/ Q\⪥00>1_GMLc7\wMnū?fzv2lAy8^5~nuC}L 6_ۮ[ y_*^75le,q sԍ[ʀ = xQCՑpn$|gs=Xm[ /^-M]zD6ĢJ.I̒@pOfNO4 kJs yʎaM wNŸ\{ kߔd7>txl1W؀A?""(#Bac?cMYp]˲N : D}u?w"|~v~~N,rv>?v {kӁ(^k+Ax4K˂3՞6oЗ=e)N}|ի/evq=?k?AEI\eicVV;Z?%[n͑w E} ޠAY**ڔxqx1w xsqMW<\][6!KBy<9~@T@ja T(4ȓ+[9ng>^B..mދÅ٦C}slxm'K۶/oJFzJZ"UVdYi0>d_}Jsc1hp >AfU 4Fk70@0YN"Z(̫"HZ0<߉/jp>FW!xI`@J@.ǧWSD{r]jQo }A,{ulQ^Bx3d% `F|4KfHnj)$!L[WfYV( F`w*r Y.0QẠ my *B@"0r=a&VT€ O sWiUX&Q<" >u6u)G׿}?镾?Lo""Pa)ȃ o$rGFS OIDRZQX {=@@wjbѣm&h[hO,g>1hax7$XyTg2@;I<_8 I%@ݸݡotCݻ5by4H* |[+Q:+aC=md Ω%qO¶+Jp|g|D!P>$q('>L?]{0 gw]CD!WK2F ebc`,2O۰o%+~XЭuAzgU3d% oֆPP`h,@r{6|\U6`11 ʰ@VIpf$N:"*́QYF#DwNyNŜ{./µ!mhԙ+ )|`ʠ()=Vּ{aYhnjnGIIb.sLaM*򂌇,OoVL*K tctal>9a'V $ry9uXޝ,w0-Gp:&a}ض1p8KǸXqrq !81 c K?2m(* BSS x+ <ԙEmg* n,B 7ởx  ,](9@ψyM0 Tz`%YΧe 1Khp}E$*KX(4,0 8>?K'x,gxgZOwV Į,*b _x1sg훦f/mXP^Ne~{8#" $('Qm% R -b8#ئN8Sd *"h໷X+$cٕ` 2Y##͟;̯R`ЪE#l~'4Gy][xFIӧd 1 -^sxDca"}˰\ `9Ǽl/e!/LNi]Z_w`XBI0" 0]}04 xl0 KjX'X}ΰ vCRF)B YP7kaczٌ`5WKOX5%yUEՉ<%#\!#ټ є;Pu)V46ot҉КpSHhMMXʋeBA=Н ~$1]*@(Ɉ @Ґ_J9e }6M|KY.xiUY˘>e mxȽkXAT>^'4EmZCVIlyFͮƄ=tlB->3ljAFNEN6͞-a:+L"(;bIzM^o~Q JArK"ùi\&1!`(=qAg7BrnS?d_Jҳt+o T#(*7MnTL96vr=ؽ^Vq$hiHDr|넜yKq}{|=##(iFq&zlgk"m ]boQ"H8! lFK)9Tdx{bT#Ú՟c4xVB.n$/@ߍܚ ꍧUZ)9R0|$ÊW'XRT|tƒh8]o~C4Dq z7O>ށ0L)@/vUxz'u Y{dV BQ+`C?꾰*EiXdwky Z))PO<4pk<7$q!4={u]rt ȰtY֭֬rzʌo4ebr,JqyP۵.q*R#Y? Nq^%E.ZTgw2KzI1N(ԪrB~k\&yXC"U{֕Rw*\Ic\ŃZFٔkP8>x_vDf /buJEgQixk~`5(X ,qz*jg'OtUG|c(BTDN"l˴MV) p"HBee/Ѭ TKdn[Wi1`V)Ix |F8irkhRV!JL`| ؁,H#"DzyZ.VLEk$ɮţ HلleQm6fYzDL#е/lf(p vw=@3R!nx3 r:+e[FCzG|;$|l u #U;{4!>lHeMZQȰTHM]u'gCg]' B#n B^VaT^ ϨgKx h~F4דY: @nLс4(H#lXUgzmWT[ u̙gy^n* c~śV*Ag~dǣTCxahڰM4* r, $=یTZA>q 755u^]YhvԽiTn@ĘҢ,m<:2e!r[wH49aHcl!skM7 ?)@ɰ%mAaz&ጲHCמ4PCx +GT砘 hmzp@{i\z]CxwS'Om+aꍧۀ@Dm*${h21-gtnt1Ľ*Y X-ղ6i/dq:0=&#-B7&`4g".$^;%dy`UbUF|;5脹}-kּy5W.Ckra@,[/IowV3)rxbQ+ -Ñh:`7̿GT˵eÜ-23=<5ϳ==cYaMKejiz"{+ٶc߭BkI4;mU ʗYQ!䳓a!?-Aೢ-7 ,j@]O]Vy=/Ks>܁0? EJ {0rlH51}ײec~tvܣacBR.Oe IpUrrg#Mt0QS|},Ue}<7;NZG;= &[ [쬜(:,3,d%Q>? u0R$|L8ڀNF헐#葘BA_7!IE}|ǒy>:htS\pӷ(yB`"-V/ѯi3"{bsSV~@c-yfE9OJi~1Fv+ջa _%jPS`"ȗs b0DAPIM  h?Z=u)6L vyZc1>&;EIv! i[YyQ\lخ c%D|M0~=5D3)B=Y% T]& `&wV潓@ɫ>h Q~PMWnBVj7v>+ 蹞5Wgv3Qs)Ƕy书/_r1,gCLO\cbƑ`=ZK=ֲSJnckM6iXW5€B0jsѹ3??_+۲l5l"?S`vb|FVda%#L)62RwYӯKTӳ?Ve 6,2QV넾u k VmVC)7H:-$;ЄÁ91o9b=_цvʛ.ZZ;-6i74{l`UX{~7ō/Ê/\)VaBG]x얒h|`0cb. I0XV^3J=ƜSa|3Mr E8)?ʳn݀2g_nx B:E9&\uѝgcB%OQp띧k(:AR=yFMP`:=jUi%hU.* ;([ N *QGXh# ]r;F÷.bfMHƚɐ|j˷-aK=o$EqYb"Kf{mZzp6ۆ~)k!R"8朢YdNje$%,qclxtͯ\V4cq]L F.K}b Oi#'y90)_/bOblz?7kߡqp`{~6%sېNSݚ9f>bnu9VƇH4%1Ecm$VV=]ٚnwP #DzC oZ*Xn>ϧSv@ rWⰔx7QKG_mM>.IͨʲzsĩfsEOy$c+]qI~Q 6QP:] >asUx#s}q<:2hXZ"ӚT\mc`ȟ۳N0ϓ* S k3zdz~a-vr{oQ P;- x+S6vMzsMݧB94J1&0ViɒmeA5EPʺmm\4KS`:@6u7!2 ízɎ0ƚ70wMN]0CT.u x ϶cN@C6ms}Ӌ"\ExbsQ&zdP `2gb7P=_ X6F%^dCt$IT-@U.+wD2}ri7F +/'reZ!{(*i1Z,=NB=å`]ϾD[U2mGpSPI^Mfk씡;nw`W`Y^Q>*#nGlִW]^4ovQsOɵN, @ƁGl.6v8tYo =vKYw)# pDIQy Z:w"ߜ NK}ޛb3aGa@NZ~&lGN`%uIiTMHFK@a[ :hf~RaxD,/b0|Q$~*R»k_yC1q lX׎ElZ8`# z 4,xZö; JN,XJFl(eIV CxN@d4;\&aX!|p4;(/F"X@Hc9,.1xte⦗mh`-xQ N1?Rm 6 (_\wbaLcu76F e,9Eo>Ʃx|vnNYmޓL ſԢFl?kv`XseWo6Kzso:~O<ˊ* -E+mY@YΝ 1~K;S v: t#H^* ͧ'-Pt>Fǻ'%#1- ̮e%F~YpX moXo6/এ|Ll\mm+/G~imxH$^kWmY`Zi^tQ j3@]:Ha%9]:H,'z8c뻈v$|Q`MBgK $vp$Gxzk1Qj(ԇE:n b D'vH/."S% ~!Z&0~_C ,Rs ֗(i秞͗~AՌ({ﺫ 1(Lv;fKëjr:I^ylLY8v˪e['!8q\Uш`%=D`$]l5bfV+L;}Y'c&*n:[u0+v}R\Bؘ>څ`ǯ_#е%_3kWg&zM_{Ȩ([e%q\Ip`ٙ-lR F6L>ifʼn9Svx/i3> G24r?A!! !8x+8MMaEKԇ\X IŸ׈6Ql#暫Yr{|M0lUz%" 2= l zxoy`MNbҎ?iPouʱ܊iZ7 8'*$*&&^{LO BO!A`}d3 RAWWȬps:;7;mw܏}d5do}ٝSH CSm*8#_{_Cٯ笸gNYpA#ttO%76NPIDX#FvWe?% Uץ.IC]©&ğJ#2Z oe]9kvڽ,;@&8D3]{v2^ Ǎ/)b$0nd{sZfZҢ.Z?Hbn& P Ě;@n6yMm}&Д*՟kb+ Im Rad8M?A!#~ZPEAVL䱸+ ڶs>^ c#ԃ1 &8ޯ槈-$iԐ];S[%; ' ʰat:/ u b4x%N/'>v|/OI G)@(l1׆K/S@BzaRU0\Oh]_ѹJNS8yIf Tf-{O5/K 7fKyv6;yQ<_yz/?[Dt[@nA\cv@F!H6f! f-ȓNBO$әY(<-SNop~vXz8K7e\"j]@f}/-,0mycDwxH‘oZR?׬)^UT^+IѵԒq?8p#7}XA2J5HwO&`YMWwg69bC1^0Kfx|M d>)->Ɔ%[7T c~26Rڄk,M;&|gJVsdSi}[CwZe1^IB-J9mE=%=kIygv85" -4&ȡ "zf: ODgI`GU /euVШV#?!ð^*˺B_)=;7аQUZ9v2ϑ@t+izu\m}?1Lu ƈ(+!|22nC onM Wdb,WX-X tqEQ^녫#$b?iJraY&&k2(kI;]{8A^5tSu$v|vR7A N<@^Ԩƭ.1:EtIVyX;Ҝܓ!xوρi q(v"W+UW`gU p,J3͙:n#VSK3 !ިvf" 3^=׀8 &Kq~oܢڟ-]p Hm!P(3Kay˸i&qpTҮϪ8frL =U@>cIJiژASqgZ?ߗ6n_aDziVU"RX$+`!2T8em*vcj@& #,KIf@ZK:)a0}JDHq='okkoy+z/OO!qqu &MѨe[>V550^7n.KLQӈ;@+qy#)u+V&o0Ƹ,p(4rqh.=g{|?:;H c4TWvk֋o݈r$,Tf~32Lb[\ qv]K*</c{(#N3qLa#fnƝ"]#\.zr ̥?!p 0157:*e[㋆P}ok'{߃5*g;ab39|I Q5C;/޹9m(J}o@2|ZCD>AOZeF۱nJdu4"{'!%+֕2RG-p(8ZyUSB8ɂL6 K 89dX.l866 <BC4}{eYYߥ1&nOwϹ}}ku~%!aA m "aHxHcJF0@Ta IJI Q!߷uZsO{o{z|r'=cvI{{ s92+g^]|s2NxWIL˲Hvݽ{ջza׽;= ޅ˻:\utŝ_τg/??__c6@AxAG-JbYe  C5^F8]Q8Ͳ\@0 u<χWSR1B!(H#hp0%T*P0Gw68o&*$Q2<N_h?|Ff]IĉD[µ: @!NUZ"jqZb:!PD`" cC<9ev=5Cpjw0 R0|tBC:||C 8. oo Jxz )D~ꔉO)jF d1ԸG@F{lt%}Ά$, dJQG^UK€_r.-,YuUA='i?~&hD8X7{?c1 q\,pU\I,i[2 K@l9<#&YGҐ)IF")j[QȑEnTq*#F=Э&܃0 j e]%hj I)7),ܴ0ZPdUuAlt؇Е MЉ#56}5OrYUQp/ #oI" bi"t'f!HзZekP;߲@H(e-c|C aTVq;LFU*kq]`2kWJ`"@0tX@.n!6B0mCv-@QVv7?<\ i@]BP||=9qh0@e2O(u~5 hbx-ЬE ҿj]w{5!]4]iZfׁxz x7~ bv >z ^-fEehDM~)zAc_mR̻$9F%HBvʮxmeӾ[c«laBE*FLVHDEcH@ \C"r7B0 U@6&BNPyUfS4.Tl4HМF.u  rQ5mFBj!62yA@x_ Z A3 fɍ6+ B-K+Cy;vqw\'_|qw޺F+.2=LjBC4V&7բxGyV/Hex Ak L+" 6zNe.4iAgkY'[h{iǖy@gs&\VgsmxW *+H ߣ){AiQCȲu!&ƂKQZAݽ6!1-\G{2 ("TK X,2oNg**4>6E["[rm?6qU,D5zh6۽p"z.uh!xFne%`*C4_WX'6eyE(z A(i`{WcP]1iJDjIZJ#E58a@aF3# ?rc*5Ox> öoEgkΫjYfq- AknK@ pQg}- ! ɁO|n@!睛=rz xr3XO4!PpN_(e&T9~+ MQ˼ڜx>mn3U&[@SgE>B 6Emrs0FMuAx(^(V٤L=;a#zԴ!mM> q\2)r >_ѝʄSE)aƲ}uێʨuPӈ`pu4w)]Dd:### 7ovC,$bd"@- O"݈a}gor4EbKUH nGsQ+ʱr媚$ʽ%L{LW:"`ů[MBwWVE-u͉ 9vBS2 oDytM|m>% />Xw6=Gl%(Ҫ! [׹Ƅ$=ߦRV k޿#ުgP;! z.z}D:YTlpBk#Ua~|keRJL@h0s/Me˝s=N($/LЁpjs+Ϊ|YF*mj!$)'`Z^ HCRR 07Ұ5a[1AܯQ@z)S~`!8|ρ> },{bS$W@qG&QRG˼ʳafc$  qXmȤ'pJޭHt҅`<"Fz`W ֦*,')AQT L5Yl Am q3>k8˸ Hdi ÄsbJQ WeѦاbQDzoDP" \'ށwb&C=__4Z \]"Hhqt]ފ^IZJ_eFpߧ #2<5c3فEghYAa,궽dע\ & ڱ'i| вJO8aX=0 `r±F٥P+p뢲CE/ idQG Qmń-a;_tT/,ħr}lt9G{7ys[Ą"N/ M?dU, ^Tm3"vNw?V E8߻qf`no~Іw)."4SE8#ds-ŘObe>0|Q\,T*7*%~n#Px3{4AXCpiΖy DK "h6h&"`\?b A5P O%=}o#\I{<2yChw p\ QNЧHmK(G3YG5u;qQG˪,* <(Q0jQ>OzYe<"xEBƫ #BY.eg+"iG#Ҭ lB6N4-x6*`ƕqU_<ėQ*‰Z: K -k تeZԉl{/v+k[Qu @7-DFBҦiٵ|yGB}u|Ba3i @bNrSt>G&3r) E\GEjE^ f쒲kO fd012MԏUc+rˌ:jSՙ#7uIE.{NFc?^8d>9(A52GU-Q;&+1h*oBÇZ* ץµaK|JBE!XҦ;|IAEWj5u~G<{@4 Z1tT3[aB8zj*Wi蚽Ul+q5jZ .yLgpkrH@eI&F]{vAJmYtօ%> «5}/8+#SÙl$|\\e1D O5߼~WV g-]~Y+ ʟP?<}9!ݿ'u,92oTeF^Qhkf%^^8Q.Gz:&#Y_OMz.u;ۛBu3AsuC"O/ 3cۛpV(9h@|x`t|z)⪭ 1"4HNum3U6mf\f̈-NVVo8_ͦ7ER.,.T-[)0w_ G2Rs^ZUHԢj`wvtE.c,?/oD~K>6TX>e)T7ؗWN]}{5jNwodtex4[uh;p"hU9B]E:%C5 ]z۔ߟI=T=pTwfxlVXt!?X ዼ|$ޫ,rmBf0e$ћ4_GeZ7م]Oڼ{U~Q(87Q^B?1+~Dj[Z ӣ7i\*$IAf|w!㉀y\b6Du J!/beu>amB,J9cm ,J7! ߝGW5|>)4O-vlӕY[yРNgRcW};U>>.sExg, :gQBMQX\O{n bG*n xҧVMuǺh$<8g[,Q\>"Y_WEF!t8a|vF&ӷh `CVw rp l"Ry( "\0ob0XM֌ ౔|4j+r `eR5תMgONw\8_Br7w)p{Y{w0Ңڔ\&g:/Fl&רOwz" ;|tlOXxN@ 49<>6LXwiV7Y?ёSں R}F JBͺ#񱙪i- \@$\ұUFfzm=pD 4GAFk e#%B ƷuZPzHЗdNB4e #;dv_mitp9VޣAY܀ӻ5#M/vqou+ԥlk}7!"J䤂m QXwc?lAظ.B&U!G UU2T[f"Hr%mEVK[1(O 2!aNU7A4k /57%m#A0n<;Qx8;kMO>t \i> lݩXQgxB'xss ll>gAb QObfѬ`֛@p?/]$`4m˨mLJ^Z*=&EVC\]H EXPW~a8 0-ړ::" 'jӜq: WM)THJq0?1[NYM}lp)Ŧ -/˃S 7t&^#[\5m q"LvI?tC0p+}"oоA HGFVYVNr9͉p3MBK"5 !gng,kkoiTaCȟZL@:GrDlY؜9X -3^G{P.B™$QudM_;eg"D(Gk`8uiW56GbKL uzW @@V͚ۜZ_H筑pyoYu t>ѧ4,_I.L pIZςJי1^G: 8 gGqoTE`݄$`6XP4#_ڄj2z5zXEW/GUdvGuZF0r/Ө(L- B_piox gvي,Q=Y #j #BeYiCcw1uۢ}!ĝ_"2_aJ]`G!?.-&WtbE >(a Pt/_k4+Fζ{ߢO5EL\Ǚ{p! "z`Կ- :I> x0l\/iQdJi`ɕ Wg;Pώ,Ȱ-F h$H@i+RMBEQ TP T Cæ~ވ e;ގBsR,$Ek y>/[O0O%4%p K&o:ă|gqٽb34bzK{/Hvp)/+ ndP"+ٶW lU1p2z60Y//B\z5v`_Nw ѾP {n0y\vsj]?bxx 3k)<ݽ__hDqD4{_oiw?b0Ze N񗕚65Bqvhޯu@ip,~R,RJ^\R/WB}8wmpNSNjNx#VJeZr݈@cXcLQyDgeEQ}xB&@r̥!G؈:#OeXhiaVEbL2ѕ=vV), Ax [+ˈ,ʝ$Ca$}eJZ5իSl`Ĵ ou!xlSI#! zH-;; C C7gѦK o CŬ\6CK VlL qw{YGUQrh- Cm\;YPɲYTͤ_/>b%{hάcvlS"./J& W=}6 %rozˏ2Ph"PWFQ88lj"8xgSߣ!x ןD?jA:x.@<>Guq2쬽O11WGvt{" n5iڪDv&W9 ,שHժ-GWXM̞թ5"dt!")ZҠ|w;iHF$&"g-K.ei~ƍ)k0^E@',v }WcoJ ~C lB8u11j@':Ny8JN>IghZ@3l~(֯Wę]g_$}1}]VǦx9 "+ 8o|0d?bfD` T7%[A?lLm6#Bh@qh9 t\W]m%iM듆 F$ϗU7IUͫM.}Ҡ ˍ vI4S-3sQqISvr•3l36;=vuOlq0)Zf\Nw/]9=6 dek}?U!Z@930*ɳZ `vЬ#Uѷ.7M%3l;wQ' h?4h`GO*j2KSdKڎq+T;^$` o,xYŅX@i2S'~אI+%\O ꘵˄P0 -9nq뼬AM\5]&kCe|06L+SO"ElqȮt6=gOi3 Zy'.n7 n F"?ݦ:97p,>!#kLO[ݮaBGw}W#l a[#?/h乲ԄyVTJ}Kx-E_>wn>u-xa$*z0Lbt}wAfW =" Ngg+!8CB u+nԥ^ͺ\W\YB=Xdf9`ڛalppIx dώl?1be[4^d }87eí#q]7g4ttr=lL` J )}}uʁW3͔Kۻûzs+D2i]uz|I0O ܓɟg?˚ /fEUB l~ Hpnl œ988@;>_{m]F n? 5+0vx1|V>/nf~dfC{N=u[hv6n f-4A0;ȓ*؉޹pz,J^p_o]h}lq\eL$w^ i/2m-kFX6 ܑ}]Pp\<:#+~qx&1pMQ 6T_7*i1PV`jGIvMch(5덌 mz"pc=dTd6a:eIBs\}H:j9oh#w-F1 wOvPtH\~?PTb4"$2nZ}=wuA:͸U;;?dDN7<3|ߕ4yfV! W!d;gW}׌\*YV{gA1kSCիWID<JMF:~dƟ0(h~G lURH%|zCBBCR6}y%WyߓfޛѼvˮ?oF)KV1` Ycc6ၟ H`dl"0UD¤b[TA,b{;c_1o)~5:l޼ k1rx;wR=+I-bqrkupxb%a8/y[Zgu~:8qn쭭sg/]t-{`y@_ _x[wt[o9|-7>':<8ӵg~>̧XY2+᲻|~v0  W""Z$yE+wIĖO%5a< 868a\fg4ex,@=q]q] A\]a|@{bh"ʪ$\Q8dfd>'L0'%}`{@ 8$ ^7+dQ*\_WԞp1X9BW=!'0MgBV"32E%iqAQ 1Q+. Y]Z\Ţ|qN2Ӵ<hSH oq-O|3;M2b*|G"<[$E+KsI ^HP49q.WIY-EG WfG-{w`&r(/ vPӻ6!DAp ju͞p1%Qܢ۟=C"P2(qȼ *jp:aI/$j*ZEIKju?gCV"s/E<:!L=f\ .g³U$8Wy@Sb'(t#}oQ~S\:\k$:;.2,i,5 Lȁ8`}GF|'YJbmFٜ6*l WDx\2F\֍JJqnEz 9^pM0 V?ڌp^OZ/³SWb,]WEI I6kQ]p< y*eev{m7~W<$ϣB+P\ +O#`kkflݨEaXdikp=KCz}+GzpIzsEyEH :!Zz7yH4Sקw9n,4/l.E4urK&`'j{k^/(e_e"$L0 sq,V<)q;ЊJI,)y X[+~C#a$MO#֦t\FSYXvRTqziY}eK4-)#ucN;BdOG4%S$.Z`"K$_|WзWbƛs}8\ԷOdS$9xR5"@WUjU`%Kz +Ӕa[ƴkz|.U.wZn=Md#b|Dg"zUEQ4%дiE? 䑼Xf8 Z"3]zsEQʃq Lp@'1cG\BM3zĦk`X.X }2Iu:?EQF"soAj4,kĦV dm?." n޸_,_-Ҩem D˦kF칍RuNu}kBt ]Mi1 y5 -#y#hmv a9uY ?j =oF1 , Thu#Øy帮 LYcyA, 3qL_m%Ck84I/i dE6*Ḣ>6e;ijeˎiB*Fa^QQas }N^}C4'#P)F=?L VEɈq y/K'>ck"k0B4ZUXLfeq4B|U߰2!pCP wsm\pV jP#5l ` R/=gIG$PJjsvX1@Sy,M]emN,`5JL3v1S[bnr1yxc"c=\ mU^i<=A3H!r{<]rݎA$,ӠknH%EF.FAvi`]ֈCVAݥ@u~Q$Q!;nY ;bYW:Ic:zLg`*1f:yf:3ڷ5EX AW o<$E nwr/O 5#TL<"c4m=B`T0hku$i>R=xSUK4*3I^e$j,rh6)" Z3gd sv=g{a"`nA'aVXUXn lխv.V2Dh u  $` zwx Lʀ`l ~S2=vdaXCeߎ$Ж.-iM)9ay}*&JhcjZ3w vop0"6qoqO6:ӹas6ra~Ywhԓ‡OQJ*aA0+hq"~!&#իby. ECN4b*W-0ؖ?)6;m.g>1o"Taw`oc~mkT&;˿zӗ8 <aqSy㟃|xS جI˸(g3-й {w LJ/GTjwuLKQthYLh P3&`Qfv,F!;Qvug<ѵ|@}|Uɰ53 AcCJȾg{XL3[>׾۶_V1Di债r-pR^~f104#@Mh1Ӫ,\c!D19  [{Yk!d"iƒ`$`9J}Mcүj#AmfN;J04 ;y4/2\+ªuGQWU9 ¤h@:2AV"[քvlU_}mup6a1A@ a*,i9LJ/oE^b{@xi!`Շ&I5C26]m)`*v8G4#p%8Ln84 @ ?7xZ#f6\(cNA߬((;moIuZ6mT9ƼD jj ae>v͓՘y>MH?L? Q64 *s-J ˋ")8T|ٞcUq= Cl ڦ 5L6,1{y  Iݪ#FrS:u '~R# 4ݚ%v4H[poN'W˒ѣg]KxIimcËA:RG oD :-d,桳J#;tz4I h݋ f2yO vB XQ>؂0A]p^kGN"T^A$1u^!zy`YDz<}]016m9_VI^ Ţʈ)U:Q)\198%`]EBP裭-XpP{(LMfRBȒ*fTPUK_AKc2aOt $sw Dt ) Yu]ڏ$$`Ym®&x0ݕ\وVȀa^0pֵ9Mn_7qˎV!Ju@KC{q֭)%y3a Z~(--r jm zzƨ~0EBQ.1Cj" Y@;{s`-/CMj6ƳUZ@-4N`ԺI <v1yxta|y21z00~рl`0N3)Ki5] i1Di9?- Ʀm[yk[̃1 i_SnkJp`<PRG뙛<; b~S}N2ƅt*F yT,abغud}3KB%j"rw_d,$֯c-1Ef(I[Ei=dxċșHضѢ(% .B pl5`Ӵ0jێ8XIaM'U0D/MU -KRXqJl=)%֥ ‡o).fc _x%hAp3)Pj|`RR90TZ iٵoCvB%Z 7i8TyīA;H@$(4ō;(yd\咽~v' ذEi7h{f@1֘9ERU]JY*Yy-x]YC6:Y.Ă"AE)A%㙒zWu'cĘԯEV;W8ǤOB,xg8,F/xf_lC(؆_|2Z8dZj´BPt)QHFɴ dZ,oң~ϮH`hŁF&<)0l8k"%238'D .+8YU'<&q jc(XIp5a5~0*M K2507΢EQ]WI}/.xvIKŸQ E 1Y̸j/ cH:9jbRpY'?N_<>w=dw6PG>[l0O1"=x+_kMu *RXKxƉ-Oݙk6ݗ1-kogxp%znԟ٬I+¥I0ݡZhy.As>ź4E@±o5Vjz@ڶ _UQ(!`vրXZ XlYf-  6PE"x KZk,ޤ~ U)zcia#-aX~TC&< DC0[a?_.xh9'lqnY/ޥI^5c١-7aϱMz>D6⃛Tʄ NYɎ/3RN(C}_Z~6?rFSd\ePinhpZAq9`3Eih4ʲ\dYT^ |$IdeChr-:(ńdUրlA < ޣ#6 Q%mȇ`0MbšDeAG³71%4QhUVQ@G:f7@ uЮ&:K@ZG4_NN} =$ ^(O4,Kē&_'p]1:LJR;%dTqm˪2iPHtkY D'7\԰=n@P\tzD~R[CF]%rW"XCQQ7ӎe ^CmfqHx7i]æA&z8)!]ɵ*=GS'pś֥k*K]2g=7U)iyITA;2Go*DUE8IA &vDعNmeKK I%+S2(H4O (hN PG ]ij;rkZT%)"G|R ´6363Ox:}6<׵wO)xXl{goWY~K s~6zvWpGu:>8X?8ƽS'nwF/-st&X=Qtz3Թ,R>[q0,yփg j<@ 'k&S\(u WAM_1,@ߤ(xt.B9]@ "#Qӈ3^D[;əBM] &qAgFcDF0$1|Z5Y8˱-'!zR\$0u<zKHⲜH/Z20e.$KhWO ܓEl뚴moFL6lvҮc0˱E=x\O&HkZ-#K.{BȈUS4飳n-KʨD#È8d{2~ٽǬ _`!ZSgCw:25ǻxbH$=G*@XK_}R)TBIHm"(E`¢6R疁 cC]ׁGAgpM > ~A$φֶb~"I7)O5_!ub&@bI$n伤MK.oqM$ L@ ӡH#ELǃ^ER%tlXj%0%%SN'8 L2 zx \$(7-Y]\(`uޘӂnk[ѡJ}Axa/ʜ/о2"0,Sۛ3j 1-Bl2`dBBu(G-IK,Da{m ωKr,]kwsiC%ssv?iэެAז' iZY"& .:IGi '}PլVKv%I3P\Z(9 )>kH)lcU m⼋Fo{R*PQ$穗+\Z͌;)Bڊɀ/TZpR a,si_(0偛P3}5/-v6<].BLAt3˯h+$U-@Q2 %%+$@H),0A[X"THv@*܀PtA`G ^# ;qUŹB>HA@ q^RڇByJW[zƲ_u7 B X PlQ 'oQ`.k k(N*@1P\BRmSR1B:I`5rj.j z$d5 hDw2+]>:6]l(g{1ҟA|k+^)'hpp7QcUxwN \ lDt钂q|5JP`i\Ⅽ0 /z&c. V aU\-oVSؾѡǢq>'\N2_PQ)t 9n/8)􂈥<\=[ ,R5agviD?h$qT\9U-,,"DqzdJ.Y*q U^RUEUDoeRO",Tx"l(y꧞}B`VZ e)ܭ-ڔFa,s^%ms@/xo0_ "hqQe~x/Xf[Q]imns <}ڵI4 |#G-] W q@>m-^-B5iJKe~>mѷF&zw ✲l,!jIB<^FAS»BT46Hu *Ivm}d;%i{ҊB%o^#IcB9JJ\bFB(l~Ց"ٲHV`bK:ee8Y'A"8z/߀gР@=UU)qP nr\u p!ŧtTAGXT F,nw /_)꺖+rGzc(F a1(ǵjS{pFFBs3?` $2Ģo,ַ߮Afchن.~FL*yLxSu8cQyȆ.JH`2p#/* lm y~\IZ{oO;sׁHYdT&n 1 ]$#z~ LpaA^;Ld:@̱k6NE_D7]j9u?sI.l\*١1 PɾIdHd9y1 ' ުvb mV"~ pЂYl@#QYV%DHhRP"表Z5 Eul c:Me"]!0US#@<1fэ-\.\DX9zm_WC |HHvƣ E T,(q,j7j 's윭L8r gM^+m둍v[۷qM8ٛ4 T6F m)iH([phu˯z0;LexHXSv0 A&4s.J Jjz$m  EkJ"[DiՒZ11 HRxQ\z-SA\D4*?&E3+2s9?`+:h[7# J}H57M+M|_9cKb$[$/sš[&⋺d!,E(3N۞ZA_@o+N0@<\f)uE˨JBF &^+PQVlyŋWfaa wκ$|b93zl%6.*)+tww> 45xͷ35ʎ'8^)h1 @/1-}"๷hv[` ̲4$@!8@S#Iv>J%ҁFqQ$ D@\sㆆ(+R~pSI5#ҥK.>fysf\+]:|pùt&Wiδ5Z{%Ù͵R7q eyQ%u@-!E( NIgrm 3u& j6KNF4fN Ƭ&Cx߰>T!wWjf~~m5Ϗ b _IjAKb|Z7,/mT#k4+BWa*_R5[:ي0*`O* 8YOU(1n;4Xdٍ&| *<@m3XR$TDWۜUfWW~P򀌤B$*  0M 2x\P,d5k6;բOeeDXJ˳1:H͹X m%]so㐙oPmck#tػXƨ>IEҌ}آ!/yh8T>3q ?Áe׃91S?ڂǕZwEsq,O.qOᕠV^3 wy\C4@ub8bQ `EC ĸ  w֤H*2ta>I:}ZP_.f\-ѿ#-Fi~\TXR!4W߱;k*'IjBDX ~ T&C} w s/EOҐRh.#K ƑtEYߜ8S?\8qU4m 痲FK uq0NYHҔO+!I7z1§ '}p Á &dx_b |mB'ϝc5u,c$ ~EkyDe1@0 T8 @QQ* :Iaں2j7+CŔ]Ȳ|?k;Zop{')?ʫ!U :UKa ܢxsyh!t>5wyumWX93J@֋i!q8 Tphgyl4,F"JOYKXtb al1t]0?'Z#{W.Qޒ1I#Ix#cB@ )tP㙰a >{F QH ީD8p|8z9Dj ?8~gڸ0d6U2T@."&g!dsLA_U 'xsiٝ^:w.?swųSxwI¨NJ;+/zQ]q%uTaYGU笧;wlϮǗw pNX~@ X{O8Wν|+ۋ܏yW^pkh! $(ˤ.<|-E{A-ng =q½jqi9@| K^?#܀g?EPyuUGqMї$l <{F>* ú,BA* BOJ ̖!<};"DYyY\]cץ;w \'.9(؞}H -CrK:I;w_"& YqR17N݋lvzqvù~=q:|e}(܂Zrp0WGH$KJ2`- jަ9LoR~Iq R/O$fx ,D@(:#LoV OXZ`p*뼨bAEIUy,=܃kq]Ty z5¬D`ʲ,&wDl'yG*(AWBG]e L@M壯J!|D !VuVר*Ymdݵ8e!3mRgnR׶L6 (#2ϊw"\?#4Q mKy]?k_CG{0V <{Z p,˼S=A%^* b:@'c73gۊE/4Jj1F2L[H!F _'->H `ms;RIBHF9"ɳ8]-yɆ? ƝK.K4JFTUQlzC)-.]tW*A,kՎ hĪ`x?W#-~S  V;8 G}b `9<3Ri4@ ^"raznG0>Z>plKRq1  =]:5dos8%"'v)%Rx*q\UEx6@b^w  #" Mvۿ`SIq{\7]m_I@4X&!Sm8xJȳ FO F+*5O=0ЛC0zuf's_C] Ϟqo$8]k;헼.5L-SB_׉S *ZX'c2B.kta3%6/AbE= Ro. iZqRxq?;v*uZCYJiY "ip* ]޶o6P|[<HDi5XV.ƒ؏6&uJBG~K[aE(֪̓˾kԌyLm|r&@=/* !nH _kӆ9CaJZoiyRI&23I]m(c$=y^m%B=U5h]ܘ;mR.y#Ih =0k ^81 r^r`oLHhޡ1k1MJ#Wah!:*peQY`"K|z8 Y}  oFe5,+v !h^5:`תb=^jm،)³S+$I\ Jtuƭk=u0Wóh 0/!$1hW A~3]_B@V@$-Nhho}سBNH4[n6*0Bed㹨Mb9'L":ޚEn6DuQfD"B6.l> K&?eeU {"Frª3 }\# 76( _(tRT +U:" ¯kKY!W( UG9ȥK69LV$>1̌hDP!1B],ђzo_ vœa+]9zv8 ПsX-~^2챡tly]Kä?DJ=!K~kT56KD +壵Z脐$Ķ6*EKt a%&a]^{{[?eDWy3_-R͛yF5|CKw&m$#`k@1E< $E{ tD AXaT)ԏWcnRd1$kO=\YUUy5FKkPS" QQDrFC߲$I$cwleTX)a[:*`nyT-sZ,ْ0#ApRO*E4#h, ܲ:ړ䓽J1E=ێjstm?A#P-H`wn)&dV\<+(\{R1VW^jΣQ6H(H?Bpπ4yՠDT^ࢌ2x5Q%u3Fk Y >'Ǘ w$w.}])DAxs⏩ -IݧFJY]Di4 RƱ ;"O~2!kDhWsF x$mvx~з*RQل G݊$ܧKƋ@!p4hƫ+K @Ee|Te\%.F<"LDv ,c!|@Y2Q/nS[b'!x aU9&AX/)nC!@"K΢QǶ;m(>^6[ 8GS!8gJk+Yʺcq1/1n|^_OxaPάavkeHH8*6G--Od M* 5&Y8*&$L郤Lc/٦ VUQ2V c³u9 3Me9܋s~vT@ΡI3 X8$I8:qƲSy,8IHt!< >߬QKU!5h=TICurO=}Seۘ>sFmX.Upٮn c@?S,ȴ ,˭ a̔i4fmE$>ά%8FlT^l17v75dpд l2Z^U` J oE +mLO >f<3PS u f[nMKRe" 객d.td`A6ow" `7EKb_̮#;e=j̭vQt=Cm\ *io[嘥<Ǎ8iipݴ[jքl.{>kkE|%-$K@<#'8+0 hRAJ+t$X< ur/!UUivJ Q|w<#T8\1]rkH8In]s}jJ!׏c^gJ}*$1".310%-M]MdNc4D@WR xTUCiA߄ J{"u=x+p䠓!od ;|U}@;%*he3@ITT Ͳ٢6Ha:Xraf!'/Eϋ\:;e"P!>T/p"M:߯;U:%PE p?miK39#xmN!`ŒW ʊ KXndDWi!V )4#F5  d:SB,L$DyƊ"Z[CpaB-˃9pH|ǚ_*W"YQPt( _dlͬ\] aFN AlD ukOTIRH %UiT4 AH|5 qՓE&@m {!{x98y]|}'.fRgc#4kEF-,{o3ev,[3??ՙc2ަsH}<{o>9>FE]f5d#su A98rTE^t% Ӻdst<# *j= i0i̝`SORKN> E JIޚg! "55Y/͑AsH,-6N0TNլD~ڢz*:'H:OWm*T* @{4SmCnJ:8,1,|H/Q mh%NJw܆8db,D`-G+zME;. -:I@Oﷴ@#eITE:^_Xm \m66l"kqECʌ{)"yx: U h/e]]0;}u/S|6D7 >'E!Vg)xDUl&xomXY _Un=dQrxkԳgl8.>lvʵD >4QIVWQ&V){j={*("OM՟_S .թ2x;^OV`xlm8;U&$b=tiQ'u|Dh# \H1~CN6 נ?iZc64,,˷WeD_k 0/5MiѶ*^; e5zD <_bSBV@9Ȟ-Tp0| e G{:,ugkRJLv/=Ev9g>=vݶY"n>z vEu)I=^z&/$ {)ki\Of<\K3QX}=1̆!iH($(sbj*$^h '5v:*%n8+Z {qigtT%+~BlE˛3qMGu&5urRd$rrNES_5_BmUO.b.KۏVvkh@{̕FO*(IA.kUS_M':JԱ%>2\6RWB/Zgߡs@@dy Ӗ騀; 3p:=Z-a+ $ W$ڃM:`uU&V)Y/}~&oyěMڟ!X%6V˫*A892 K\kg5o6<%`N$DZֱR A,E[$k-r3 o1XF'B9{eLJ#\džφ?<4#7/Wuv["0ytZ_]#|X痨pM=7,1$꧆lXp,5ɛ`!NN&Υbq)xtx3o=0K&h |P7C̎Da2MP'VC|ܳ\饩/y>6 LNOf8S»6B;_2: pj%*LXl |TؕTI{x␕6`+/ibMҼ8+{ӣYEj6bm& Ӟ~.+3#4 Ƥya/L^ܡx$`" pNl]KAej!$uy,*i|;: <{YTjV-cY7&`ؙ:<0jQH³ed9РU!^d.z0}Mk:q6'"`h[`2ߵ3͛aجf.*0 nTF/?M| gyh.ґ`^4q6Ih$%*; \sБsdYO p( #0̃C ̛o[aLxY^2-Cg'&Y''e5-JX kWh o1lko%fJwtvv^jl-Ԯkv%Os׷lz1m6F _.P_Y <'v^8U:`9:+TI`xb?S|fc ޲-!6Jxi „,,Ffwwf}E:؈~momF5͛H_D9y:9s,3J6mFB)}K a}v RnrN8P#. 5]*ULG6~4#EXLHir24d_ wnK'pH$nsvvO=܃ ݨh4G 6oTVa3+8Eo[g,|PT# 4w%[˽QqΓ4ۊ8yPA+΢"*˸a.<|:#maaW3t×c,ʴ 8ɀaT.@y]C ਘfz'WXxUO@梞;]MS ͺ(ڑ4"ig*;>;۹ efwG)8[؆I4k*pҤ8G /Le8yO'XmZK#b1|od"\N-{GKmеCb`60JF$?~(?C<.Zۈܴ(a5 $47$a?t_ɗSP3 !Μs~cLsf7Ab7+_()C63*MM{98jDY]lFϊwI.؁g/׮$y*KLd;ǻ.^ Ƣ7>Qq.Hm$g~W~^:gN'HeIÓ=J(3Ca\)N'YT[d3$˦$M #;n!9hpڣa"ⷢ"A㪡j`Y c$e.% yc#}ը"ISFFR9 #F[ U g 3+,i4QّxZO !ڔD/ozĽٹsQFvsQQhPF'i!C|[GĴ(Xd|uMŅ3@=T.x 75*|";Al;W!uKpoMY3i a!f 'qͻn,>4f ުn֨?FaѲ6Rm*;IYu7Y A\gCmƢp__VA^<:>CA%a+ǒhѐ9s$tBS)$1q0RD *Ols`lu |U`WBVA`vJ]F0BfDlvoʭч{VysUa&a2xG}י٭3kRYE]=0F_'l|%A?Q_#&Π0yK]LƌM_< ɉ+ }`aبJC[y];ZY<H`]UFixUk y*ZN=ɂZfQ*{%`w-΁Yl tZuľ ̩:齒A)NʗEVUV VC0W;SVP')@ZUa ]żcND wFS>E:XYnf)lLEQeH 67,k*v!:{y, jI ֋?r_BC2}ydYyctu=/(i+ ˌ0q10e{ta0c Ć1-KD 0c$("Y ,BB٠{sVqjr?oݫ_ﺴG'؋&|O{h;UgUUT%|[{{tߛn<9]=Ogs8_K&@Gw߹Sߵ;z,{6w@<{Bƫ8JtUiXl|R6`g8JWI>=4(LH#A/yL ? 0]:*LdUQCP:0tIC$* =4JxU@#|YRH=;op.b72 oK5|D**Dȹ4+fGEAO6dBxϰBBzS[-$6&sc9aUT, D6Mu2.|(h8. _glZqJ4krg# ܳAUY*lDLgM% 08 齍Bj- sR#|0iC[֜W=Z:xA$T$Upi}_P<ױ/bٔºr`_1,0ѮVyTDO>2])UZ)B^ 4lq8G]L3Qux8-"xZ]@UVI){Ô3gI.~F]D1:HEܔQ!}hO#} N{0KUY&uqa['B* 5#}P77TqsU(w|zr4+]kaCMAXguXq1vd`_jlsT*΋:TPD>|Œrc:\xa`1H(g?(#=y9|,#%BJѬe=<%1 ђ8߅b#PA .!e v*WYbh QKo7Ư=5$h ^$c&,r*8թGiHig;@v| KہNsZQfQ3fol@A F-x5Ow6BY~6Ω. sz=rb|X`O}[_'!ҁp @{;COip8ܧ!=$jҌ4, &>3S8WUs]2xyQK3%<} TG:I=J:$=Q$G%Iw\QC'^0r*ܴnըk-i4Vz`^WGRV+4+ bGFWMhpQJ+)To>N.@d2*\m aI_ VZa)ϩ`Ou>*Qgm3.>Zr5* :R=$].Y7D!b=wP ˂@0nx.AГlkjCKk/a- ST* S :5/:1=t h ϦۮC,bom-OHSG$؈rOe?kR?p0j0YeE"mShPxjͦ[}б\׵5($`j\a,Q"@f]c!OsQ7k*W;N&RR#l$`]''JyS<47DSFkZXDSAvA|mw׬M 2v-94<^R#{׽I:D QnQ$.T\޴O tˮmܦGj1L?p\E"5Me2¬iD!F'{?J} ޿s%1rȡG}K`\I:%j2DeGI@@9'&/P5uܱ=CN:rRJ<ޅ,#XKf&Q["s$DHE&X =, p'TdLJ 'B?W3 Y*f5 Ǟk'PvN랽]вN:Qbi y0" #mjK>VYQZC^R#%t}&X&}NbiZ3xpSVU/tw-Abw dދ42u$OxkNUg,Gc2 >//iB << T4!0|ZX.|;`A6e ~`X$&zz4'ϖ ?,BD|jGE%=*=]14(ǝ)e >wk9gࡍi_IMKhD2p۴)q6_Ao[{4`+S*.</L0)墦egQk7e4REو(w1̍ |AA}6jGh EdXp%r|}* )TysYnIG;\xޭY~0q ̉82!u*CKUYi߼uY7 C=E 5-+ҌweqN6_}h36vxv-lBS|A@`3Yj¶UePG% Ո4K1־VsϚ&Q&oWD* 1søv pR]pK/ce8Or.;]:8A5ˣ /7?Tُj%l [%cJmW!Gh٢ ;^Rl/ /[Kg{_g.̘Pၟj2bC!{3#(p_{F*ϛ2V3GEA0͖!в "A ՂU#֞hW#~Qhy F-ۛW9?>|/* wJv燾q`ƹs>1ƅ 73mpi)='i+Jȝ{s]ts9,7fsmΥpߨM4x<%mY.͐a"6U/oy$ENcm$ǩ޴rNGVIJbH7 U oԥzr0*B#b"H1$*ԶޭV"M#528Gh&`-s~I)ӒMV䢒YMS.]K>h,-b\_bN N46DMB-ymo¿WPAS mZJbCE~U;xT='ӄ#Pa֋&yWQR||ot[wp%!8G؆ *"̚ nN_|BVqN=-.]nirEG#cߔB2>2D ~^# -õY)Bf :@cR)ԑJ{3ǩz xD*K!p. PnL\EhS~i k |BnX^Flz_^ZB-Eb<`݂v =u6|Ew/.|B&,9z)FϢq'9TNnkF?N)cMI,*,@#D " lɓ e &D{E-s_8.qrLBl'p=T"|]a4#0c͜U48M>^'ky]N+Z&$zVgA1gוZ*FvHmӦ[+,[ךh"8~yu"lGeQW| P3g#.%$I 4XꈁFuH!De#>ُ"=ާ0GPF1>8'" 0?†A\#ū JGYઈ]E|QУ2\:-:(WqNZK~C! Vi'i€h&ZFA?Gcgxd<5Fy낱4 K_)@r/2X[~7?Vȱ9-rnD@/ ƣ>*k'.3+i-JH$y7xoӥqĢ`,">}p|ꘝ@ v=Zy=l\iƗIh>kYlmx6P7)9D; GqVѷ$sFNdY‡,Tf8kʛs?qX:u*|XXekr&:~2B)(xc'>w1RlͶ>umshGr  #Rxx}#+TfZ֊Z!0 *7>%VMKᣖEV)ȉD蠠ێ "|W"XUFŮ,$W[Ip,,655eaGuE'^q=lvو>7"S'n( 3Ke.Ohf>n{0w?7y- 1lcck4oОUu"bׁΙ@;eh#.qpIG[%PC^Sqln(6: `a+h0j6Iܨ#QP'['כ^< IRʬ9Môf]̀;p0}ݺX|-~I{AVeJʌu,Bh`S <>E`}$ oa-pv~PfDyBNguԥqpf^S,&9X)t DvrnX^ҜN]/QQ"`%ˇ4s &N_0OM-1!`s-L"/%D5)ؗt\LhkR_"v-{M?_/)|D#ջqgU.v;0tkwﶇRŽDUhߚ tuT@F *"E9 j^N9(rZF-rY($aQҀnA> ȟJ3Ρ"IP7 :!AE B'͌pM31DaUn+k`Rv/BLfiP[ZȢU#y#gG8* lvZxU΂^f\! +l |S" VRgAj9YV[mD%<{ۘ0aV3S-W3o5!ε[r9+u*U&`[߀oM.EDg~|$\HާSG,Vm5E.,T4ޗ/]`2`j?>yԟΔ *yJ^ESwA6  eAK HQntQ"N;(,\ <}ա\-w-۵\GGõ#"\1׌T1oW1#=2@~Ce{qjSKSW$\ӄY!A2cy.gPb^^1m8'-xeO) Y#h[&-Z)qi (i ׆,كZ934[R&ЀvEH asS<*[ ӴŭفgZ/ o].=5W^U9F- i ii.?M*LW <{HE,낋A-c} ssN L0Z~`x o/ ~t94>x-_uAGUHB[`f&,G|3`^S GHB <6G;[3kCƢ"קݔ2 }c\!"AAϯGD5x) |Hwo37"46M `@ԗ‰.Vf XGHqzyGQ,'KROsb]O!s@IN{aIWtJ,܀ܡ5WrXR6oLK3q`x.o.%3<P%y zop.P 9h[\icT_xZk Dn9V_3N}Xf7f{4͚%Hgk[":pUb*[ffWFfN;$l!i 6iӦ ˿%WR~3fn);#ْ"r]>z*k ٍO6knKKgEih$l P"lOQHvРsr4 -1Tɲ"( t$㬊<[EZq7[!}i_xG&<׬b``LK̼f hlpUN#@[(ZZxpYRcT]k >z$\lmgS#C_02j-d@eyuD`aT* l;Q7~!ASZ}WuJ-xղAX޶*'$ǺF8Ubi>!\TaWaM}T(#p5NI8۸)[*_z }Kpo#2<-gB,TN3AOpd\&l)l!<4A%%Jf2Hm!|}ll[[ 2=[YX'^aʅ5ul:I$K=Gb&VuRr@1Ebe$ZwHqB%3[BR߶]r̷ؑ|I-xv$QءrYV`&Eu5`:#g0'Ц7[4sJE-=X鎲B r~XZ_ۏ+w"w{_&T!88qwc a-oy3.^vmE"/t ,TYNlb=8BrEǢvͮ5=A0ԧHhO})! ڵaO=] ?` m~I%}=ZRT\$*w>i/o*2EY8>éO6+2bPF۬ z9;#rAG!_⢙w8 xM{ʌ5CLdlRQ{2B#i NL~@&ʋ!T%,e_FR nFۜ[7*~vT%6g4"1ÎL wbYG`mv`5Lq] Zi-Q"0n;w 8yq~g+p2x:p*Lp_˵ u}7F{DO߈ ߹3`m*ս#[Ug^wARan]\G:'[XEyd.>ց0\F+`GRu/Jh'BFHU*.:]Pg$(HbW uw3Fj濐 < Rk^FUol ~+m]6:ݨ r`.&cF"{&5Tɞ+Y]J^U hjB <'g[^E 9My{}jUx#h!)XU+ ,]gf00&v m=\i}8UeDHXBbm!="j֭b( rp mŢSo|GAbCkۮc鐂 CP;rBޒEMOꬎR  fzPbqݢ2bL3{>_6( ha2[ Z,@!?f}… I4VI$Ay#:fRlR`? Vܘ >1klpJѣ-1|c !0z_ʤSg8;HkLH(BB!}?}銝j(͒?z9|=櫴t8>T3#4݈p/J,zW"Rv΀³ghlPY$"Tx,7K<=AWb2[ Dt-*;SC³wjH*( U5^q96()[eVBC 1}{-Wy R|ij {gyY iޯctZ2T@IڐB#Rs4yiy`*  WRUGUDj}k)&g j>CCP"Pi'> B:JbfQ] )=( <#BPjXsŇB_lQ|5 $aiq(Q QxOw+HFӓ0.$K*E[Ku Q Ż5."QDeiWA` YpEv:%^* ɏ9 (R|"Mv|" P^w/^)"H4Z3a6J?5 ;ȫ\:?av$e%q4DEo@g[ yQIq$4-Ҁ3_t>:ܵEFxQd %;Ĉ"OB\&4u:vR +/4 Dp=RޫH2RcPqn`QQlbGPףBF{"iSP?PdAaX NURQ1k@QbXp!XtϡH-|?D) S3Qp^F&z|-:ߕ(A$@N`qv|fwZ6*4h5/"*Iqv%["X 0R)x!6<{-|eE!Xȗ~YСHEL$'t(ZbyEPf+X oC$#/HЀkrm`c-Ai<8^ ) xtYh0̲,*hՇ5Ut *xM{\ SjQb2I Zj.K(GGyF0B a$E|EC2V(0FXJTFҠ4x =P³7 /SQ2FRۋd8"D|IE%8~&i\&Qh{…4s,Ew}* om>T  qԤ,Nߛ@Uڽ%*tk(1tQ[CUS"A'*C!X % QA`0XviQf9o^y|[{\V$%AA(",q^BHՙI=@|X2CBCeqO:8m\.l]q2P5ydfvrVQOBQBԢ0+m;W/ljV<L6yZn֮crGP쒢/h" ui4B K!? ry—x{lm26&3@`*u~kk'{E bPTPy (~"fQy#AA@M V/Aao0gnlԮpeLBh1*Iٶ,SQAI,./D$*1O,RXcg LV\m{6syeLx+ Bkw>ytoi{ƈ~@vhl9o=[P-@UbfJH,-s? v:q8@l1 %A]J#n)^X6Q22]$%RƂ蜭@DY^YQ U'vż< i%:on'b_;U)ŠL+;_ƩjB,.H2? T Vhsl  ^g2Btۢn9۞uVfsc#JU8 Uq %kqEY umɿHhV.A|"A㨐6M Wfo: nziVlQHԲALD1{v/ƩA~YY:J odT{pL[Q_Z8lWx(TP"(kb4>Ԡ hQ< PDI ( dRx'GXT%$i,5PqF,$܋yA.3G[i9@# -|HQ+(xa У<uQPw-l:; (Bw@:C.xWzCڋF,hw̃DiNaCgbJ1^pz9"mE%E[xDa8Y]q(HM`jQTD9? I=%'OVQڞ96І>mcy"+ٓ DE%e2) zOY>Jqt'M jS \3tZ'a`?U0Oa \54J:d;$Q|Ip*]R<3xZ%+}Cǁ(iI» A񈦋HU3DE˱<]SP Q~`(UUwGu(d(TTȢL]:\a{M;pln:rq {מҋ|$R52NRpl[$LeBb10$b3Th؀7v$3Ùd_ճT$!VMҴb Z #G$OTC8>$ ifN7 7]990jEyM#1^(E\%_ T\zD9yE-TDwqYJ b=#j5g$|n ^ L0(F4O 6@,xD*0°(B ~xT_P4b\C;3íðض^9MuD >xHB!vy`Jtm7a@X!HĪB-/}H4G0&β`@8'6+.5=ħ; n`*wJ؟HR$Nt v3TMQcqBՠ.imlғ8"1d${1 Ȯv8.t #0`:$ /G< ItTo:f#OPn|L\%:r }'jZp>5?}YA J&ށ3Lj5E^ wX剫0lGCኌ,Kڵ߆h5k #vW)`E`}9ٺ'ĺ_=:Tx(M!h%gzUTl{., ʓS% v^T'W"ьA' >IkF!ve#PCMDF$#k 8F@VO9|0\u;0LOt;Ƥ<{TL `]"GZ<6rkeِݰZV I(0WEˑ>xMa!yTIkgj,$#}PSY73 RB tm68nS>[k2"~s(1u0!/$6r^7hm\Z#߿ |`X]D$ BޖIW@ςPO6Spd>!`5Lh 9YJ?WJϢJxڇP̂iUŝ zec\1$1]ck@d}q@4m3i%.Cikߧ!~7Цy?,>)ͻYhAyk,<ҁE#[<<"LdWc٘`eYgYA.w8 E/Z[ sazUKk"|U_DԪы%☀hh\&D c7[`pq:>/cq\"|U!Ѱ<K?i`0&SJZda~t!UBh2@`պ 8vo…c֛'sSa߼Mp~wqo0wj Yԇs&ӡպ&f+կ*L:y"Lގg1BvҠ<$ ~e%AfԀв :l1/`!,˼|iolX]X,:^ֆ[soQ1]5 7bnuԁp7ǥ_DZ\Y""ܬ<ź% ڋUR cvpO%0HiErR#97伪- l!sU\ezʽzuR##AP-V d]K868fw퉸t1 ʕ FlbF %;AA'Y]ɧ:W!rN|\˔ Z7bj]\ÒB ז!l. xhy@̆Gck*t4Z/Cq/t^m9o;.”n.75F-Jjsi}{-^1lxJ6Ʀ0$B_mu^σ۱<3dd ]۵ 3Y"Vcbc lvVEgSȼjD'Uo!]>-:^W gEq0)4:Z3B9M;7q&}өڲ?n[{9rOeyҦE.<%I |KA4k6bR\EaPobW5sڍ5gB72[džal]&zs[JEy ^vnC&[ /eBABy@`  >&[c&!BD!nx:کTyOSabΖI#pMݣBgc'TŒ TYX qL#kyx -쟏\QNqnbЀנdsWh|1" 2xLͅx0i٨柑&!~1F, u ^y&| M w0H q̅+z=3j! uޡWC~spp/OX,БP/BfqwD=HRBkoJ'Dւ@A]㰚{^\Cfp-*(0'Q*3/:ISTPsmw4`0TeuD fz^bBurL\BE, @4 %9iS =fCK ujJP$ZdTY'KLe=6p:%y;T)2p6剼sm`֭wa-N%-0/22Pخ,^6Ujc'[!ݣy63ܶb}p7f.bS] 8w2_3\xc{sZM0`.|n@sF_A3KX 3:O8U*; C":~\m"hY<%ڢ, &zA8QrQc>T@j>H0<׈ȸ2 FZ|eyKyN#m{{H`ܹQc-:q0^n[_xsyp^=EfxL0Ey46M AzhFQj%X9x!AZE[{kUokkreAKm$ :搣=/TӲQKw-K! j9|DF6AFw?CBrI=$P=>c#-@K5i@i#LZjaS5F== 1*t: <#`^p jyGQ$#,6cTWHT5A}NwfZkd~WP, ܗ֦KQ~OaU)ri 8Ɂ Y#; d᱾|{QGÔ(h*hq5r6Fn<])OƀL8rmӼr930ka>~ 9qA-sQv|dN$ ^+Q*5G|tZ>!9pwv_91mט-bBqc!ZJ)!Ɓs,1($zG:/WLhe8 |GqmX ,kcѯ-}\̛"q^# ~u4dhC)"ƂS8n"쟬ДAEA,3WHw4f4]j1E=UҌv4끧*ʮ'-KGadaQAVoC LlҴ=M9ܱ= ,v!a7Ƒ㽔x\_FzAANOЗܾp~"aDUg.{<6~*rw,XU]ba#v7ݬPF Qc0QE:jS=|rgBTuXgflw\i"^r^.Z3e'N$)0YYa?D.sIkF@ LD+G;#t,>@EQa&O~DTx=@diG#㢌XWYP]p1AQ-m;|UҌHǨЕ<] B }MDNS۹tG*x^wHP P{Y{+FxC5k-5 1l@GxLLUj$-̵Q̄J (S tjq-^ݩIgATOL hOz Lb񼫮4LV. vX8a[ ۼlA_K"H7%F@^-XϡL>k珨'Cգ185fuŝfé9(9w]8(|=B5BڼqW[ ?[AleU8 "pj ׫ -OlK8}%Qj8LQ N6Hڙ0p0H3{;9mmN_}:",aoWL.}PfQV-,tCApI! /YWPV,*6l5n\1S^DsTyjxE.2y]`V^]5*ᓹlT$}POjZ⾫,j![O~Fw"ԷĤ~1ۀ8{@"h1$E щ̮VΟQ!IۚN(6AV-vaڍh> AFOS dEdwNL;7΁&ڜiq=@IeZ2杭,.H}*cMd&س2KOE mi[w\YpYA ?bLH^א5]twi 6P' @xAU}H+-@F^/TWt\\:3n&A 0*F;6X%6N.ٕA~HQj0E\6U:7*{9<4 %"Tj/ \6 ° jedi?E2}S%tyC6YX "e)pQ+A dk'fPpy~ gp"X+Y- {8ji2<(QҫXY C211JX6 OW7ffk-:*9Z52M3P}X Zk6d ዏI@Rp1M; Ë*xbG7T/"ek%^΃T3 ##,nwPDQG/49 "`GfDÚ=oL揜Y̭c&l:!PTgtD r%e &V/.ѢȟBZWztxj\C@Bo5P!_Y8bN)5ӫG$ʡ( c6!OeٰEUs-=8 'r9kaBo.o[ ) ` tY 5 B3uKfa?ZgA{ D)_7IՃD!R3 F9KPka xċ W ?K6ͪ[s-ӳ P3BUgbX>a^Fʛ$uN `/@m$u7k^:\}aȼt"48D#XVmnVyI{VJ!}m\uWO}̨_z@Ps_ Q3:+ή-mcrטeql@3ᦨsj8 Ә g^?`pDD0Da?`خW%_+c4 6[d5`xwL .7fDV It'`AyQ'z:*h~ԩ!z_41 ܗsBA"Sq4âFJ2 ^؋ @J0 E(60Ż :Bd$i\yVߢXSⱶk `+lA4y zQ(/j:gm{@M{uG+ i.H/oP-ԫ?g*|}H!7x"a{;pt(*gh'eDPFm"5cg*~6GiA4am>6Fx+GO66X.oZF5Z&9E5]$5!Y89][<=kĻW~R572WZmSzFQ,~ML# C2 OPg5t\|ە+6WakmY|lv˱q|~(|昸[/D)3Hv }c'O{E6A̯;ox =(1ig!T\Vh&^h~r.)Qϕm5SEg{"=7iR >I(У8#x{qƉfvxDŽU!A(MGSeڐm#q'U aQQGz߶=Ou ~- ;\ h}6ۍ͚kenL2tˆa0 M6_EҭBPaMY^a㒡DG GFEe__)FJ_32 !BC 2}k$W}EgHsYLOwɗUIٳ] VR6FBeappLkXN P1'NH vʐ*W!|vH0r #y3W{c9sƋwu/>?{0+(-.$\|+|?)|/"#?[>ouc3^?&Ǔɥʅ9i:u?YYw6 ?Ls1_l^{KmvsK]zUw{Oj <VA_EI(pC]5[;Z6W}Cx^ B_BXP^ (+'fOA 0B<_w³_ aƽ0&+1=O_q]mR!𫃜E,#DPZ7 i}/"dK Nim;"@\ Bq.ɚc7%…gB8 Gv)7w<gR(AZ~mFyc~`+c/Os6;O/3{9gf:=A΁8W!Ax1H$tQIV!9(4̣"(TPdv g0\h?Z~1(CpWZOPFFk$ᒄ gJJG%"ˋ AP 3X-.kC5EZM@^*\{)ϗ: EiGZ-6o_]IL幋` <`8MA]#\6PR8~T" _IxV" E-T`U%5I66o6 By^e5ޏ%~Z]n^fE~Z ۯ$925bp,HkMu]; F}/Ai! 1/J"iޮ69΃"M<\ԝTz~$AF`g9lDh"BBEeqj{=T T\Xaq"Œ%I -1vҨ2>AFeN|qܧ8s}VGҤap#Ÿ~\!q p3NӨ490A??К5tbx NvF8hL!neY@RmhGPƙTḧ́A\Q۬]QW#YXD^0*(<-V+*`:IGeI@d h'B —DsABة ӠJ#R}>4ΙW^dM~T0풘)xt1sKM3'.ˁ4刷v1DgݥMP鸆+4u2)HyE^G`=hco) E 1q!蓄b!d@ㇹAûs˟nw`*[`ep"y! C!44cd¿ڤ_UAF?uG1zxgZ߱>[.Q-{9mcL52I i;Ce=D(9'w'I4pJ*Ed4jA3oxi'aEmxD/"V岬FS9]S{>_|pzdn!aύy/o Tlz*̩V-xȬ0$l' :G ?B/m\z'a~Df3qGzj9$Œ=B /Ldy:N4!ZO^D0L==[Z#k4iYkxwIJ" ޥr-hI/!O㌻w?6EXQKH[Wd[Ady .yx1`Dq`׆C s`µ=,cc5?N" Gc-wwIx>YX iG^w-@7ɪ\B7jD!8<# MZDpe`$.͏ " kn8ssyk@oCcĵ+۲mLpU/(?QGXc2/&h _*+66g!CGe#(!^ e!-<\!m/M}52!Ί(o4ZBCCmO  :c$F r>6Q%+Urea&/4Mx*u:|C08OҧO 7h3G  xA]M4K!nZ){U+^+j '}7B!O/ 3RTO7pk$6nocYP$XnL&+mqv? {_m"FB@@!`OF"X?7Y ;*"45m&6a&2DV %ĕj|G2 ^ғG//C hXI)eD,۱RHSylTQ3!0ϣ$)4K"!@ӚS֬Eu _ՑOõ( "O6Bl_g-T2R^NG @%A^ ԥy,Ÿhj&Ds$X'20ΙBB? +!;^^'1?ϮkD!ef0 0iuyC$kl@zn4\"^G > iBaēgDnN.R[q߭=I3! cT4 ,M粖`Fg$<A^a`0GH`ȈB5 /˭ 6zAz(az!،0uI$B ?hQ/#p j$M0_8YC!QuŒ#m!K˖ADh nDhvΰQO"b^šԉ/C@tGv * FhyiW!tLԜG/h l`$G8”RyNe9HTBHO|<}?@`]"!ŷE:y fJuuUV3^0\H|!4Jtޅp]Da4/ 4&.XO +u+lnkdаְLTDhdہJJm(K19i>:TmĸHikM"t"dhxvh0}H#ѝ=@U \T#ia?C0rЬt+6)DYI!T"!\X:Qc;UgYk> uZÌ# t R#˰EBF̀0*8f(&#³_Y58ͷlln'ѧZIay>HxsylG]"4 AQX"̽H`M[mޢ;}-lXݑI.@xv^%zS`jretlHa3* Rc9rp,Z%+Pa`;,_1 t%~_X"2O3lE"faj KQTk(@+h QY;4퇰^7X:J4p&{ѽjuJp.(⑎¢ջ4a$#]4c.sm` !!|D aX6g%\>Da؂N󑌍pj@66UڊPދk׿ڿ`L-6Ŷ!FsnY0^N_IL>6VFy{9w;ϡϔ~2 NԘ[ L0*baq-c3+\ f[ .YQ!=ʘ 84~B`1an15jĴ=[8Ktlq,& n?h`.b CCÊ.׍ Or~N-̃ӓҲo>8|s j^DwƿwL28p4BKT> |K\"M{[\*cAP`-@ JҬHP@ Ghv$?q1}1kM9_,wK n!4ce0q"Ljc "eH8棇$K^G1v{y2A;\mZ58>ºG֗$M"t>j0S a@$yZnD鏢-^YEHU&pm }$^6kϪ ג p7z"%ZRSwPˊ%N&O3rYqT@"ANEqV/S^%B +b̒XH+3HX0 DӲjڧU? Z>c܍Fl! Mc#2Ԑ_JT!`qX6BI<ұba,5q>M YC ^n{ cz.W}-c!|X i|#?|qTP'eBGc5mQ@Fm #m AD#4]5cݞ7H9IE!Rܡbs ٬-Yk ؃iD1r c coӦ+ia}xA4c#)m}|dp"NٞV+"h{zľ50 +:uL%EIi*$ :J(r9-iz~룊UyW F#˴efd~@}e 1͸lmqu}e rlB{Mt1s r_~ hZ&jWceo Uc!|Db6o?E7椪\CΎA]Z*"b~y69)Q|j#"A@Lj[C~*gx1!â 25N4^ C y>nJB~|v'魫TͶ{v5B|5,й~M5UOWta а)Km»ǹt,at8gb1D}= 0qʣf%:vyVMj]"TI<\;8 ܧ4zΩun#7M"B{_WW2딩ǚpv7s*)p 1j 7%DK+(?"Uօ yMµXA;!m,0zę5]>FTMkU¸S:Csa+1tjc4S2~.4 4|Ts9w7:a,N RШ߃܁ 4]l1,giÜ`g}>R3L ^&EAĦpby`0gj qu`jXj679>, |RbvE/A..s/,OǽRކGx^aB2(PzkugvP'# #N_ujN%g.::n $pQP)yP3R!@Nnu?%\` }{{ qX`T#Dq<bgn`4U(Se#I_ve)' %D8f~CD9?J<>P۲y};`;}Jnc%ql Kl؁kғ'Cm{COj޺Tw&;{~}ڱ="1󊸎i,J6M(X1Kh3b,vD33=&}\JN VF}QP|Zui nG_|&*8Jk]5uN]ޚJII$%"z~&'w1J𪡟ۍG1u i;'iǂ"Mp.LZmGN6@ޮӰ}eK[0 9:iRPtrpq =}sLq1t 8#$WPi=X.f(R2/̳*6 `:Ql0*] AAUuF"p_wf] 1PpVN~'iM%9kJÌHm)ʼy*Eo+`)E!Lub?uNM/XXh~lB˽|5v*jD0n1rq6M].H(QhבrI1IslId`{CK*>}g,KdlK"7l wNn{Y܏ՠPFa;_k1'j(َ{P lED>ء)sg>iuڶpks)*D7t U޶\I3Ce7偽33E#bţn:ɷ'ZMWgmY&h8 m>Q-qD-D*-kPٴ{(iCr%(mQ "~ hFmd;(PMB䟻^7&<3."G]CFO[MKPA3k=j2 g ?!q.{#?#S!ЎTSOiP9R~p96,Z}R9#Wdq%z Z;ugNL‰R:b$?'%z6Zs P8䭺J;"ٲ#PRDO:{:[;nv&W3bgT @-J./k:' t;]M5(6;tU-O@Ȓi:|ʚj@0ǖ_i7-W"AQ %p.薮\(PxOOniWMkb-{k|ܛ mX`bZ^ѝ8GAo?PԳu5QqA(Ѵm1{e;4E?T69qO%˒ |xDg%'Fߤ6x])ýop4fm}k]%lOaMn_"U@ޢUQ ~:_XVTa95129I G .+lءKJY#uP-d>74!>lyaQ@lM q#44Xoy°%6S%-~;A[E?RL^CC i3@r/YW" DIg,Wݺ *={O?=5qQ7m].D^2؛{zb[GKu Ks@F)o,K@ܫk4.9 .I`߶$s'qJvњ肸Szi%AwUfhA~d D ľ7hA`aA܃BvxT>~J'u¸ESZ]⭡V3TN0A}<( =(V.ΞaC 2՘9ldpLۚaqb^Eua"S6QGZh3|Z2]Ùږ]uTiq^0P2DGun%sDF~!,$(Rs,J7%xyjw֡!^ֵZ:7~ BKH d%OpcNb]&$kyDLWk ` ld{MKDŽ^*M(DgmIsf#yK/Ce.ڏ붞EHh94!Ja eG&Տ,I1G=a/QJm%Xa=^ ms*r] $p ojG00. 4 ]%p>C$! J5DŚʊ]£$DX.[驅XT!74 aـ[-g ܞI ۲k`+rW;Hln0L.dy^(Ds2U+_Wxi.De9WC}>A(q#H4v( @8=_o Xm}4,7БrPG@4@F{cWNƏk̀4T4SQߴH )\b.!N u0Y|E1WC X%tf/O!U# }]~g'Tth@G\=q!^%)Ɗ:v~Vxfic'oCt,~XoͅC9j!@4 Wxy +|\a$`緸} =lF3miE^R{"̏BuL c V/LCw5Lá=dMl8:*&6u̪'w!h'<{6b =$h<1eD9W>*ZOݫ]7RI幧G 6!Zp-xI~Z"Xcx[EhTCm|~pRDxH?+D$Ei>"C" M" ˂$t]7Ey%0/UtRuz҉&"JtK ^.,KU$Pݺܟ)uXߔpѫY44N"e j±YbzS+% 0[j{y,e "ZuAx%F5=W"%ghp[nY+g~b:<{S7秦7Ov\Bs)jڑ?N7[!0LX&f# Dr ku7 C+[H# T^27^(P)y§TȲ[qpslU.whUjXQk QޜY-jfeZ,\ @g-bJA3$X Dܨ(R`#AEz⠖vmjm …xx#1jfu[@rM!_wGgXqvD CP+5m1i` /<݌NVuм[H9<sؑjCr|z}?'^0qz'w#dYI=g} ]$A~ḝn|5^t͚ y7rlQ(15Y=nC񛃉|_M 2Q§\%njf]awy|IBR|CbB =t3;۫-uEKwnzx+>>׆UWwWUyaPi^DUGa|Cto}i{KDŽ JW+{/A}x_m{}{/?[}~coB( F ]{ Bف PC0(˪$.hOɊpo6kO#8 Q #@QWESh@@4XogN?P# ,($#)mhw6o xVx0/8 ҂A_?qmn_-w !~::5nk! ,$#@u ` J0b<rp"_pOA6C崌""e /وQǜ67'B 5bxòA tوlldEAUT@ϝˡLWAZkM%A4bDQRUE0GLr*}24}:ϕ@@Q S/$ޛ" xVYGUy6BeShWՎũ_ipxNSe 9\=R=x%j%W/PYl|TSS|CF!$:p>:DxL$[5UdqG1S=̦qx y8?P#""OLW@jrDYԒ<:E]ΨD`9s|BQWt4< >s n"TeZks*Dkatm > x}L% `4TF',25kz6:}5<9teOCQR3QAKw_ ?RL&# xۚ7gkݕiVig8GAiK  B~+8-qK%Ext~iU],L|,w3`Zx9~E;< Hj /eƱ8D2j>z;<{XQĨVcP#0hGw+ K]we6Ft{KxI ;i?Bc2 tl4NШa5*`anm .<5 $IR#k>o}nAt S-:5b8σGn1 4СLpNS@(DaJg_PBo,⦛s"\gj?<0PB|ʅr&Մ3b~qB^%9X& \1hV\w(#*, PH$a5Z|'#=+ YaS!po#/.B0?z"XPRA.Cy>PQ/w2#4"0VeUl{u6( +!.7PgFr~X'h BEl=k~66&0-8Mk뻴G|lߖ+`Fok:.0"MO*$զ'-߮=j4\JL-6]ZIfr(-_h c#v,Y*(xc|~tCCAV_;V'(qcϲM1v ˴r\"Vw|\()%B[F49JR7K%{#8+N#z kgvv_ֹˣ,“2ez<@+F{jڄk*jR8I2g_Ԁ ,bB!R f*"|xyuH³/hl3f,"+\j jGX]u׾ax摷8{D]\* Dv$.[C:\,,:Nx:& @7[NjMݯ3m ΂X/:k-m:iG'W'eQ"AOj"G">'U"0 àҪ۬0\lr^a>BwI{ladN;t#؜U 0Io|A!k:5:gTY}4L0wA>-]`O|"rH!G\6ڕX_X"/,Ѵ Jp Sڻ6h𳊓:D{VcƑHϒi}q=$*;/Be|_YsPFgowUYP~BUCynBʭD8e:1f:'Hyh=CA]/׉$^R]"-CF׷\W/l4+وH9&,e""e{]Ba7⽵_f[I3=m( 0a pSp±YR H.sm,Pgi$y]KxXl0O;҈*,. 0g ;Se\:y@P栕0)a%S{1Q -ɭgZ!˼*0* Xv{@ \z, | Za  GdR &bB {X6Y ,Lng@aE^q.{01^{ l wz12O$@ KeZ $*A ҧ}5cu]=Fc(*)#Q*TC,=}3:l^p4**%YtBeUkRa-֡?Mל5D% u./TzfC%Thֻ C 6fZ sj (|A6^`HNA_l׬B3-`DJ( OX} 3iHn#*"lk M\2~BB-OXs$ A"&}a͢8jzAV&XVe'8I:Aۉ ϻj x0Aq}YC ݢ 0:U(5M !\bC>s40%]mĥsa_@ >zdBw 0XAhސ'%%¿b!ʓvBD FF]mD%`bp.FH?R :KOM2-!_-2lAKe6eJXxxH 6 ymR&2k(<M<HSd4<p~MF@QDx;~/Evv5E}ICq%s G!$Y#*ѳUxu `$(i6-^q,w,׳LcEXQ[,,Z"w~v6[`L"UYY8IDh0 pTQCxZ8*-li![}t,ε q i \d):iZf|l2o <1ͩ8a#!6cѿEb*Hg! =AsQPf9xY2Ee,Z:X_R Jȳ}-6~c0+A<fz27$x˴~H"g6l?2d u 1 au|w=AllCFzDgXjcǑh5WBi׋dgt=0dA؆*&0 #P@`=1#ײв!m{F+Vg8 6 m,t&xu:Kh*2s0s>qFXKF#.M&:Vq#N%_aD/s㰊&#ȯty$+lh ]n>"{iy,C9I qpLnJZxoXEOjSYdEQiz18+E쮅&F}ϱyq& n =ޯm(!fo Vۄhc?ulsFN&IKz/ b!lQp>q)B˛+/f\iPJL0's`{B?t/du_i\똠}4ۜ j=$;e-7Sla7DLʬHc?ϓ`B_|(<>+m ? 6=ۭCg.(|DaupAd8ޜMDP/Ά'Q_50AI>"ic耳mxjf,Z3Dzr.\F sz$˸JHE&ƥ<l? ;u̪ 8gIa!p6auB-sۃ9EN$henp$,/G| K:XuςMrnBeq oZFt̘݃/TSaxE@JDOwĨ@V }2bpU^6%^BB`yPѢ-}6!V`:\O.`V^Y8QVi"ʤ v`IB'F{k37clQ!0 ӱX[_s]r"!?]c>WJD?]ѧaf+TLt]LGqzDGeyb( ,ZO)!in 4?OEUd|^gyV^F;b3#xNV;%]#xC*R~E`{լlj)L `B%6yl%Y!i _8 97JOЧa5<^3o߸t+=ox!в#ښ 9K%y't- 95`BܟRBjN㘷ˆ5Һl8s07<,Jpןz5~oKٝ?,ojhҢ<2SmUwٽtP8(o& ^Bw!Њkssi gf?G׳=ȷqH^ܵn;jz5N;5+I?Umh}煊[SFif,FzARJL,gFͺȆԚo;=bKA$!:Un>gqh `"xTgwy薶x{6C`v~LaO $C` a }꺎c>s6M,#d =T "1fPa1rF|6Ik>"ui}H`BZ] nAzKE"nmayunwRH0{{CU:Z9R\ %$U_ mbX@܀h30֑gyW-vm|Ѿa07; Mfע2jVѣ=&Fz vㅟ&ׇjD`W!BkOh %{]1]IFũ;$T@G[-_?H>S]a ;y6\[FSb1g9ekf8u}ڨ3K%Q"XkS:H!HpEYi^#h܃<:A{SuD a/m4'\{xDS)3+PF>Z*(ׁ՘{aMszGz6XEWaKpshl[5.x҈:^՘j8j6YE,dn,sT?F;ÂΔ0Z:XIoA輩_]'36HҰa^I=`L;q޲}ϰ,o4_8K4)"#*굚;hc!N31Y h)XwGA +} XH\cQBn|:nswj)||vOH5JҔGB^F@2=o[6Sfȴ=䨘Q"9kc dDGPB0"͔k?;eAi;7:nkt-vA11vlZ'Y4B1>9RieFNIOus9AF n91&dլw vFlY[G͆?2),HIx]i#eTOH߄g(72"D>0xN #xWq-t sXZ/888Z.{?HjO*-׿z\vmC˄u(S'b}p)(4GPX"^u*nG[ ĝH{2]q=o4L׸h8utdٮ3eFhoFs^ 7"fV"0)y/A7ːdː`SN5;,?qZy"¸J47:vZ=Zrwrr?oP+!Ÿuo&#)pɕcbMm_|y IL0 O#㑚?61iuhv8 64&+x- u-x]t<ы6N= l`["|z||%!. 'G.# w9A}"Gx~- eUbfD%##BEbH36}_4(HP,ϲN/6-g ( f )i6 e e?{[uEۅ;b4:a!D"lwu(ouukfB(xLq3WjU֩ḐrdDhI׎$_#D l8+CvL c:jIDt^!vy @@R|JBw5u'LG8~AQ4 B$ g[|&]$؋#9o ! fS<$XvI}/ͨpp;pmv1vvP䎔T@@\ٵ |LxiNQvX \k7wRD 4 ,6TQSe=gnS\4 >(ɾ%R~O'{OPqcDqNe{ABUb$U4&ۂd[ޡ^azEMl6q:wgI* OFˬ2}8g!Y6[^ aS"|H7j$/:w*B"R?$RwGT>Tw" HS9Vtu3,ቋ:Bpߺ1CaFQEm\@5ҥũ0wH Rh ,aAEs*R[20/OgN9 2JxAbSL#;1FD`{_ id,i.6Ug:fQSpƽPqh%56\"VxF#5VM;:GSh ScrCڅ"umz΍mDF 9 O³A*$"!AK?oJ / w b?569ݰ-~!!,YL³}n7 Ü[][‹A!h!PS}W|3Hg$un \X.i8B-nvNȟSKo%nZT hp E5AbQ{l\_C/6,Pmq4 7Bx.lӸNrM7K]jƳ8 %Jm -0W1edm촻mQ~O U$vC>Se #ILejPs5$D[c9k \v@5_~sWqA<#܋;r**_,rA=" -P0_Tp]HN&G&3(9 Cg<ܜl7Wӄrv}GcV s{dEж4S8!fAzDbؾާ3 fR!bHH 3i`{J\/ JF{&8o9 6̗ 84uzkHZ ;gO#jefGAQ[?Td:zHL%%RA, IJ8G:P1"q[o>:{4ǻ['d)X,!_ϗ{u̱/ek%^UA韊%Na41jAfS?b w VKy]9 {ƌ5G'F-dv2<5AjPR;ݫ H2Й)̀ ETfs!i(O֧Z}u]m23 u B'NZ$;LJ'TYכu4ת=*jυ@j|ypṿx6AJ/rX5mJfBF *4돇٣8;_pb@rKmYQ3"p!z]k!>WmF^_^7~ Od%8E^MDMx><լJhn@mqP`o\Nt.Ҋ̥*Q_.2fQVE骿j2N}~.P؛ *(}x,ሎMYv};ГꀹhzB/?{02 %S&6jlyۛu4z*qA sQz9AܺM{((LDįp:Ʈ0v&"82״#wV>8rh#r7snJ܃^!]#0(&gfZ )´,7D!4*IQGOJo 9e!nKM@bfGNf݁ +k 4EFUbh{{OX{q61gu!~I.|{֡cY56jn0<& ^Mu×bA4ȿN{LF-l\(W,eӭmjh ҤȪ2_R D)GF*P:"YAe3>NdA"4Yr:͕R? 9a즜U 'BO6R*&XR#. T,e"ț 8LMeqLR$B#Bf)rvPpX/͂ok-~z\TB`gq k0b ,wo |μysn:<_g^[^zӏyȀੀ:EFaXEqVyG~GWj!<A  H#e4`Xs iPC ~ۄ! H4@҆S):3gW˷}=*; ,A#.ox /o/\ng#gQ( qUeGUd:+ا; F6J$Qt^#~wblkk(TQU$ )7u}=DYOlǑ.˩s>zA G=((M GAQ`l^oHZQ~\o$(KԑZx3: h>A"G : @!1o·9!Y(((,I|϶W f3\{ygТ1 Y Eە}PH(RDU%qU` yeK($Kh$=;qF`;/$!DIȢ(Yx2_}SnÛJOa n`#p0MS6C!%P? C-^ sbMQD; %dS#BGOgQ@$iei4_29%b u|iPt,xvAQC`< vb#>)aL)8Ow8AxD >!)Fg\$f/P(2`vE=IPFGqDb0UI"SmO)Bk( "P? ^hYb!*0JQQb~I[C n*: AX&QK—}@< p\ȶ[{ 1H”@ όa"Bn %RVOP# x?V1QHyQ P`Y14, dVr(4v+"Y ,ޥ(QA6B!v:;cbu.ss|uMba;k Q\աb⨻eS9*xP!ӛF mַ2EzS Dz*(CIN}RqK< l +T z '\L~dVpxs<{VhFΏ"*/7}x`Yt$QTǗkH{XHVDrQ /6oS Bh1{q\y Q:˚ޭL<ͪBTB|߹{%<<[^.!1/)AUĹLh.~Mג{n4b(_4Mh!¤(D@ԿUlp@滧@ J &J2hZl7*2ׂpL'x=CR4 gқX/"5nE?䮃EWqR[R|'B5|ԪRLPGC I(De!BD $_X ቒv?w³{ |A EY$;|! #TF!-3 m1o>x8_G:a.AAv^51fAP:õG~2Y^GgcEf2 ɻ#8uIxEՎmb4*9U Be&5./83ލʟnt\2LyYE9`7-QF𨩐كQF[/͇տmIYn`#^;,JԫrQ5LD/6R! eR[@uw/"`%#e cKf]+b*(ѐ#0vc_,u(w"FB~û\;SVMϿ0I_,AFH+ 哱y^0]wsT=MSPj>tG_lk8N\M&q(4S󟙚5]bsnUf8 ;<:]z"p( l\3Cd5N!uѬ؀fػ-'@ ا@m$}+KO_eDHjmNwe ۧNDk AF#'2x**H'˓j^LS )/[.:32 ߓWYAbQOа;/ BeFKp=C40[:MC:tCΟiҡg#ˉ܋p׍s$}47_r//5v nl| ԍ. $^*QABMdA4 bJq`yܟbHfZ `v[8Dax^F qR> 8Gа)Aji&u:ywMdQȩz l%`*̗@wh B?y"BId@pYF w.K|sι{¾< R%`' ɇ̝p'J@-|Z4pδӎnRX84i7޻!]$(L{tPPA! i*R_: .:g?o KpMU' {oWIA~U$Gxa^pQurHS `dq F)Q?&FapyBV$QU!_vو߼[g~6cxYMCeEHeEx5h|!W_L.DcfB$S30ET;ʜg_3߄<'n!tt\cehkUDLG< pQ<ͬpi 0ِ(SUUy!)0Zno;6vxf()3H A~$ ;-1^Ju ,A#&~ k;_sKgdi"4OG@ i"V M #q) ʃ +vi nbx#&T\a8AЉs砫NaUFjMиxs Z j`|@, Tanv lI2^LJ$DKSotNf$B, vk1DL ڍL|D 8\# E_5.G"tβ@ aFsl0vKNy=![ ٔxZ\幫?B!g@Eڒ ELCӜF 8Ifb!UJOcLkp=GF|X-Au/??,j*01lY2C$xYG6xqkb6-7JJ t( lr ΃@TO͗|5yxEyx4N^Üqe6=..lCk~8/^ `9O9gK\O^j4E.>`u,0 Atna$^7KՇ{N ۹q(Xމ,$rk7:QMuF1Dp# wS (MH|Cu!W`_ZX?7/'<R cBklx1kۇʑ`jA{ڸ[K`ޣE_.\k1w]E\AOdOHtF)%>mxejHg5Fk@pXp ?hٶg]\sm:yS+TLߵ+OR@hllp`A .4 c6"`'QB'Wc樓Z x{_iH9-$}# .`#D`xdZϛ#SC| "Ц_M$nssa8cxOfi!X긨fq4.J{OrЀ!} W5A@p7<J-*rkو.A—Vb3Xh]]AFfcD9 RYtu@uN I8'3;#P5Mofa~`G"ЈO jI8Kω<E ƓT%sn?ڔ7f F}K⨬ \C]k Ndض^zeY B>[ ǮQfUrhϢ-si@HBWj!DHԑ}!c{n% 3TfQ^ 1OM0j ; ]!p`\oJVBDP{ *'!{ -SZe&Xtx]g#AT tA0u, /aEQ%m MtN ,*b:45{:y%XqL=җ[ j{MF X*7^Y xs*,s ʿ:ܝdFB1yuU L1.֛ ? *8EYU$$(iwKV^|)oRdtS{5p0ts”[& mmrvO"OCVMf^&U^r?CVI=V>TGߪ 0t<@-F.}WW h$Pл0]U. )2ߑ MׅdS}?Ih D=y xB_ Oȯ}o1x {З4`FzMS4:4E*?O2G0r _(TSF%?k" PzőH k\#fw?/p A0,, G^(d=ns (o]Y6Ü%Σ&E88_m:N& "<.$슠=6" >BmnNJTۛ)I>Xk!ɢ@hx-U~GssJ KHPޑ=iB=Kc9_l׮L `ǶWzC-5=½2wQ]iI>t}[R(E$Shp AґjQm rp!F6:s&*7֮ЩC =z=# arC^n)/ȍ h~{y 6|;a1N] @b-4eCFwP=Fjo'ܣ/ We",)֞X'1Y!CzO0yaa\0[ x'S8#?wXWR7L UQ4B.4̯sx@nLGނb/O?JG*$e5w\Gu&Q!UkOB_̍oe;="lH '}Է#;.Rܠf*FEye |Ħ>ͩ`#N)v6j0lXrTp`w,h0˶;}^I 2ɢHƏ[&x2g kIi#,ʫ8Č@L}"_8uNx 2-%<Y̮^V5Ta3,x{y۞/v9t- crVjNx2P3Ě.Hҷ5QBG )hc+dUtaS+ݡF:0;C#ڭ~ Cub&]e7x,3- q+~NsK Lw #Y[ .Nm-kDF=+02ڰ0;9FQ4q'HrE-p*Mzޥ':\{i`"HKH^C5{ cu@.T@/UUm Β(RyCD.0GxSWRB8Ih4P뜘?FD=z ȋ|j` $$ءo6 e+2 ONݩet(T b Όו}_p;G6@,8J`M^OEF?^FRʱ:F" L`Iv_E瞬0|PDzpl s\#¬KhFO+xr*z؊B9$0h &z=0sk;nE^mMgBɳ ,pp_B o@qBuԬɣ]PʉĀͦ,3!'*7FDNB5:@ xvU+q*iTxKp+ȦmJya<|N(KjV6fN`"z#:!X25GvZѠs` 姘.Ko<˳͛i[F$x/WsVc|pL] ̩?(ȯx/Q`w !+NJtFQ֛ wn<5w9!E {^ͲDi"hZ~|_o g۞qCDw+P7 ub2>S|&ϞnS4|E3k4hb&Cjj7u|\byYb"c4p^+ϵV+$4hlz1y4G "WZ %G{o{mb/qZPLǁ,ڕZm@<<|>z rxƳ/LkQq! :CY_QE<~0w{?Fk~} V/|TkAYXbUa#eɬG{8վYDt\lw=2퉆y{5^B' ӂQp3MeO aeuk.l&~ @؍jb#$iFr/ג]ǘ<@>)G%T*VGgʵp-FաȩY{ :7SMqHFh& }XR;AsaZA\j;-*t %'#W i 5 H&h}zeX3_ps9笝%4DPGfeeI\{Z&ض~>m/ó; p%1&'pcc0k2R!2ǩ"T7]iA Q`J_A#7ԝo-~{ӓPBt xkBNmOsXE64jwz獵\_ξ4F~(uN,BϨ58j/cQ=:109$bdWjT Un$Y\ qBFB0\8So`JJ}|>_@q\J.0A3x5/)ֱ %z=h:F̸L[Hp\/k{9 9JH' edfĥ/,*_4A3~Uت,5v6σ4199V{2cY }e"!amɩ|FIZTJN_+-Z`n4fzdl$QD`{^PDt.1 $$A`p)&Xւ:R2iE!Ij:E;ʰTn<)naBCP0}k$W}J]`"ͽsgu'8TɮVH8*m!$HXƖB@-ykc p8 eTֳl*/KJ*U6A9>̈;W7cٱc}U;gǎ2k’f o)זYaZ4 2A[ر+G&O8{GWnL7<.g wp'[<b > #ϣ,(#,#W Ծx!E $/a\˄҄2*8E|[gk+iFa +2Hebйe.~AaA4-!]ί@H!D1HqA^akB>b@"߃ggU,(QPFAz7=ZB_jQDeZ@ K 5M'ҒF)(,>>{>؈] gXشL8KFm"/ ާAq0/ԟV`:}|<{AQiEz eܞ61}2"$k;hHO"wE) ][ +>1/wZqrSHuBZIedɺW° FD Y!xh4eE#I0!mliwǔ* .Ʒw575V?gj| 0 @p8c=aw5{R7[%AxA-iΒ@`b|mPow`qst;msa3p5)RBDUw]z-M#P0 k;A$s6T60ʅI̓84k,FXCXmZޙgX$"@N5"LE d^CU"xs"4 Q,$`l<ԮJ[#芲R|j)Hh@H+-\bx9% /qAyNTR4 E~ ҅+yFg`dD@-TdqejiV%%6`P2τBPڎRC6)y2PA)IYga -[ 20 k,wFqA,"~l覓o}N> YC[3{H"_h CeTd$**-QPqBp-,bjY/ogQD piZŴqݼF Ws !xGQ 5|"I{PI$ ^-G T(Z'kc#d<ީ 7K1 duGێ<^I`2͓$@b[}xleI9ނKUgY<;Rf-J査^O ruLӅဧ`MbDޮEBП`l2hpRέ$DX 8U\ Aa*W“-|=ҥR̃~A" ZS$t"b̓VFmak"Noc햁pSSZ^Jlt!=0Ǎ㧈eX3,>;)8y> nJ͚W0@ڛ7cL#)! *Pś]@ f`NLMdz#t!<P`94A": U|inLj\7 &@wޯa8E!X)]g%~Moe{N9r?@܀R-h ?vaA>KLL"4|t*hC̉"6RY`6g(J!I%4e*A+{n1slOi\!Xszq`ZK]<䑮B ]#j6uJ3\lo185m؜2ϲ m=^qW;k'ޠ88:}/"qf-A(M_z1"N2EaR+Mʘ^dpdw',yc6kb4Mk)(P!Ņd  Ag3ZLhQ!kCՙQܼ FkfaBKՂA[5fmPlAXyHOѽЦA a g{&(g P:,uskjx3yft-0n0!(A$*ax6 |ϵg`\5`fȵA=LX#RO ȚFޤm$$/0AO`}ɬV/K2Ju&4T\b nF}] cD yJD@ڨ+JjW3X+Oq\0b,pXQ$rk XK2 3]ѕM Ęh)fӚ}`,;pAM|m‡]# !\eU=VW|bMzK;\t=Huj#̼0'IHUh%v1x`aq.BI1yMp&C\ġmͯH?B2aOnbtDv_ +WDlԩD@x!(MU} ˍ]{HGMn瑮-F"yj H[rg#F{C&!Y?gV- 3+(޿\-pn4j ú9gRGRIHՓAGbn-HUCH|fI׬5D.BiD;baB[um.!tKi<zThf\WL39a(Ao1>Ͽ7,-dW%Q?F$KuK5!}[&cZFD5專3ͫ0AV@+l& hTY`O`t-׳LuD"I8cN;6Q ˦ɲ1gz\iq+5IFxA% ̿O;IgFb{nl>_r|]Dvݑc>;Ip& ChB+_H2f1Y$gmӴil<)`7cp۬2c|j>╝8o5P*IX]ѨZ|$v? `Йq^^5ȩ0aFGZ7]`ozl] w&Dv/@;iPe In ^RkB#?~kH!BSAx6lضTi4$mRQf4@=R >q!B;ZvJer خW"BEm_88ZVE$(B~]bq܇fVChpčWo o5y峿.wp\_ @!1D4̫ 5@Wڞw4'1zFr5ւL0h*# T}CTo55tY,_U! dd[yQJP7tv.c\TwփWJ'ߍmQ_Y)W.pJ> l]*ԩU$Mv@`;ռnkGfW=<.ܮZy}_1sT0]6RxK",` /7pd3KBwUș1qbu#B Wjt=uMC:"Ze 4CĤn٘QȖߔ:yN# 8 iQa&NU/^301AШ7exK.q(@Qsn ]zʗh(b&0V)j؊C:m|UQ0y^eQDTW8BT]*ACă/GVDUfE Qfޑ݊K/#ͽ}*:U\v;Bpa0ߡ/-%|tj ׋պ A7|L(Y\f] &5_5U飫vهgej32rA\fI1o_ FP-u{g NI \w0IYj"h&^Zޞ8TI!Il:4eT=Y9Ccv5/}k1faYgYSÙ.2;sow6LOvr[3U նax!j؞舔]/Sҡes[9H2UyEY ABqvanmyKz,L}PG`RuG:gTƔlr,'gѦne[q@+[Z,Ҩ*6]|\S_#-*%4@y)dGMC5^DxkoE/³ "D{Svk2za?xtp[mC - ABCwCqzsð٪².xccq8rO֌壗H$@ֆk!ʫ*.0snFKK$^~j=DМqiB嶆QrUR ];g]Bm*'t>'Tɣ (bEjfH O9sLo5B!1j.VG'5?a RnH۴キDiM! m'>cukLd ªU{jۺtC4Y.@%s*sȣ~TXGm&E%g{v_s X"KgBLq+a"=IA;6'[w(S>S=ri3`w#6j9ݖWl%. Ԫj%67-%+Ҍ~$W1iwϕg*!/Ѩ \  Teeͦϳgqy?ٹ(l\=ܬȰs/e@$\eƱ% ќ[g#e&.Oࣦ+ e3\BXJk|3:!%5y:KyQbo;2$czBqP}l62$DL{ޘ5e9b$~γ&]_u]i*[Fxc:DmK_cpII lcSb^?5;.4uMc)K1_جY!V?_%\Uu͒nt@Zo+ B|wͼj)B]M\h^"M%Dxthuhg pY^6apv`;#ޔ mBt :5, ogh?!džB:w cI' ZNxaVeSBj!1 Z>,K<- ^/Mkǚl5@P{%Au;_QF-mM0"AFWjD,xɷu^e97*7h$e(Dt*Uж#9LTVڃ&~iM4nIvG>{c`d:w>TW(II`n8vݹ,l*۲u ۦ= {eDTvQ*V׾7lMt ˦Y-eSIH|~w'0^ |f9.Bc~W:<;e6,1k5F3.n Oh8,q|U>Dv5]Mu m%wHB5\Y ;Cp߲aN]?i>e9FQ,ѥsGnQF2Ob\e19i@!ಫ0;#Sqh .Wř! |*RW[f4@HanvB56]@xF)]X$) :°u>,dfyk _8Ԭ +cG9::iryt["P3lҤ ׀ KרL(ynG#61 zVt4@FlpSf4!1R }{o-;MLbzcچ0o&;޽N+Z嘆X@:,FQ5zE{K~EaRy\pHI؛9CSSט(qxe7.@)<IMdQmKneoTmR7(oagqQU\禊 E X6"mdί[& cAu7?_g aLh碄x)ESՑRBXWCs|&.ۂ95Xxٱ3mu)m{?~]>Bv`Q3nEJ^@C_G ۿNfmgfDz]'3htNsX 62 q~yI} a. vop(#I!('iӠ޺#ٺ >*·8 (&"[р]Ʋj%Uq-w,XMafAֻD Q]Ǿ/>jnmFkJ4:O4F);WUfΞ=S8leXt!fp)5O0a9p=ឱ^~xz0 r^EE 4+$I6+Z +7o28xD24 Asя0-hdt>XF{y(a b):YYx,Ē(2[dz/he>ص@P!,(s %9g ~ojyA#rq/,.d7+B;HxGYlTKOm oQKzwE5W`Xg aaAy w.+s?G?gE,yQ\%yu{痧UQ8ʪ,**f K-ܹ|pvÃkw\|8?+!ߞu?<8٧|O.qk0K{Dh- f x*IȤ,keDJ \If#Ͻ[5^L#%"ѲYFv#aHN "<;4af VҵBn+U|,@:Vg$N*-JF 6ݡj}FUA"Z@☦|Ե7 /0B@b]c30tthRN F 49*ޥe]ه(T|8AE%8I%J(qte @ a>mPe|D!ʁYV S6(!%Zn1=;jbMGLn*,Y'I4dFցQ񎶉 ,ˠ4ɇXIPI&yxc?2Jry,śve]px)\\<:x>FY`(d@v~H`i&:m*9>بe `+rԩIe[xo!$.^<D4lhy Ͳ 0"ǶK |/}C>3VVe=9A].Cυ3pK0XzsLdu- u!JR`KHH.9&0b(J! . lB^R:`,}QC\wN|mLAIY1(KH#ڏ] t2PY:D u4K lۙyR;+ߖkH0g2zIE4/#33¯ <0ß.Ag7(ʲuGE6 X<A 7ɦպ h@#"gEدӦ3KNF5aL"-*R*HGkJI$w=Cx3FQPdy^3 ڔp9 5/x1LxSFQHHS0j6][Vp k dV[+.~8QE{ks!MJ1*c/*ٟg;Oc nLfk̺EoXsQoP 2+*MsYܔٝlߠ, B QZurJr2M ɶ>)n:9wtxeZuGU,tکs wxO&ݝ *\WP᫘0aHY+L:J1@ J*d,|BuSwSp3Q2AHV:pt#x_ž QIY,.oX Ghy*Ib*fo ZЕe"!-}iPJD`A lZ2Ba#E. ' XXGYM ͚Fya$9;ϟ?͗!Lޤ^2eT!4̲ 5Վ^ 262Y)#- <߶B\]pد/̌>xҝ//qhA袾Ԙ i6@!EW;DpGF+ a~@ sQB6\dlozMZu *2g @Y ISE|wTᓉ9,e)-QLEڲZ.hqQqNE3ҕMk xLU%NY.!:%@Kyw9b]fdG['U R`w%t\N52@q@ ITpA"^'\GR4B22HxbyA]MRH-ZA:*i=c!E_l5'v4|n,wOB]jK_8|ccoSFX|ѽ>Ҥ-Ȗw*@9NYA0dr@A <#!>*n%i;{|Em }ݨ*A $EA еhNCBSXI:ZH!^V`WVN)|"ͨ1 la ^ˎ`-[ AdZ6PHO5\2Juzxxv~[ʙv%yw* 2ulۮGń"!T9h# .6ѻMby eT,`B9M=":u9Fe?0kD}I<ɁYN`/$`ŃWMQJԮ{y~KGFg`ҜqnFudY~Pg2 `Q <<("4XvF5@My$_m0eb/t AwɺfgifͧCx QD:Yi>t﹂# KG^ױ<&׷w(ó_KJBftfZ\exgU|;Atew(K:o03f-hT$QUUTȒȦ=1}܁ ܣ* %f;Olaމ/xFp8 Zvoytv U#M%_w.EC fŠ`Q14@7" >ZkvCyyBY@Mŵ lZg:hZFM24 /n҈㈳IXC֭N_4}'kj̔HC!!A&yZ AJk!J{4~H|L}ySZ7mUcǯUl $-$\^}LGnJdxHCi6JS I!¡v"{l6F'"UmE'dY 8/?ΥIXOxSOq懇ÅX'k6O[( ^n* \T ._|4JPᥦuA v-U' -viHNډ~SQ͘ip,2Ҭ!LТo &+B7"G|?ty?AE. o#GXyT2emGCYzy6HA(^AEܹ_5TP2:} 0Ap QҤ@3`F F*EQ!,lǒ|,:"l! h$B92щ5sυLz@)𨩁ٸpRZ 4 9:Tw]xn; a{c_'RqP.Z W>wq9W> mcpLb|U=H2kh0лӈp#$c%# IB8G[&,”u`#=6A>jǀ}FZbQBW#EX"|T! .@0IHitp:"t |2iQiFPF4I0 0\35ƲGl56bVZLv6 t .ژ\ۑnOA侠IDؘDhQÖ2ƤUkC< };diJ[!LOAXA!N>5U5%-XiiRkD`>DhY [L(m\ᶼBlw=98ԓ*>}b:(mڊ;XAp%dzpxp27yB4@2&7.j:y=Zy"ᅑ#tw[m>N[:-& \(|^G"{3[vH|LO guV`\lTZmZY:n$ȭ>?7C&EmHu?bcͷcNz f@%*<A׿ڄuB2d< 91ije^eQ&g!5j.ꖠ_ӱ) W;?2a໛2 :: t(y U- NaY~BtRx{\|T T1Nj0'a qr1KG?2FM4ɷۦA]Tk7wGr 2+0CԜM"  gvhAiU&̀\ #|cx!ubMx͡_SBFnCPw7Kw). c6JP8TPΘU86Oeh-+(uo(UG6oEa{Fb\@׾]xl~AQ8Jcnr! L_Zb}E+05;G \=1wRM';y c?k"uf9e!PU7탏 >i!Y^BPD8ey&RؤklPݚ 4T?.r]EKgFDG>:USLE]V(o!>i-ه4c (>*dEջ<+@H{-]z=g94K$T՞t)\!d <⦶RaM9Oo.~w7LȲ.Ph'Hij)&g}Brxv6p%j9r6f$1n;  "doMsEОT(Զ[UDݵ=Uz)t[  ۚz#UZĩF:I̭fjӴF (T$O kxu#̸_ㅾW F)Ba< ¯j3;9v4cT]֚"!,̥eB)V}ady._* //d0ͫh(es[ 0CN ~WkEo0V:_$򞅎wrPkwxM_/1Drw+#,z!3a4E2]Dԯu5,ҟrͺptYٺx>UlVbĦM:UdR܆ dZMwv{3F>,PvɳrŢES&{:$!Nja)ZwB4EZF QZV:5$8{3J&> vhcWjpk)]T DuhYkqİIp5_c ,p+:1M=u2q9-tl4[,Dׂ- :R x485/_c{aTdO~eK\/vyC/%C`,{kuNU3 BߢAДilK0G +bf).9aSEJiObpYDP$ }2ezqxƗ\⌄kœ[NXӨT{$M(ЋlR! [57=aC%JsR092bvS 9y>]psf;ve:!ߌ q縄/^TiWބڟSD=[C{YB 3S;F}O.>#:5&u|,{k|悛W+|#ɛxc La!uQ^RVGZ {a xC%0`("~v %!'a`}^ހ򾑜E凈 Y -@ l4x1-X^y*ۏ S8Õ/ O}t8*^3_mkPa 񎴃GH .*qJsBh*Su'N٣/(GxF QZ18vGi6qLG`"[s| J1Hi,fi!x d[GV8Bc׈=>/* `eCgjh- T6w](/k%=>r lA:X)) iR* 5溷Ǧf^A \y*vwD€7G7h0_^uс b9K{ttǻ1Qa}ݕ1`cf#5r=(/j"4񤏪EY[-~uWƋ'E/ YKK>8R/P~Q缢G`[zm>*Fk6!0bQݹPBmD[.~(I}&Hx]:|I3g݉5IDm5#!xW4c;P݉ ؔqnX>͇*V0y:ڲ;Tk)ى޿,pRjV|.O+)7x2jo -1gy"Dz [K5&bOZ"f`g6Cmڌ~/W Cԛ# 'B_&.\w>ެe|NR॔ĩA#i TjZ |$&H ##L2O\A%™:,=_4F47y\b,/hmdw6/MCvW5T#:נaBxLFwpW&ƜQo /TT)/X@z n njXX8Ḵ\ء,AlYu渆?|$ gGy!82_fwQLc!|E!/X|̩f-޾eؼo7Cm8B!s1%+23E{>~Tp˜yxKIQY*(kľ4ū9@`Sn$3AC Jw'r%Ryk6fkrfMce˘B:#`;俢k6ߩNW(y=GByqbB_d~q|csSAS!@j&5)``Qy6E_UູL+ ;lظ;wUwx`De2~viM6ћR0j8ETE!ekcP]^KrOJSJX+AfU{k0tيX5#}ԤP5]DJi'4ٴ KSY",R4pfH>ܑ?V#5jC1xHoNeBpA7P ޑ7n~::) k|TU8x2uPNGTjml81J:G3p ~۪M eT!Ϗ*wԥUPc*`gZ{|NIAxv1B4g4'o>F#]5xr~Rz_Oۿ^.?\Z,_[.ub[m_\^ o33WiH!GsFj|f.n c/*I@dl@#x9Kqe]S䡃n^V)$rcI+d1POpAArUGB䵬.q-eq |Ħ l4mʔf-юF2ݶreZSJ]|l3HQxo?ٳ[|Yao<˟xuȆ_txM=`if3Jv}ANxy*0;rJ@کDx\|`y&5+3@X ;t r Mo, C-TX) o&RBGLmXQ7d s?eAp} >U+z䮎ЀԌ'MC Ґ'e4m5D> &AR +B69ہYDUYe> |˅b N],@׾zV|}8`w>`6:Vx\aEV❔d@۩So7od?aʂqʘE@H $af0&gSW8H)]4$HUԶSBXw ̈́zv'  NZgAC-z1T-uBԎPΓHo7 1 4 n=5aEp0) u|G})Kd@!iܓ'VRZ7u ;Md:'؎A!f\7ц E6\_P`]lvRC16?'PxFr{?#- $D6+!PDUmeQ $ > 4 6 E&SHZ.Νl+| 1O4N].s0I]ic^00zOeq՗@X{kulH Q@#YR_ AXoH7)p^3h$]2ld\' T zx@-"{՝3n/eZ}ScV瑻Om6}9ջL {K9NHG9 \B!Ol;G[& Dw "{]`J(ȋɰj}n-Xc3H˦نn|Ȏ~_P(/J,cEUf!8nj>*l(ߗ*akFkŅtG]Hx HibTв] YDl5xKc7\w1Ѭ9Ӥj ;A.(?ep.FMD&,6Ҽ;AW8vQik777S fI# (a[?w57uBC,4}kfi}W̮=vsx7*zkY记 8 FL(Y[2d@`I 1!dMUȒ,2_((ZB̮s9}v~8?ÿvwv vIij/?oH7MV6W׾>MqT7q^yS'e,ξKwٽBw\ydws>wrϊ+R|0 }Wwxy-^yB@zI /_EEєETcP?iHA""kj\go% DESUdUG 뗯_v_@W }YF Iǟ3Ifϻ \C"ܥ`#$wjI7ETV\tq8. g-K]vHl \g&ZVxx.ݥ`*d )ɲ45#ZC]$\IGgI[AQee˄>U[˗U?ۈS=.#Ki nkei@Pn#&"AH(Nl Js臔?'#B;ށg5u't> N%-+=Ը s. :Q>C ,lBAeTIYc3·G|Ko$s0QeFbO /$< O>&f-F E]Y+2o?$0y)YE1)qG&d8YPَ6!tD@xĠЦ`ҨLěS!^\/k& uʲLF@%(@WHFqi.\Xf-8 6@儡c wn` ʞwhٓ#U@%ěeQ¬!!8oIx !l[2ϑ.HDQ:&7;NcШc ࢢe>WL, ʨl"F s' gpڈ` V9Mstޮ ̃p@cN.rZn t>=:>׀{MƛiVE]6`k0(QusT[w' SmFyI%LU^ 8g6zIuT`Ve>tOɣE^Yp ow 3XQZܑNlH<)Ϙ2~aAҼ&A ຿.=K߷b^,(s:Zxұ,k.)o (Jh3Bt(_qLpjo2z1aF6q e5 |_P YzG&WA肀 #er "2/6 9 fܒZ1xOv4)fײ& NDMщBʔOg#ħN?1(N3%{w@0civ"At+kxM= B!oSxR'Y-/u>~@ i^aF>:I' -zKօ)'#Xת.ov/ʀvA 18?_41(k(c3:|Y='{Tl8$hZCALlyA]·j g4ʲؗ/OV*1aF޲F=d\@ViuRA@G(O89-<>:a1Ͽf4kWB$0EkL>^l1X"5Oʺɲ8aP Fy祎0+Np%K|F*!o⡽nsרFQ`-15*9u1Q8jgBH֦@˴EI:-^,/.ZZehw_|we5D$G'\Hur0C?<ϝ_ی RGUΥYgv_)!mI@AgM6D jyBC"%u[0M=O1X>*γ# ,:q6Y  H,DeM_0:>cLަޙjjjA2z)FmZπi^AR>>/  q!x_!@c۶L:!qA-bam`<(%X ~a B"3 lu=!fܪ(K0,:5k`A'J6~>c-BBm;+4i,8G'"6mL)W(R0Dœi͔;gV}Bb:S0hcT^!RyۖMÂy6iZGń9֠׃|$A ֈa5k˪xfFbbX( ; S/82liQ˹QQ@L7$ xVOUMCpn#&i <|Å7:9$x{'hT\oa>2ѿ S1NF$*hF y>z(EEQo0aĹsHu,XcSz.ڶ$ ^flö*r%V=?n~M^kD<M F"{9\T9pC$ xmd +5%6oQ$oqcbQj(,mtA:a!Ļ_"0N(Q"qךJV%L5m(k*mTJ1~ñ\Zžn?X,߾Xv,k{gyfLѽ/hR4"JnwmL)] K2#~b\"dX#8FNvy F,\!]Ie="`qt*1%YHQ8 mVgY%P*/!LdZ3Q\Nܼ0 :bùD(Gٻla"!)rK}4XH!}HG&oQA Y=9۠o>ssRp'h8GmV]%1aO_ryni.U.zph.A1!8-&6M]AmdYZ%MUdk5LoJ>5vYdBme1Q.:AN. |a"ra/(d "O@pcd~PZ~W=Lm=sv \t ؀V2%!آU :4Hv-N:YsRef'P672[%5 #g1TTش\~7k=ʠJ=VeeA_b(– >TIR,B1iiX}Z4j5R߻J #&xFa]'ϢAtQf^$\ڐ^E ؿS c-&0Alqb8"C!2F!p6|k.D= sey6XK*0S,KZ}9wtm AK wqpppq.]:p]rw#W0\bX^ i( G0΅nMAs$"XAHB+r̀ `&O(,4a&6t-::yD0O!K4kbtj6ZtxtS&U7EY۶q!.r$qC W9LnK$BiS5/2\m-Fg.Y̆wS}?p~FG<#gSQ&G> vEJ6[IdGqe U䳵x}^Z#9B|lJݐ9-IH_lJ8UM aˤ_6#O2QS6v \ji`Q} 0.r*p/q, [߿lXh9QpƜc#y njň,E\L5bb{iwHO W9?gꔯ,QQ7IBG\cNЀ"s|]XgQ"D0>(d:r.hb3H°Vn^N02PܼP.*`0/rnClK- lꪪG3ѣ@_]/Tc3ۮҬ寙N4Rvї:(ϜhŸ[h'zP}aXΆ9q"Qkى@\Z~)BZ,@Rgn\ٗBo (ZEHȳUUn0V~?'f%Ze6zB}[,W1rťld D {5#N-dY῎ak"8DO%~@3:mJ@B86 V 9S(Qm ަsETM0d!i@(J9 {x;BEm#L Li'5qu$7WwϚ5 i%W @F<˦wǮXdLKz G=s FV8JUBNo`f1Q`;ޑvGk%AQ4eV# Z٢b?ʖgwEd^qɧ~ʀFԻNApU!͘cҌI*FA=ʮxAhPiKaXS0U؎ˤ( P(sшgJoAjMKqT|]FLBУ>$J,eam'{Ty]dQ!@y6mcmym{" 5`6Ԫ.pBX ~#gmPc^reeU5E'#<`3$-] cS4j tȑ`-kg [XSg@o1f޸d@б l4٬=-Okd&Y h*/:וè/[N5miE|B8-JsP79J<]E߬YC=C,Ip9p*7jAt˶e z/!ó)I,*F(AEDNى~z~B£$+ ([M(ܐ alB⍊lߪ* A d߄ٳ+SNFCWƪE GfI!n܏Pz(>MT2*$A=QU7y!n?iFFL D?gGЇGʸ(H=(3MtcMSo(#(ypK 6@X8*iħz m3 G336OGP=R`N%n^dH2Ho)L(,BִX6^(Һ(d6 [)_'.vm xG/Pf)B ֣ )ft3GP0Rʂ]?+"笩 Ց r5|(P`f@ځpյQ:5G(x{E7PVCA=/iq5ΌVMY~V;ƞ<GxzA &z:zHA [x/Uјo8XvnYAh˲ ] n@G%7^yr)F!2|LYծ7o֩b߽|`mUm 9߳|?-._#l YO2^C""?G75c&*p RiiqQڊja@G'I1~{# OtguS#|%)ߤ |M}4x+\MT7i?ff*o@$ ˱ ŧ>,Ŏ("9 ]G[1fi]EрY<:P<P}`0#Aݤe&'nO?Hq$ýI }^a) <bSAu(~ @6 m*Os)NXCܧioejMJ[2&4yk dL{GQ,9gM(V ۅZ$#dH!o'G(T{q L]"[.1B)EVp ++h2pzWU5y 6,7f<ߨjTRSUR` %6/[hE)LϘYCt*4ҦKy=jE4C\䰅AK`a;/`߽r}?p φL5*䉞M;DKEl8e{iZsb'ٿn/Y;-%ԚTBIQ=#U шM!ne/-.!0BonO)TQ%Ba.ґKw}7 K9rY.|ڢK'0 )ުhƩZNIT!N^ _BbisR4Uߣi}Ȁ'uZd=_eBp_ȱ{^tY~ONQPT{ /86MصY 7`ӊFi+@Ma"/hb˗Q=YфA:`'I(N3;}&'KS&edPlkPir mub)^?q,:q6(L+0S1hkF !W<&40r6Pmp@ltܬCa @38dAc]%螝`aF~A<> B o#D!o TeQXΓYlDZ8Km S|yWFI__#Od3FٌJ2Agıa_&8,E X0ۡXw6{Ǭ, SJa"X >AQA2Y.iY62^xnYc@a B}BYb"(=7tՂ_H~(p{74<歎iZ>K&m$ZpUvv~Өpc DbQ2) avŧ<*Xn2 05?w+74n7Zg\d Ỹ@oj Mf8?$Jɪ\,UU룽6ۏSZas[ Ѩ$<7G&, di#[Hzz&6m(襖-f`bN3̀{nS QLv:]<6ޥF,'BBikg]#<:;cy-6FY> !{wUȹC/,) !.~緣TH?PH_ 84DPcNɸ7w fר~Xaq\U* &dԩ/A+̲߭c:v.~XAk?eDʴ¥4UQ0mˬ=[ܨJƵߎΒ9ᦂh״pmVɄh:k{즢-ˣ 1v\^C 5`¯ppLb]ΰH\݆94[Ӹ⢜ U*KЍ_&J3 qq1p9gȄr0{3HiʈuqmLx)ePGi?[, \6 |*l+.8!?TPG\R7yI'{Y׫bT}m# Dx+<'APD.! fo!!< u~dB܀TS֯Өh;y蒉\*< 8ǜ( `4mzVt<0ؠQҼ axAl)pO0-fzǴY[p8yzTmoB " <{x(JqՔ\j=hIt6,cmc]9Nq/4nEu9t:-1Bl 4sQw|FRG/QGJ"ӧTXۤρl`hM3DiS@Zxo_{^_َ0o^WTMZb4q2^%Ō]g%"辤ˢ\sAgfv6NGX `q4g, 9rG~Xߘ9pp P `($u\y.?Þ$Ҫƒѥ{- )b)T2#H65-6ouM"s*vfms'MW'3:t˶G(6iO{rjlEPE*3?sG{.Bwt']{^f_a=[MC$؈n!ĵY Y2D) rg7!tTL66q%FԴ33l]G//{ɋ8bX}:pѡ7 #a]RCMt%V8«wl"$rUx[ C5Q9SVYur1~|kuLGV %FnWyZN}ڰKu#cMp Xs6Q^qM(eH[$GӰa>^`ڪRʠ]o`tD(J tfWB'ʸ&#ܖJ7u^q*@PBX:ǎ\J̇q OpK&,AXf YL+I|SDՑvAX BZ6i#|dy Ϯ9`Xh22o6NlaU19"1I`׊y#Cț:2 |.EMl X<78x!be0nxXlD`@] ;4$Mgpxqg\/;=`[x޾ZbmMvLzx.5"V8R ^9^F* hyU:ⱢNec,8"N)wȭBbBALi5w|!Fh2=FT̷V0ƔġxJ{sZss{|ؿ >zrB7y}!>ϾʋW]Qw7җ=]eYRuidIe_ƅ YDye;AY\.߽W\?_("v yUKo\x9OɅW}cOxŅٛM.Sx4mR5pݻxN7`]eūgVS,Tȓ 4yڕiQdSߖ/>E "(ޣ΅ dB&MfeT wBBʨ{ʧ44a` !@ 횦' G!|s]s aItrGή TFm"#r>>*B @wt|.|BH "(>"(YH$P>S@#Mg+j! .EהurY:U( .ׯ #/?uiE <G#U!.*0DeCyzS}VBR0L3Pap ܵBpi.r J!0 bM 4B Mi~@BU`)>BG3g}4+4mgl!P߰VN bxOEWGoDY0`x0ܱb(G- cT[!{s 4Q9z3i›PFw )@x !QJe̢Ͷk ~fGEjA%uZ!SA~1 ʟ  pgf#sہ4FaZg`qU%} x&Fm,)3@S)jr.N)~B<"-B !CPx;4_ $; FnLԌ; E#cJst*|@!@;' =`t?1(WWQ{Pa2d)eVdմBBE>2]mR6U0G!=cWB((ˮr,LHAĂH6Lx(pi'/-'oWY1.*.odJ>ަ7PBHY!.EvYSJlD?ؘgG@v *&İf [rx0 Zipu#rE$Pxe!%̣Gs:`npa~-xf"E{iEH.R7[Dd*yȼע8Gsū?;OHЀ`@= ]w9 u]4ЎBUYȫT #g|7io•ˎ7B[tQyZv_c1`ȺVI<#"Fc6Ghw$[ X!@y \g .~[P/-5i /nJAZPH]du1)pR)<,$:f<a,D; Ͼۂ si]gRHhk=1$5f[(NERSy 4Kl0^N"`@%y; L$•0 dcw~Fgh %mK`a,kY8pNOLC"B"ДMP!}F溕 Bӑ.TnA װ4&9(-ZE*㵝cL('9D{Y} U[]eBQ{QdyP!Rdcn]x <{ۄRMA&]$PEDD&bSbȢbJ?ô4` ".Cг BOSSj>`iHͺM`\Q ]KA}0 >a~yڊA@}y6mצySOAp|q_.ǂ(=^mCDW5twR[[hc+r8$/IXF(Kę\P:P<]DANk2j`"_DLDqL6p>B4 l>o]fAI.6XDRD+톅Ki6^Di*#p5{R+#B4XQ/ 6! %j(! 6&C*eI)T狆`c+YކpkW" 4ef;Clm/]Uq@PmĹՔ6w#66#a'ZdA6n;^yKa'|L(>|"6;H^@UHgHƚʺT06LSa܈VHG!/jʴ dtCק}o/]x [B b3ZÆl㬅4 -8F]S'pL N0pʲb=ouGv֨ &-ؑZI.&t@#W8SP[ٷX ؽVr ºQɎ!H <9Xid-]-w6":6X ,c9AhA0D4M>6-1ԥ4P(EdqĄA_F&(#EU1ީqQ_,ʶIEM*FZܽmbLjL&eyg{g=Yΰ+ɥB5B)T&)u507O\@x}5IRDg1hZĂ0'- 覦 )רeN[l#.8 ^E( !@צ; Fwٳ"Ѹw9n a8m3`y6A(QEx^#>"bh\¯YE,oi%&yM1?H.W>Z! g8d;d+Mc9QXxPTI`#SlA܅(L66z ׭-aad%M`\*]ױ`Fg/tliKŽ@Ѣ|E@tїO4[YiP`CpeL|`I+"wEbN uqsǙ\?d-0ܼa%B^ J]ʐoUXޙMW|MqzQܶC#?wėU٭_:"` j Xk""8}ϔn:=K@xdpKG̋\GK##J FؘNDD@壏im6$ ER,m+˛&hqJXeP'tc"jJf ׋-©"#Hie5^xvk3>kpƢ܎Op=qݛ~fy5& |i+J.3Bxw=;/&.X!`! i! 3(A'GgiKu/gj=4 +psSS5#V>ڈEb?V,,zbѵPR 9ծ:EƓB@hxJ$;ZKz`a#-v·Ȓʻ)1I C%FM62ٍcvJ+ iIM(MBR#^'gRcy+Xpŧ$F(Q<)DXZg&$"Bٴ]~qǢBECF{BVM/acY!D%aցxDJ'G^ =uTu[Sac i`ȾlG9wߘbSLV*k]Jn4;h^Pac4 Yscv2?0aЖD}l1o4M1S 3߿ 0b>wQYۢi 1nrEL`l`UG2q g"O `\?yRGsV7I.&LΚRT&V`)j{p6b]Nؔj&ڨs9oW1gxJi+Wi"؜W³/Zіy |#‘{߲qsD(018.%wd$ygY)L:-z0c踡jͲJZR++Q/yM6=n yp֧Hud4D4+N.ymi##d$ٱ\pFwp{}g+kF:W߿EœVUlBleVQt.I¢D#\BGȃi󋒇MgRLچz6Iu0bh pυ\&Qvct?3f2h+ LfDb,6A!4h2kR;ڑЂa>&0y B`$a5RSBo}{F'۫_\lg]z;q$ahr$\>LTVH I3?7H_ .640ܜA] E7NŸfiD 8^!|CNl*ꢐӐFj3꣒65lR݋Q@N n۪ͻ*oӝ#"3HQ቉N\SP%U5yvUTП>Q?niV-m4J_pϔWŝﰦWP! ]R̯RE;Y <54dIRT[wdJ]1O*$9Zב`nvb#i!ff?,vᯱB@uצE!`WjM$7z!CIڶe MJ`2C\K$*mjH%3#MH 17]0GEYY#wiY :+ʔXS*-UOi&GmS]yCv2 DKrMGg2  ½wG/Z 4RCT:=w-`~f*,H!C _;|###߼Ʊd/:7G xmȼL5!xqhm%ʀg )9-ZVFbJjRliA^'èO'nzdBba| 3+;X x&X Ht}-2 Z[R^-eZgvo\BSA 9&6FH#[o˽f;k]X#/pڴ h\pهlo% t^ -$u, ^0X޶(:Fp@2|U |﹈{O!ض/J+F#o\ཚhjw2莽m;aӽБ€1ގ6`˺L ^DEH9NQyYk.mH3.+~TSF.w'?S.R¯9κiGN XD^{T[IsG# ۦ BWn36 2[!“O[YŽw !ۿ™E ~=+wm,h30搜łDaNx$Q_axu~&R!g)& ګ?T d"$EwN8$.,(ˤ@5/7gBB \M73"or.fŊout.wA$Dp6 ꦥ / Hc[B-!Gn"$UlhteAxXXՈ%< \U Eh_?x(ԑE)+`HLB0AeȋL/#u7ſNbB1NW}h7aNlߗ JljRa#\bgSIFk[ک`h'ԟ6"y>fņxp-xLi >MHU \lcK"F9р#clCZvQ" />+/Hޙ6Uؾ)Qw/Cybp)u5/% 4m`3fx>* J`,&v o [`r9i⢃50|A%mO\|ͬT6>Z`l>A<ih#', jof71?6AHZM*@:hA-H,V5qJ _e2̑C(U+3O4 S-0Y7ec%77a<0BtpbBHp 'ʲ&2o䙆~ER.)L;&2 <#-;9ع?I߁gkr`Bv^`qf66oi$RUQ2_Pb.Bb6xO)ȱ\2wRoT1e,H?;oWkCB۾96jײ zܱDr[dG^k,UH|Ǜ'!.y=/$[S&uaQ.m=}{@D;{Q!nGm(Ȼhϰz6ڣMGl,h@icfoGaNqG'NmNs!D^> d1f2WR'%H3m[GM=FSg<ޜ$c)KK D#0<{Gt( tYe\{j8SKD!1t0\xBwE&M>#kBnπpa3\4;2A*#T.[uC}>DUx k0A[/㪂ZKp.{T<˓YT%ckh=}a;/BDY=HfBnpr\$Ї |q܇}?$'("aכ0rVandɿ){ i>Em2θO_DyO[!Q "iz3OM!4fD_g?e Ι0e|OQl~{w̕/Hoólܼ:Q`CXB8"9FҗSR[a`_yy1lt"0&+Sd:Jp ^Gtm.HA,]柹u%o R?;2 dղWGF=y:oCX!,ȹlK!X"EC —i^xVxJ#7i z>X`n$;:`O|=" nti~F \Ȭq< 48](`E LqK_3_fԂah>^kPk䔖+*Y8=u8 ǎJ[|pC|rÏs ^U!x&Li7YQ45,o8ѝ+WlZGav!?u:M?ٯY$At춭H3AjWrM(Vɹy w6AIv(Q_8ܹ}}ex%1Z;2IZL{k&Tg#ƋγG_+Ft5E^veLi eyS3 Vq27'"1GƏ'݄j-- ,<{ͳ3GIVtMZ8AbS׶ 3UL9-nf՝ hX"i㼖BC_xb:~ S?dx~hI UZ~֟D>]{‡-]N lZ(1-~a_T=UIo0go6[=a0`!|^"bUg;.Rzk sU7iTҟbKuNosZ&--6 8!!xFQp-6@bm+FװH7ǚSKGT{|v>9o@άp@ "61ҷs hp|THbY5*hS2K6Yۛ!x< =[\NѠGvD\x[)mS0|<2*F ?(aY5Vld M``b>d,tJgvq퍚P;ֽBMS!hh܌:&f Ǻ&BEt%E1I 7 +;CP›Xakx(fennbW ƎDXFfw}!9QK]vE}6Wkl6IFݛL6{ SLr|R/JY0h6} -Ty0_OC 38*f+zrɏMӀIHҎF+uFѱ;3>kB0Ϛ C%#Ab4y(*߬)q0h {?l_"6Щ9rłPUN~ͣŵhj$ţ<1bh !YZ~g?BCf6}keY]ߝ"M{v~1/S g䙀M _qcD%Q!y33@ჩʪB!3_k9k}0s>O[{q͵X<<<&IpTE}-zᵗ.( :⬪<5Ykkw6Ow#ڶi%gY'Rkk/yB, ^ 7^vEkO.@p $J먨.,G 8!eo3B){)6x]ŸkkޣBT1(8"| %,~Y 3x*" "*+=6]ׂ"~@N@(Y+P{>uVGX8X[{wyF- EQ^'aTzT|0 ķ np>#cSm tُ{`8mj1B(,*IGo_ķfn(!X^n~{Hdó!:$io>erxrY#ۛG]4Uޙ(I= o³c#P EYI#<ϳ ;YE@ 5\0'ѭUxA]N~DE[NV-ߐVpnKd9g?F@ Ԙ[ Q2I=Ct*ܖHjjDH*y~7e}2+o_Qr7ѓ%&o)Bqΐd {vQT<韀dSE8^AB 8>C:=} ¯|Q0P8H*͝=HL3M;`㵟P#JM"O/B=謋Z tltG٫uҌ ).snUPBU@_]t5l@c:wB" x`A7k]  Cώ"# E%"9 N$*joz:}7¿AUQU"I`̸ -M-a(ALsJ)I ID}{dm9|w![R܈^l+]^+ IwT#ҁ2Yne;!BI+4Ф&n'B#x~\Pfi ڵc. utC @\ہqP&v%߀g@]Ji4hpBDf6F"|@ȵ)$x,TA q\_Ih\_[A bΤ BU@Vi>\d|﹀hXLQlAp{:?J9Y`Y"xݏ `኎aR5 磖6O{lA9GoX?g:DF9>?g < ; ar#ΐH>C2Ɣ4@g tK!ĕSrVoE!Vj|T Wc#<봊EpNOd΅ /[;qv<9koLa?wز9{_ ]ȓ_OoT7kD?}TQ:$,/Ya;J d<_ 1BiJt)_h'~WZ}6WdYWy!04_*NΉ-Bxp9Mtaz<ƙ}m:ЭIDu^Ta4a&rx߯Cq w /!x1|%t:0k)=l TR`3ƃZ#0|ŞoM&[&,:#B_mʱ*X? *"8c dI4 'zcߥ AY7L SGJ|4!a_g(LWH #Gn<@UeG? &ZhaE/c?Ю8S|\c3JcӤ4)acFBrzE>I%̷cnJD(8wAЗYKU*a. iUDu4Fv>|nc3,.p>n/\rU8*j %I0_R]kXIɨp|lSFdib 7s>)A i0hDs $)&wMRlQIq*L|;\鹕>/𐎏7Bi¢Sq|q>%9q6nX4|yE CPa 0KH8*gTE>,2"B!%@. .Q[A7l/o>*]v4yF&R1{pewwU mY>%ކ3= pg1\ Ԗףl)lIU#4}s:ʟB;ÀCaġbF‚}6: Cm |ԲPU%IDOTe:IHH*K]i0<9ݿe_=gWx.qvDzv …:>zH3`U8QOvLժV'0Uuepv`A:c fl}n+eT#aTaAR0I/H#ؿPX c1(p0KG^޳]dZ.+MwwMl;mH%6,hA6:-30<24S苒 v -ĥBUZEN 7u{";B`-Uǣkl_Pn  KllWvGcgǰw <μ<&|QF1g T0-Flúhw g1۩"-&ʈu*ʀ볼*&T=ߣFg!ZQF,ʅU[ߖD Bɲ9C&S!W od=e"'/UE++=ÌP>)"ѽ,?ї$|_R#HYmx, `fb09%%Im%v9c:UJ8l|UAG-& Ў #QU"% .惉YGL":"k`"ƢBFh`"g֮zٮK'Tv>A] i EÖ#8 _4Sb"$mZIdO%n?2xB8) i$RHUa;Ƕ:%׆}h,g~Y" ش8#$*j*.{Fuo,`_Q4mJERY$`:lsDdئM|g&zL[u;Wmڈ iZW%<mdd"2`#ÝJH6fs l_;1'CX$2*l1V؊RDM~g.'{0LFmuaE bVl˜AxX7ǺRѳ3ʄ(h y{r0 h(mVF*!,=?hw x69& qC蜍A:ddJ$CCy]$e1>M˵]C9R PR4ۢ)BfTF4 ,nTwwk6b%C#C¼ ,pb!FUDXͻMV`~Klcy1%#l^> ˲F!`9bŴ,"TuIJ/uB2Q< @!!l,p@ZPMNNCU81T)ԑC甩h)HF?#sVTصIW QӨW^9yWeY1A(YY"7ݩB7n A Im/ڵZW t7;DgaRߐ؄gGڡ\v&=RB`kĒNY1syzުn^@m$,ޝ>7| ߐD o24GbYa὎0 >"<;Lvj[U N|T)\=R/5 hw7T%lzx/)XPFG>pQ"S5 Ĵ <-\{oJl ]V 7^yQn&`I١`y f&JlVA : [=jsSA0t<.d%BY#|_&;xp~Qg#eVS1)۷n;%\%?k"Yf:aR2@ 9+5شen:߆CG,N*N*-z͜sn]Le %k`q_]f z"3"ţ6CrFK]`sZQʨ>8F$BVY!JT0lniӣ@Q޿Ԭ:tB:GFbְT8xzY]$-[,tY -(8u4xZ:y$:tLvL$-5&e!t v°H OBil*|,NqZ$ FEszkP6=Z\N(O\pʎMxض`$ݜKXA{v2%Z,jfst#1k*r_l^X;άa2K` !`S0_2/޿ef嫩D^kbw:UtF|d3̆O7 2>3Ҷ>De2Gu(/EL5 <\אd p.0q!vBX4gcwiM3./!C!/=神 l~4xA;,_3&|5ܶԆo)"ѩlp9VDfmVb=QpMz[1 Բ!nkI:Nz~ueO%i} t4x^)8 i&]g S<#A# i2*f(KeUBM TT}f. <)>±(*blA rloi3 4Y6DxTj@vnR 7=ۆ@s&:xfmvOEu)\!|ABTF5͸EIu wM>R]4ǷF('a=7> p反\[p(GG6|ɬ=@zJ-`FSY0 bc~vc( k>¼+1o& B?|( s ؊bS.8XOs [Eڃǘ>ǹ!aؚEI]FU3*Jbue Tl r,nz?Fg]mi,%)ݲ .Xoy&d>$.'tx[lC-?mqK["?k*;!TcIFr} uA&Eةka͑es S퍪TB:DbYfo!`_qYk[e$LƩdJF_1 ^Xv+EEX^c4 q:mRe2?8/@ 11Vi _ R%ITe*]}掣8[yۊ\k I(OI`srllPiGi( ^t(u>uDsdVMuJ@Ѭ=_غ|t$qRQ*(X趇 oN0kG ";F(STq?B;Z "\SWQ8 D]s͒†8w5ϕg{tENPGQYVJ m"2L5 Ybb&>>>WExZAX8WDS,|ҹJM#O[DJi!`(L?Sd"(s}M+0:>]5&eD^p˫4f"C=\$~Y5NZHLmC$#*8 #LDx|<]XsaYHm퍦,6 G0AQ0aJu* =$(¬DlW`xSQPzƚF?(q灹B Äe6Aak-`4}R + UVY{hd])ft@Ʃ a#n*K^FG1^#*$Ds#ܡM^3Ļvtts9i}qqUU.K|mK~A`1eDzl;e~Aŗ4.m ^R KB)/F;+HU,j֊/o7Nx|ET(e"# @% 7;5X-dY(b 4jlNOMf%lt? E3C,,PB5S! z]xzp4_YKeK"#B0SGk|)\*˰>RB0Mv=1".V,;t},R-og6&%,*D ZxVU%B*EYDO~[Osv)K &6TpxrG,']#f TG!8g F?ws@wk{"xK|֨ѠHDŶ-oݱMu-Ng- ˺ vټ6jVۙ~A aĦ."O UAk-NXN8!C]/$MAE]ZNFsէAїٓZy T;l6[j-4nxe!wYGY 4n\0!HA4p`v-]m_2<1w:wqmqٵ\)Ee6 TH SyK/ā"ýH>9kB8ߋx6ɠF oՒ€fA6o8ũHd%qL[]#TlgY?!wR;<{BK%-diD[yV5ޟ<)RV[H0NGKqFiVMUAc=BfNIA\AX*ᔺow؁p;z{T엩!M%^ʋH4.C'S:hh;*h C K4[:y)[$8ą*5^L> z 1VR?>Rn,8aKG5*Xgk߲wE!2vMߣ{G b0$S膢0za4*3UB&xǽ ^S.Ou:]M] ~RYx5[E&l3nHZr61 ڷm{6pϫێmSsg1=({˞< #dBN\uq A\bM~nQC"<rmC8-Tjz_dD~Yz0X "M0\GlxaS;ǜD0l'%dz- cnX7&|<+W(w|4ѯ[8Dp[cn9ı-ba4ˆP1̋yia"EF [BM#̞'t"m;p g˂Ԫ qszO_G4^e >F)4PRyAi*Fi7I+!0)gbfb)[9iQu;ҾEٸ}yb;[(r4󀷼ɞj`RkuD'bi$f%1]~{q/P߳`V82)f/֚wqUcw].c`wlbYww*q4S#J?h |뿡ܦp,Z\:E.h]?0>q.Gв=6!ӛwJ/m8RDLAE:p jzV.eR#pqO/MDjGsGrOHEeʤh2kp|mBq{6=%˫E:?Fw UHW2SޙP[Zެ bNq2.p~h15H,(n>3Q[8,E)eG:CK+6l^X]K@?"1_5S<\O]6@>5t>c#xSU# HKx.ʊeY1fB{{D>/2+M+HZ^\>3zBC5}keY}ם Awz~׉VVY{4!!8` &R /iVcx$c2Q ƱDi_BXJO Rُg{}{7UO+w;|;;?}/k^/Jڼj/%?9mݦYumSUk{ۻػ“{품АF4dwGa.YD ]EKFQD#OG}v?CEbK?|W@.|?(zDx.[d9F5U n!%Ρ9uf A Rn"k5I𠅏ߊ!$BM.oEL㟨8%Ӱ ^d&B i޴iY&BLf!&q2%# `"̠b_԰K6Jd4Qy#!\>o^3O )*lK_-DHbxHLFvRIJ 2[ C0VF/HqREi'v`x`!("QcglB ֠T 0'^2 QREhtг \"qE++Oswd Iiu! |/ /}xь:!n.ޤ!³Y|4/ʬ(%y '4mp]x >lAUyy;+b4p ʜAp`P"Y NEUBI):z~:J4Kq $Jm Awgo".r2Td2RBF}Ʒ8^a5@bp 9: yR!(Ou$j'2[k=0֝(|>zmqB F̚-F$̻}dr)6y6/ζfD0b*gt90I`;>z=`m((.Q+YUOAH !@|>z&Xgপ *C (*Z~sAs9dHAY #;d %ips5NˬA4@CFPDQ"BJ jZ. ğO_Paϱ$. )i{ؽW`)"hJ;Gp/BQH x3飺x"2(, 8!t*8:"ók$I۬;)GNMu$<ߪPӴnp "H%,]06"<*O4k")w"6t5(;}]#h~ȚPeIMAH2/PP-h p;<{x A a fE> #z!uB]@YHF}5`OAIF1j[ B6C V4yR,U%2Ks !eC 3:B)uB'4{S 4p~! L]!46\lFCxL!xj+-,&n*aUs;*8)ih_ns5ص( Y ( a^\H~Qdނ;B' fX *daht@O )속8'kY%nkM]$mѠT&fMe* /{ ڮRW5p?<{G-1D2׵ wyЬե")s*NMk 2D B2:ڽ{cf=- lAzN>+_]+> Owwv RY(Pe&dY7< L쾈ńH DpK- u:KS-tHPejPy') kdX.wD ;|၁i3,`J;J e!;*kHn/ 6HïY!*,,z `@=JTejwkᛶ!lG,pĢaWsrOUpMok)|aT΋7;ۮ{D^@3nf`s~+_.J1$,UJF40l-,'e۔i6M lSUvx"jZTj-"qS!˨u'V)dTEދUT&w5݉- ̍v8W`@I}gTL4&t[|`ZH̘Eւ*g_LtqwK |8+_D+~O#̷_Jdp!!Owu;Na61c.vvƪ$YܖtLD5B_/B#8 P[B="4x^7j2r69rB›e,0O*H1.ǫZ rUW S' . UTmI>m ȯZ!j:# Mː<_zкʲ@Q璀ˁ&yT`{.wANe<)r,<Ԩх XK|ТQHÈ3؇/ $|Z 𖑺*6ot i*.zh) 7gt4lJI6Q"a-׼b"RAeQFиYjlb-TR,KF2g _m+y$+##lO(xt04"pN <t{@/mUBS^N1'ʷB) a]#u?vڶ3Рih ;"2q1"D#FD/6/c=nž*漙vˆ.//>%kS;q FoZjƷ-`T# E+׺G_؅LTiL-휇HfԤ^:QيEb9A3MYMHnɗ>!S>Mo7$o̽vb "^xKɬ<\, m:;=/p N*XE7$Ne[<w##zHP (ʓ|aZnsՔi0("=14XՒX0 YqR1byZ髆e4Gm"VwD|_G iJhlx(<`5pR91 ƆOF p$ 9g lP-vvT#z.4GyU.) )UR"cZu*˝Z1ؿzyS7$®[%!)ĝ+l@K"f BV{(Tkyģd8{fې*Ɩ6-ӕyI lF`{j:9C6B( .p|Le!qw]7@I€c rO\z䑐yO6{ƕ a9q3#/8Dx М St7{t4e+_ڙiƹWuĄ<߳<7U(|mUR [`VXX>OYe[j8Ff -'k9ӑב Z q!u󜸢ѡ-}pż4k`_Pn5k$\Y2ZoonGFk,{QHӴl]0"x5vڐx yNHe[Dki" /,,1_zgvaA7,Eܵ6*+o ,*ߋt: >?eSH1ef$c Z* @aN>e%kהeUYQe3 ~C7yAdFcL]ԍn@2Vs4|rӐI;$jM/{<|܅G!"d} /(;0'sXI%VVW0xܯZ̑lBR75n?Է `Mf`\/:ںE]i˼|r%T&] *!b9פyXIAorp#UrrfϘ0yq:]#u`Buz9P!( Læ16ך`w`q6 )np yaGog?k: vA2w.f>k!3|]pbhi\kES/\0Uϗ7I\mV:)%!YMPꝿ-A0wy" -ۜF≻ric|~.y, \q&[mv8)  +FKwGB2X^/bQQmQ! W͆L)dB74󪢬!Wxga9Xޅs,و#`ruml#HN cK".&"@ .ՎP&NfX(!=I!XХ\q?96D6iҦgN%ͺ[wQE0Tvzknv|}Ge\Gдe֜KJT4؜p|N-Ӹ+H's3F7 A%O9&wo?[ÑO{'-BV<ģ9IN@O5S^m T7CCN\>Kչ:B`q˟J0TUu g$Zv.I֙WsLE&M,sz<1Ȧ&sYj;8WmRIJED{+},N3~ߺPII4hO,D!%,lQ~#h7 jr_ CUYAWskJ6{3s ې rY5mXH75kfGʤ'/)J*0TlCldNmYHjF8*f[QO6@7G;ak:vB\D$M2W&f`ڜ㖓D0qanFWHK6߂65DNQ|@O%Ix&!Ip){AS,GWwdD7~Uh"|`l6LGQˠo>m*/  :O' 8tBo iFb;8+u ~jpi\^c3BX{kKV{XY$֩eEsg/J짭{Aq |JLNG  &TpP_2"jf=#[.AF{x Dx*RSfx} '|w4*Flo2g9ڜ7vrnDosFhxm!(Z6 > _?oDmBPGL u67fPm|&ໆx>䟁sՅ,Sfꔧd.X̭m3FnܩE:X j0c#$؜:ݔ|P]yVl~ pzRG:6&GR)#6cDy:||,U]JmD8ђW]*T=I@j۽] u$P9Kh+̅ӧc?>2aՒ"AZsmϰ, }HX۩jQM!48=G7>hlA`/M+,gAó,3 ,L*I֕6ۍ΄o.bU\"?9N,D|EdpWl06lS0{QxTA zҋ<?>|G>pTp|< A(µy#c{Q ai>o-zLx|;>󘴐>(j^h!. G%pJ"fwi 6h'u*ڜe*R ;ѲR+A;r\6/ |ı 0Y6m%FǑf,Lx&"0 VGOwSsYQF/?* qC90!aoHpxYs/W: $Ng ߘ͸D q9UhPn3 yN$A P _僅|y^]ħ*{mTmu6 ?r0teqŽ~)ZwQEǩ#ZkK`#,e3HuΛ=ca"^'XS }EFU؇qvҬ ‡mڈ㹯8rA(L`ʚz /U Qjl}%[̀D.uOUtRtώ8p 'E>*S |Uxq9 ,!<&=.NW=*xQaҌdswVJ.i;S;W6#;A'Q奾*s9=ރ0^ac>Ku˺-#= \a[C=fgG :*{:u?nMmEfr) lzcAoә oFkh9sDnB7͎ 90g~&W`f4t1fM5 Sbf}#\ xx=A8[6@+iOـ>q VpJ66N|#}ryuӏ=gxaᆋk Ag˿|ұ,Zuuey! !\ 5\ Ӓ"u. AYu_nH ʗ%IVmդ 2 Q*?-kGttyq6uB sϙ($UL4MmԪׄ8ħ>NQ4I:f6FY})I6$ŏY;qx|~iɥd(3s,\ Ι!8a? /n{arΟBw<::p/~Ú_3Q[q,=j1B1vFTx`3?pulnSomd4WwJI8qbjSvNÙY9j1)#gw6\ ;)(* X6@0Fbs\2"OUNLy5PM³X7:AB:ơ: 3&URH lp3ql7ipxUj(߃A);q.e %(X 7QG{@gSM4yO)԰_A"qT;2֚2-4Q䤲leA#6v@L!#I04φw^']rTX!QK;\4*oGv{{ -$1FMwFj8>UkՓaEܖ;N"Ujg8ݵ)fɭ2-B0MN;噻x(8ڌUw#Z ;+]6q{߷@ES $KB@:Ѧ^nKhp,`-;6 BQ .8v+TU? B~^;t-|c.E@'惄?jH'$X!Ri)p}]MlH-"yio0,fbUgS娔bo :+DeeRlt2 4iˤ+#,W׿5Lt}P Q:4 |pBmEB̬f[CZ}JsW \r !sV"A(T Cd!s*&fA,%B!‡L3 7jVٵC6,XTu$,DnE` u؄#6P1։ 4 q\]C|p1DcNO*6&~5e[Bn q\!-RhHel%[h!Ҹ LU+U9 eR[[RcR X+lMNA|`t6lDrS6'i⬙Fw5?ʳs JBC4}keY]eHp{}k$~Jv7P &`@$tWXfTH`FcRqg` U, FRJQ(C~\9ҷo}{}rckKڦ?l[3< , xD à "S5uCϲ}H)(tk?en+26QTi۳#cY۶n$G}FӾDCh;@$B\E|GeNQuVMSaGEG7>~ANGI dEpӴ8''͋7훋cEg˲do0x]j~%BE5y( 35ӴL8-L@[k]lm][,g4wԟU!<9"µUEAREa,,ApyWP ~nP/= Gg$8?##Cٯ˭`fEJH(zjeNznK@_ȐeiQIPr6:r挿:KTHm02 */x8t]]7Y:^-Auj2u`oK)/QS#q]@qM"A(I$㒣8:4wkA{RVk#L&'@Vx4U$ ̤-w (LwըG1JLGd{,#Y%AM@z KG @\6oaE"POyJLT XtDhRZO(Ԭ̫"a@`\:`p!@4EE|c> ~\kfiV%E3C!]^X@׽hp`( hR!@O5 \!X tcH|*B@S44/\ n:TvDZ>j%o"f /xI qdj`\JФ`ۦ >ʾCb&sA|&:wm3uLeK8hڷtU _SP</]坛7i:7~cCYx1v1|<Ӡ-CR2YpڴN4v,PGia^Wgr0]{10攺H9w8!sF(_9~ԑmυ—ٿUa<')/dD7t ˺i=_P[BZ%I/AZЂF7`=Y ۇ?&#eÂ;]28>>;wp*]%i:2"1[ص[Q4UZ H%C`fz~4 Yz]݋{uK7Q7 E@=U BR:g﫝$hv[uY#W@@i #G>*sR~!<с@|4E{Vf:Cev,ml,wW`<*ʲL!𘒌&0ׁdp]BIS ˠ}S>/N `Pq\eQ|knMso.W l)Lƃ@e#u*O5Hg.!N+lጂ2B0*P2 p[Ƨvߡ!=Sˏ~He1L<;3/3 42X< [cN 蠪!xwa$Eu:? Ø_չՁ0/sP g #{/Z"|U!!,O&%A ֡33IE?blK qNCleYSؑ кDKry[lmӵ_ٹsrrd؅]yrs{3>T܁R\TI#L ]%^[ۮӼS2[Nmńb^c}-xzj(8Jh`z`mw%~Xyb)rMKRAFI $ PLi n\F*~2 [CSg7RaWQ,K jD9x E!\zn&Dxfr 8 ],kˌd\da4C&l}h^ "`sA BG4's 1 _i7\vYJ)ϦPf Ȓ`\LaFtY:`ϐz^PD%РꌐJ|4eo0yEr}YH̔qXfΓAIʥMg :$je{#V]irm$E0RKң$f#mC&w#@M![MYa"G0{oh?by'qR=ݰ-:+fDXL<!.]t$^fM8 (A C2e&̻>C ̫].\e&2?*XJC+v&0 8s!E7""K>,fqT%arH` ?"Gڈ,q}:A- *-_ZFꈎtEBrZҺ7vaG9bxuyڑaXGG."ux ( QQ vy5Fb XVwȽ¬+oVBTEFOsi?,jiqcQcy hɿtZ5 &\) HePW5 `K0Ksqr#\9P79>@,?zΞ8zaGSP.<..xozNg;PMwimַu}a P tiFbzgf0mHo/w)R[ȳz$йxs xΡBx@b9s% n{(dDLY ?  '^|xݳeUeƑcg "~2,pU'E@z}"ĢfPcqF$yD:@6ghnQ6;!])p#lD3z4-V\d#Bʶ|/ 7q:z1N֩<&y|$0-ڻXʲU<{r.?- /Ґ( 8_K@70w<#L\"#Z=@ Wih[C" 8rl{m ti0WZ-CsqWYp6W8wH#3usyf1/CXC\cƼ=JNwA&O'eMe3X7{_!΅0ʸ(X mK Y­a[vx˺a6W#IHi>8-SPW@ :$h+ތm:: c+ Ю i]6 rD*U3yOz<j!p/<{Rn2Bٿmg[ox'<DێlB0W!dRP*T~ QaոiCk^ ܀TXG <{Fs.$ CK `#lss\fʪ0j&6o%LcNIl$5އWh-28y墨l)t{'exK[X:OtO7=#h= r YU8עL"ZWLTγ22 kTjuiS~"o*;KtNFbN)2)q,Fꨅ/T( A*JxJkN- 8"*h/*ڂa_Z}ԩFALe-)n,ꊧ.B Qó7N䃁 3b ”u8A3t !J&?yY cwTf | QvXIYlAf "ixv %-ޕ.06Qf> ,qEʫl2o=s"'؈Z"PQV fOKe:EHٸ#Kԑt._ H4NyyJ`{5nCt"{s;:8E$z'+v p̙nޣݳwfH5:7s, }8o] 㬳 !]iu!!hag|5SBڎT'!bx/(%tTtCQnFuiHEOL9ۃsR8c7k7cl4DS#৖UYN"~˿ݴln[M(ˆӵ 5 q\K^;p%!4{ A\Axr_ܻ<^ y6u6sul}"_^"8` u:͝`- *D,5 z}{imM熿|v^̮r5 yle2۸rFlo&ޓy.u i_|"0-4KYU%]}߶MĻ!IMi{{Ƽ:/4bݩi;O8,>lGT j,<-H f#:^εMI= ~ e f_,K2 *$icUCYS.u25(DL^BC.[I{{@#G.ـ z,k)N/K;ƸZݤg7 Hp Hɞ45x:ӐfT裳ytwG*yh ?۝a֞RaBXo%U•>7.7?8%dDZ P\SeL1R=J`7 w.x"q"[\]_ܔsR^{i&a0},6gpxl,\a$4/ N*6|p^8gVoq|lVp#:L[귧>bM\Ήf% ,KxDeadUI%xm 4BxIUEQ^u HSsQ(̄>- su#E0|sgZLN"LEO\I"Pqi\"!=ʋ$^ қ]6ecGQEk9;e Ĉ9I( 0!D omo]t=;wر#x#*.b3/8%%$.>皚aK{q r>a8>xryM LC6ub_I@I1ByHϛw{70t3sY,hnjqq aa|O A[5Z'ɳ7xWvվL@BGR}Ng:PoskttA))9UE[i0=QP,3iPaV!"mܴh0X7"h襆7o#lT@$ =`4X$QiiYJr[Ak?DDl `*fPMm0t uy$]5ϖepӻ'91cyD!|B|$8(FjQ~| T@xJ nnwloFAm:Q7JIn`Ip Eg:_a85a|@Z5o"f{ oǤB!C0ODNUYO׽%ШH鴈mLUVԂ_`h{{: ={pOEV!lgyVE=<1m^5c;. Cn|q<2\p<F ,Džml-6yXegQe2N:dvEПɖQE}"sGR4UgVڲ6kmA0 /39XI*K, n丯N  Yx ^rzS{R $ TW;S8 m,q|Xo)T)0jk35>-f봰Cgd. Hz; k5\e>e9Z[#aǞW._Zњ cW'8 aP <&\)l)rbvv]Xt W:k]>c]lQ 鬜A/?=pٜsQ5-x)$ ǝٴLv"te·f?hjC9":w-v#Q@1k!@ OClY6"7[C`uVuOpfS@'F"x4UR6,ZFSBwLr%zx L\T۟DW{v>'p`%%Le%8͹Ʃ;N! ǎMurCbpG |f6+~wo" y.[mcYo]ת:7lr5fBwu޻͖P Re,+*tKR]]aZ!R}ԤT B$)B7B\zCkt𴾵g(m 9ԑ Zg3tXb{g:ZλgڞvglpyJuWbv4Y"kk9{*S7iHi}{2L30V#Mksr!+֮&E߻a |tu/E+Yp=Ȧ>]_pG,X/gJ;H"'C ~6sÆU9o唈`ZbkWo]9{w|RBG^jRlCත`e T#W{R1n޹Oi ZQBFZyG*7w|pmZf9H!|A`ŏ) +2:"ͥ6m_ұBqU|{XN/z2Ik@Q HBo<$4d$u>21Bj*$ÄjDmFC \X I*IyxM*g|{>z@mal9%,l'0i.~OBa(# EQopZqݖ{~:i"7! fWyTeo@4h^ gW9[FP`Ϥk 906Sl±M h!H9^ >e IISWX9Ұr%—D+r.HYGR8[.$|\ϒ.M㭝}/ 6M`ETi\-etyJ|ϿHaVbE I a[iǢj!gBi%_paQc">CrU4,<vK;xc")k#vaYQJxk^p\:Ậaeÿf$U%T!tEgh%fs S@ Xg)Rsr vJ"hkY[ÿ}cZ`/B8b;{u.ڑ;l+ Ìhι < +M٨kS Rx%KD 4ѓ.K̅zms~ۗD0̘@PFA-D:$8'Y@\$/NO@jG:ۿSZmR yl~Fq&V2X}hdWb I d0o)SXgNA¿ 9MtM@[/bp3+*+T9yvn_]lT 1v-)ƑD kSblpKQ \5[}E QU2|,W00K/%LjǰqAF}*XDO-;!g<Б#[Gih +)V#wҽGHǘ>gu .6!w ~``a5rBY$j̺=gWmnˊst " 'l#jA_V![SaTqT]:B6 v٦Dlԧ< ,y/Y75a"'ڦgfuZGQ +D&stFkz\1ַ_ (L68Z3@ܨ.,}`~I>BI Vs-M)c>Ui@ R^؝$\EQu;g8"g -~Ey8CsZ6mm$]Zfԝ}ˬ0 4H!omEkdQjIW}lQl q6TeĚE±}㏿X({PN}%UR5>|k%4P܀+ˣo9;1+P?@@Ae5 k0zX "9[X$*5z1˛cGǯ~m^ZF'EDv|= M϶i-`lHf!-).j2MN U!4]kg!{K<ﱵU*]S6.O6ʪ<. >r P\ B-r ~,pwwpPKBC5}yey}כd~u[{g?s7 u75ʰL 6 $$Lw:@E0!%PV--u6RP*e23[r;e{Sy}j}~ vVŸϧq'Wj8.8I$N?uΎ}Թ|e>=s+9|0$}¹n>'+qNϫkϽW_}-y7r[Ox݀Bx𰽵e[ !dQT4IZW έWݝ+JK 2@q?y.[]G@2k$OWC@Z!eGA4J$˼*L±L @5 B8CxLPըP椪&*C u v40'? Y/ * |FH#d$kW 6H$dN@l~IYpe +z4qFz¢,yְSuZڙ/³Vfj EQM L/_P|,ode>A4i\6Ec8.\j̩J, |@`!!:6zG5lGi5.eVQ?&nY _2xGiTi@;'*i,! >h$.* =Ø~`1Ay so{i߾x>hM?SHFFy L6#G'4y#6}NM_~BD1z)Ҡӄ"=T_qޣ.+'{E 0y x(& FV}#_|0Plĭ2؃,j*U ru q}pW"Z-xz|V:bBA.j(C' L9, | |mBMUEq(, loWu0H` 7,zLpNQןY9O='!0Kl<4WGV]LHbE,eN`YU@F5a#h㢋S~O5#!qVfm5jO~UQrVcfچ?s-X@ye؎;3lǖ퇎珚mjEUTMJi;|bhj,,< t~Z !|TeTW$QE ,9oAO#gAU̬C*6 TO iFPqS dtQHZF}Z >$JiWG$[Z r\p3?060@]Iqw$^Q1kk: n(xQn@*]|.dBIDSGɀ Bͪ8]SB̈mnb?޶ VJ\,Bx^Su q@(˪)4f:U@*E-0l!L>Nz6o${4,[]]hc|`bpLZ5k n8VӜ_ PQQ猋TmOQ.d/f S, u.@-x0Tģ0'b#AE9K^lM8UΣZYNi<A`;fkؖBQC  r'BgAJUڔEĝUQyCLF/h_mimI'$0Ӛ ]t&+> UyZKG9eEp[`5^{lǵBc9=3=9,=v 確7TC: qԔUT 4b2,"M k2*<>A5**&*#;BB=G\I@km>?h{0~A\fCz4ՏXďDOk`b8UO4>ע,CX]B?y]Ȣ +3 v4x-+ZOWؘ4~b x0|v\ ާ<YbL=JDw,M &c*#daSF5hȜr\?gF!`I:NQ>*SL3W2 > ޡ </VSHcJoSC qaHD# `˚5$ |B~@Ghž()xۡr؁cSsN 4/ #N1_%N5/@oxxB6m%k o7DA@pxQ8=8!@M?fsm8C7C8߃p $'э$7=)Oqҳtd5R)QЌ*UP~'LŶD:#Ԫ@1]&8iQB@:u&WGc;Տmr96:4(grv+-o}]<%o yCa Ucsu:@^gUuk?كX{Ƃ/j $qrE Oc=1]ü6+Y#G (5#DݺۊyLqMRDMaua|J]oP=4+TQf ¿?U`,j\zX }W_ &6R%ŒeSH5I^pUa;=0? MVXcz$#\ʌd¢( J`ɋ:-L=p-`fYٶ](oa^ÜKaآkN9M|B G3wr43Caf'C 6Jx\.wHĤM?كGhA !AӜULEESRew/,$¬%VAWM S^W0ҏK$ß |lY`2$}"c_$.GeDOhIBBU$ RK]<~[֖8JJJ=CAʳ;;tBo6|G>;ciL$azWl "XJhg11B 73"i H2 "S\Vu~F)-, \"ͤi2@o+2ir#.{ e,t)%PySE<%:.2I?T%8eyx"ݜ6REE xTCK uajf/i[a|S< IqTIܽ}`ӱNW%6 #6);4LAö;8f]UAi.Eujv%!MRuä@*T\` ya 0KALE:*L`d\jeqC-2 *O zsIsJ)ۄ4"tpU*:΂&w&%'50KB\Ow$^uMlMF̑r ?5("GV<>E…? c.=#Eu@5JEXfV(ŀ0P-,Xe=-j!pPL+jw |U߸rwyWMY"睱ی y4D,TfNaH]%!ͽLJ"gwtL{ū#8/ 4NNeXFiꫪ-S*WlAQ5 0=; 2<$`3g\idI' G!Hvx\ eNi+-.cæPAog *cU淇|2¯BH"g2=6 ia%{[:F<(K~6HJ>+:3l,pϪxQ%Tn[HuVy-O-o>C!:(nZ .Yf{agDzvq~{a홾]ΣFVH@<>A˜-ʲĻtpL a9 x+mFʜoQ#Nr}i[67u^Y65?FТBu(H,f\?G9g3ɗؾS^N$4xF߄GW$3YPw#(j W!Lm_dօ ;ve{̑h?fi}#nA\ӓsHH#lX&{IJ2qZFW zr݁qPPeB6u,B1] J20Šg$1T|(V,,.gOpC:ۚ,X̺"jJHJ1}I}f;7t/N$S4^H+BC|c-z&,39 \uNe0^TM< u=C@|f( <a"%c6aI@["=P![B\.]> 1ⓥ̣B#uoy| }|sq"L~tmA] |Eҡm|˦*^$T" ΑKz<$, ^6c:<%r5n?[B EV5Yœ7Gl c2xjQUTC{u=}*_׽*_| }Ies$Ah&s'/LcjIcx*mT|S!$v-٨m}^~@ׅ+J)v8RKj^3Z ӏBV`"~IC FkkK1ݷx LA')J`1>|&s燴%s`iU' ܠT4 ]I N5NpOh k̕:" `|yS \ `Ԝ-Dn$;C#..D7AuOmV*j5 گv1,xg4~uHGBYF2$]XS KoFmpPx>=n렗D{#alN\5$|nG ]M;,pHvE~L- 2 qTeSfyT!Dg/HpZTOKKÜ*IsT -*CfKF  ّ&DCH3I˜QauAz6FG "[xsj"nB͜DTNX3N"@\|b.6rm :I` RnA')h+! cO1#{EXxe\5uNQmnR_>6!͐  ![Y@ ó֊r)xwu%VPRثYMUFH,?X;kT˕г}:peԎwN}xRPFq"Hu~߇ rauRElq*ܐV O9Fe%zDBH>nFN Mml6<x(#Z×vz&sl^1k,v2S-s^× , OjJ5]S4଩_RB @r_Gn-':+G }8 1h@,4|ƆZBvFHGxkDS wĚnRu&ĐvY4yUmx*mxσ7v6vQx̑ $D=K䫃w1O@uI1,C V$e~`Y ̲,0fXhdFY_(MuM0 K2˺Aq~,;0|kwŋwCQ4'I&vyD1;-Vuŧ]| xę [mfo#vaCNtdg( uYQ Յi3*$y.YYeM]'&,웗2^V>qAq! KL)('J@T$]* b"c@pn7dZcEsgהDFM቞VmIT%x=T粴Z\V8|Qί)λ 6@2j MkIT:`q$CJ^ -p.4LR6*vvoڏ6kA#ѱPDY /xW4vK[7{Hfqutl$;`:<<63^- Fu#ѯf8۴*x=+~ey;v:޳'\ ^0d$a^TBX|:Wdp]8h v!V|o'Ml?уø8y>J257rЫ=$l<ni#"aw]/KUF<(,6pۗB Y$PЪJ$)2V`έl$zɨ[Bs.> ݰa@vKnkkkOp؄,OFc=mف"#e; wKVԧb+jZոT7dS_y!I09)Lnf9HsfY4BBIHwFhXz.+u>^,~?^DuSS*+PdWY\[p x"7>ri0yH&͸rF"©G@m+/?J< 57~Y`i辷/G}߳wg\„i!kmc*X3_rmFbyB*VVb_aU>{D*$eYay*SmHVT,77OY?MMU$1VeLxx BX`mU7-|y½ A0-^n<⧳T)A"lCQ] tU$hmTLۇPG/C>ؾ[s/O gUwtX0l<3!qښ]tkM^4nKR=^?0o uһ%D؆g?$5:XBp 8?jZVAX$:ʦB$KJnctg&^7$q9v`xl;;\\ߛ*4iUtlqW')؄Q,uʷ'8'77([Ҫ? ,c9 n{0mS![* ,j F/Jb.aRn$W'<OTGQcz')Qer~o;&xdҭs"ovN>zF ;I EoG|'7xS_$9H$9E-VHyS>2x%۰Ub h؈.[&|bANᩢ_#@F836(9"ck۳@3Q)GGJA |>FU:68-"8&Z#+87X1s\םxf].x^%x]$+B9ўk{o3gu) 8m5g|:`huJ5nE7dw9:hPbB ~ވB" J jQd|M ;=ivݵrG(ń`SYfAJl ZL&BgR#n8m5.;v|& p $@ԝ}g@!MEpKmkK)掰)*I>Rc#N"$-] QqK,]_dg[eF"a5/}T'\CI{^E%M0LeΫeb`%<4` Zp"9Ml$f(]G08UрhqVwW;+qQײÿ"TT_Ix\Y9ߑ*CwvEnw0gsY˼ݜJ,&k =R1Lr*)hi T@ {فka0-3Ihxyjy̰T gƲIx'(@0끿7>|4y㒴20+E RHI:BRqDkAWO1MOK }X[D ;X#oW #;R,|R" gk4ERb"bF~gqss 5۷}yH}d[fj"cOJXg9DŽ<:ynbp REYGJubz22G|(LZh6$0V3# \kx Ÿ^t*ODn;LyetuhZ~#I Tz Ao`CkB]t.pWg%}xQNRa|ޭi DGNh!VIp?/\/$^ír'Z 򒂫# EKՑ$7=N1.]UBa5q +9 <* F",n ^rܹ~ʕӮv#(jlض؎ZhQ$UE"U7rQ{x6d¢??&VH }k#=ixZdAxvEIl<ߤ5"5y+ R:6'<&"]Y`=!c~ւ#/- mx1[U$%b\܏}6I;,ՉlvFSGuTBRpK\\d^ ZFYD#iҔ_,S"YA _QM`fkQwQ$Ӄ*a;22mh_O-#4 WkbKE\sh84 v>'hXG65MUރG8h@(['?/!.AZW额N )aH `yx-]G6(b?HO߇_Ïmۇ\x]/n uY{}W_qj jq%#N:(@zߖyw" .n0t 5(~|_=AE;EȪ>A Ā158A~M( ~:0{8s)iOմҒ >Gʣ,ѓ8k1S A ^cXZg] $̢h E/ qQ*Uq&Xs:DTp |nogi ?D>3 O 2^p xZQ(*;4Krp77_i tTj(+QbVp/#h xHgQGr6 5})X0u WCd@uErE4]_F@W_=I`__xG xDm>%1*mh0!1g*U"!>,EN#ࠤ nKT|I-iӵ ‡%Mg5"sD(!dHG -Hh<1§4ƈT E  @ y'uKlc{>{sw4"e'TX椕F-7POe?q|K|³ B 2$שZNb,UVx ZeZzYu K֮!<,Ff,l 1?૩/IYH ZMy4e>˵`-J T\a5ahĹ84ʹʀiȉxYPY% Gf$LGT5 ^Vي("}:2,Ji>DIFTa] -pP]q|#D4d b/k('"p$a%s 66$\sȚ6qxm_>:1WJ˼/ˬ}Bb֞ D:´"hDp,LEGtF21ormpUNb4l@ih@EVuVBD#JYDbzoJB(4Y\E[(k 7>v.E&h${zMisM԰K`澃G^> ̋ƞFQ\Wxw4,%YyYM*׷XpÌ!̵CΝVC̳#ѭ;2SJRdjB Db=nmm*d;\'JY셍R ç@F߀WBgP]󍍟Rb4yՆEq :Nsg0E y|=:QFe!!&SDy،гd|j̻Q$:NƔQH@E@O~& 5!LSp;jk^8$D_i%! ;] 0 *+hfAALikK"~~C= #&A  1Zr[=O(_{OiZQנ$,xЌם ZU<(0:.´O`_T]qX%ǁ W{QEU aV*1NaOѷ0HP!@4x:" !>!Ci@!``'v&֎FqUG%{UM/aI݀CZiV@ԓC0C_o"i8ڢ0D`&\|Z 6\3!x'dyhc$t:Z"8Ev1l밌6 sS9 5 zQjT2"( r/n[{61 dy(2D0uWDr 8K4^+k!a>bQ3u+ $ܦ:` I@ e91أ0Ii'D7)yG9fU>m⚥cD0]P$q> *Q{@V2s*N#cHoHU%놇09L@%c4̼49&mf ?: >X」?߶㝄:Mt2VIZQFUJQTsWTu|HM!]/곴#˶R'mƊQeAfINUEj4k>; Ƀ˟^^-$ઠ,N9m]Y&xRv-DX#Bhٜ [)(ժZ繋lDa X]. 9`0}E;22ga AX ;wͩLH}^"8|bi CpEN6*E/$9CX Sm#YdE19JM݃0*y|`ћ\W!olv\8ILMeib[`RDET*uVY4* XlF}:tYaWMo xGe]EƺuTVhZc-5/C rd8 &bǚRV{`(ַDt.$ SU#*-> xG[dlDua玔:p]Zv5\\r|ooݷ\˅]g~0v恿 7q$jB'0":UܮlRD3" :F8U QG ڃ A?hGK;@e!dzVǺDMfBᨅ`93koߛUkS;}vfA&wg W1eX_e~揲,2B ZuAc=.ZJb#%li]D%/3YP' O/Vp~K B"qVƸ/YPÜ{! OG?/_s )~_M{FeV`Аax/ͮ-:ڒ`?&GVkHCK[Qb)'m.FuuxO/*~<a^FMACP{;yDpBRN|M,/DVb.uRCEyG9̳` I.Xa/ɰ[exT2`|}_R7p`Һ{2A]:->좉֡—%Ia{<(%8x3K) by35eEV`dIR$aƷqWpmQSd]0+(d_$AJBV4 sfT+E]JVD+ar>@DXOi[^ ^4  ~C#t2tħ-Vv.wt8>4ϒ:O`段 n΁=v-;{֞9gSaz5p! uCi"EܼNgi!?h7JPR2Ӡ0 7e, ZXT"oE& =.n.LaTEZL]Tψ,*I']7R"!j"pxZUE#_B<)c*` 5#JGD.=fQxojT cώ貍 KlTA ~Ruyձ@2X ^O:B^vߦ3QVWu$ [W6/G[7O{E{; ˫U1.FWrx1^ˑ.aiܖUb4aȀxUkiگK#js =.wO]<1xց@ G .Mߐ~Ylqz*.(C9@lE"c,kĘJo*K'*)ϒh szə6`zwz k=?:ꙤeGD]4^э)MJD6Wvf( a$#զQ---n.wѫ$ӕ%'0m ~bCf8)TD^RsTԣ_N)_`WE.cѓYYTTO.!0gr.HsXE n J<]x3۷@w"|/*[220.tyAoq.%s&,/WvW=wV5@xP 9h,sȩ p'jcAx7rCz"& %Zou$d#6sj~()Y4,?,'g"9bL~W3b9uY,A "0cw,sibU~[̘C $pBJVWYWU.Nu|1 W84=|>:R%_UD8~=]XWL@UB\iY0 "=RD0ڑέrC*@:/#طo4`$۱|]JYᖶ&GDӾ][b:h3?y&(4q|# *x;闀/isVh1}~RAXT(.V) g-h*-VҨB*6sԍ[/S5puE^-{9 p DUķ8Oѽ4@VUuWJD~e^ bu[ׇWh!( ,.;hϏDŽKW7Glx$dkaJl`Hazo;(lKKFSIt;~e>6ҪÉ8p A-LfDD@mDA[J,D0Ͳ GRdy>Fp^=*I30o62,7oټۻw@aS4Wii*T[&YfWٝ~v)MBNQ8.UMIp3ARLabuV?aE'ץMJT5ZCwٲ0th"n`U C AH( 3EST`L>zdM Gb*y A0hVmh  |tD_iD畘(#0bݑfzZm?,0)Kda:0gVͱqgmˇƛ[t׿kpb'tMtK0酛ӖJim H6 |`/͸*ʣBp0Z/Q?_!ƫVsw ]KH{8|s @MA:3a)@0 x4 zNzSn$8a}YF)YU`bnJp˲-k#dp m)ס' TE*%~ olf{TC3v6-Vmi!`50u#:+D}Ӿ-U3ZpY1H4DQWYQԘ^,{un5Ŗ!B 6 ͘A_l;!]2!sbAR<Wt@8J a˲k4a-ԶexX LNG:8$eYgXLCq6{.H:?}[3m@dF~5NV~MrU6񙼕g1P -^mk׆8:\yDd77]R9Cn:@y L~# /b,ݎ #mF ^q\@G@iO=-]!h"gdYr,?U4"Agc_';.ݸNHulJ_j„#*4Icd o4T"` #φzmyT"fg c̙3M{gg˷6vl6Ko6sfgNw8;y[/Ma%D1qILtizT [FK|ԗhF9KOKع'a% ^2s2U% $,m;8F"Z:k|vPuyͧ¢QI[7}m] !.If1xXE\:Ä}G Lѽի&AЩצgYؿf%^ |We#s2w&=$INzJ W xG3I@֞7k*-],I#la)Yz.~aG 3J1%~7㍝k$%%y:YUUu3>;?ڍ:uF1uD=K[2vՄn:+{1@0dDQ7*ǵ%[^sd'57C;EO۫= "k $RGbEhנ7[$tY$~ \YwIZ%_+Gpw zb\x/%5P=$$aW!Oy U<~];0&C>}nJ*+7 څ}玛GuWi@{܊$);7 zΪ Y #as>XcaQz[rcBPG1*w%V#CkDI{'Mb%Q.h5DTGVB%Wð0v ppخ뙞cmfWoy)Ee"f)I!A[$0ƕxGp 7pJF$X69=zW/ &E,=5m*k(D|z BK Fӽ0i'=t B~NYlm;l=VK]1늻qx5N/~DqS)NAI)њ{S1x vTi D ;=v?r"6JKM*-F8_Gš[Ti%QakEPvHgUL!<}tDZxi _e`2 Μ 7y@IFnߎâ7oLMa:_b&o@FJOU+vLz{U|QjNNDdY+ H,M˺ *fh..\ sNkkc] b7LҧǻWvjH.ʂ+I=ʇD T.e0}(a@꼩—tK= B6(Jc|aK1$zT:%k:DXi{JUiebh ‘I` v?5F$z[z{W^`C9YCw5V@z%k]>ZFp$Gh f M?ӹ LR)-jTҌtr`ק@@¿s3LC*{Fd1F%u*=d880vK,C1 - ;$?Ձ kF@Qb^Ly/G,!,[68cn1۹0yܲt'I7|lv׶Sm.\Ǽøm;ƩUP$hPhIQYUx9p%A¦(bTFD_  u&|Q%GkՅIt2XUbW+1wlcgٛ`9y{g3 mB*Xl&BYjOϣ^5ay/ \w 4S-JF$)#l% LNgr|ih}XakBucBL͹%n 'i TPrQuG|\{p /Wa^oߨ`#0jcoZi#%׵$o4`ݾc仮Elvʵ`.@v'ha6QE"q5Tm Td.7Y)K1XO li9B{mUf#T"-LFVI V??eXwenoo1= [`ɾ1][~YwƐ>++0Is%:@LqSXȮϭ_8'WUE0*, G`VL >?%rax) y @PEf,Ƒ{Sꁬc~Hb= ,8gj'RYo+v¼6  :O.P8<ƫV\tas],iŵ vuk/eB_0MEs{9?kj2Mr~>"==wbyWXqx3n:^OR^i1(I/ri"y bc\AUQ߬[G7K?snpnJ80$&E{{4֙P*7*@B҅Y+?F$zwv'߾WHfVj\gȓ|r"ܔg}DMճUq4Y.ؕ<(guc%ӭ7Y/(a@|>ȃ3]7${{;gv0Μۆ13E+G0$eю*-_Uh$ k<=iN+Ө#68:1JXDzoi}ؖA%cV%i>,!7Y #FZx1_#Gహ7cX,28r`sq9|DN SzZ x<88F64`!^%֮w\f;G܌(*Fn-*NM :QRA~>yDVqQYB"' %ut7 MA|>Y rmtlg>jyr9WF[٫GREe }  C6Nr[~v&;bp;Ǻ 1GБ뤈 'p Z>D0gѲ0\D+,s_zND'ѨZ|$gŴ] b BC7}{%]dyLn]u~Uޏ+=;b+l6IMEve W9gntm»=B}t_t=O_|?+O|.y+ϯ"Zkx#wm6"xۀ M|leVp+/[[7o-;wow!֑x2K}w !$YSDzeAz@q?kS`(_ K[0>F0ҸM׹@a`{hB -1jQ*<{6b e]%hӖ4DaG6b O}~K[Dbb&B񍈂Q<>p'Ib馬0G(]hyzNȒ=^(9;jL9,(吥"KMRi 4$d~LQɿO!SCR &OĻ҉(v*I |_c Q|Ц^&4dU6Ǝ|d{dCc([ PUqɒr5L0I2M5{4Q,jd98j.v,}' ~%dSqSp9 "0( vD#PP­-?uLrʯtEg%h&d/n ¾4X4^M/Ax Ͼ̌ EȊ(aj9 AbRF-h/|%Ty dP.@KqCpQDt ZXkbU GV^HB+Hp[EA cJYݍ$Cm')b]`;>#0 HD#?!4gJ*Ky /8,o(|UO&i6HZ8'QM 'jz$ $OBYfzoi:6pv ͗7d{mUT1HH5DXRj/?'t %>`ˠHP-n)^FhtlA$Nb58vs)[ncvb@](zPcLJB~f*8tSR!I@Y4/`l1Jd@?Ȳ8?i8k3!q^Y庄geuYvΉZxryݧ/i<>>z|,:c˓otn0tIZe*BY6" "ݿ^JSŪ{!߱01wʙ)4O120)vڕ0E rV͈jT)L6hK?B64S~F~ H;-{M`LMz!J|Lـv=AyNj׏לy>]\=fJ$<\WU!cidB?j>L$yU„▶@XD=b]S`lFP.~FJxEp@ZP "[AdGBm= q _ ~|F/c=۞lV=xF㏟񦨪MUHv;ZetCƄ pQ,qzsg4 )b,THtI˃?JewDx|`Mf2lp_, Y8ׯ-Ĺv5p|g'H#8˹~GGBd8ͪ3u1ffWIu3`c }%A]xVM2A54å2N:/"7uP'h3bpB\TZQ\FT{h'F%B}wipmc6OTekppn'ZM ͮ;roP)x E1BنSm@=ԇ$WY0lKҪe>_#xnb"c0xw 2`CERݱI{4D,3, ~HUh9RY0ó֯lMUx+sjƏ`Dՠm_/f vt(cȢI0Ea[-ھWul;BB/_8Sxw8zy+JDM7 k-(o`pSOmP!=(4_bb5UA7|HagS >c!lU3"CYCm'1ՀъĊ|Zc0h\=E]$>6J.:oN<)|9mPQ=>M4dM q#Jh@C ɠ!6w?`y~xye9UC7ySRђ11gCT. i?migJ *k;.9G{X8^GG7|tZ—duyiu@-ExvEv)Œf.Ƽ raRT2(dxt ,zG+,/=܅{2zN/a YOo3eQ!!F4\ۀE#`^>DfxL$clpN:ؿ8NO]'.qKϡԹq;u'!dq hM<_ (qAF?R&5R!"oKM2{?Cb\ơ Yq٨-K 3tQ`5ANxԖ)y R $FOYS)ni6YS+ɾyEy\QllAl$BZ$.wBߚc2i04|iVmX)[ uxL̠FW/:"J}ck|e&(yhU7Y {e\^dZ @sdCuizYB NAGZ]_.{oAHynrY*Wezƌ. ^cq)c9YeCV20ngZ堮4/i$D-i\W[VYH!ҳ۱v9Φo>܅ЉCB;|ޘ$( "i n3izLӒ7ޫIa2ʸQ`n2$K趧i͉fSn\"אN.㢲ChU+H2Qԥh$W\|dY#l5xNv%8*O[rSt̅5Tx GkJ24uN .P=$\]CVBļ@lvҝQAy Lh5C-i@JƧz\xݴm'_YlwZSӗS!`Gj^h|Q7FP ,Dd?k!(DB6=KsyX %8vw+v+Iq(qf.rFC)Y>j*5bp[npǟ5<\_r]#!YuH%x_La:䯙TioM[XH0sUgB1!CER" aD|/8೹R wUwAijUv:N?f CZgՁ+yݴI@6RⰎ$}Hs`E'r vB<[̅xnh{4O9VI , k]˂wE6}} kzMx+#AtV"SaL¢;+b* V ,FS;$? g xFq\AÈ@_fJd{{3:98!A?)IYkdoY8Az5$Y)bHGjN&^֣#T3TZ1GfW ./Ghmm3HgU&&rgucjrǻ\LN.q<~[6L'5Q,bky2;5Ѡӧص&34I8qj)/g!Kߕҹjg@9>g-^CJB1juб\pA-΀QOh˃O;7\g͉{0zN_۷ %(.MFTLqk{ZI襹V&i},+C`[~j <ajtQVIǼ(,K= { `󺪧RA܏dmh{H`$w~C8f@8i*[y/ zݟƩV4j1r jbX/$|/NgL{^ 5#9KlT;J96O]y ×h/ײkco^6Ae1L9DHծw/ġiHj#;A[:nbBgh&7?WQtza& +|S)zEUG=ck؁ldlIG!ڝIx, 6dyP..間!5~>Ԭ^ ۜA1tˊ6KeњhYP穆 !߶طjM' &)2ƃ8([RyJYΊV 32U#{!ߦ|#u~ue0@y̭JzH&b^|-I.?wÂY7X_5Պ"t}!]ni.L9-|($bE&Ź >.+6/`l?lѯf1(ԝh# vNԕش'5:kWIaT1NBL5aKRJjޘW9p_zo]\q]A(W4Ecpj`n#}Q%}Crg۷gOW<x1iP;׶#d]v8]L }3(Pw; yiSRnvF@6Kdȷ 該s"BO1鋰AN!/(໑,uAFhTbP"JUVev(%y+r\I0^ncbn:sR#1OF\GLZhۗEfz[p)bGቁ|@wg1ኀ0VOB}:RȬjL@eoq/[:ޒqO~ӐJ+l|H#OR"rp"IQa~\ƨ3ضݘ%:#,tɵFw+#e婢j[m0x8~VU2-nF\wbty,@kx˟'?ׇu+ÉU'uEOQ4zϛcWd/ԶԘ$jg.l*/RTxXGDU s@ #u=0W{!zy!jqasIg#@@D6PV:?2r!9JpUQ|t!o'Qzg+#= =f">I| [<17X|{4uOvyCWM6^nvaǫIZ Bz۠lh#&: ?57P|z@ CŠI(:NwPD 9SiT,խFzڗƈ2*vT|jҷ n!5A8@+Vzl9:ޱ`f{7wpE ۤfgnp֠ ' -\? `O "T&w9{ G5r德۴`;݃#qJ4ם\hû ܼ AF(KвMوܔo DxG)8.ƴQ@Izj."N-}Uf@"ԕV0[]G}-7!r{T$@ WQƎ}4lգ,5Cp]\gzB]!. AİzqrJqhBGgO%Adi dx bcK6/ OMB-*@jo壝ރ4Йlj-` ws"(qqmIs5 s80#!p<$-CvـpvQmI5œŲƀߨxTkX:i~4 [-YܸR ATD0>Br ٖ u =:` [o B#KO> OAԫo#D@[ rOj2zt~z-`Oai )i2z&}5faF6k;cLʈM):*+u>Ax/uNIYQ4<>ZTrS!mɗͰl/ l ;,|F 4t-|1. 4%/I.,ݬjR\xY)ȩDH^lt>zFXE^x*,.B`HqgT$7H{H:>B-V BPXD4k,tDK9vߏu%lΚd*~Dg*~di` y;\V[\?a]Ԕx)0"x(}s.YQuztW# 7 V`6Oդ`pjte;=uwD[ɦ*>aqB =R?YۘpmJS+UoӓE~B?= |{g'+ #i[FZ]یvt=pSc :IukbCospSUgA؄"%G>/.xt(.U_kԯlH@Vu6x-#dx9sL?2ޝ<#aQ j'`{=>dIPD8i0싩M%<g5K9 :'8G.Dxg~p,.|3s-p[ ;[_MSuoe'ܚv"EDhRP_ 3vSbLR9Cn⣻8Hef[IvRO5dxzl[n9#ǻG!D[ܮ©ƻfo:2gh ڬ  &fSi~y[Y Fn4"h;5"P鐭{`V:_4]f)v DhCQƳ^i`*ǝM|Gη|u$[d&zt\dC FuI#ceR7+xGJ'4۾Tj fxV sƬ ŝmĸ6eBn]d0$hG[ T3^AOZ?[2"FJK7xF>2,p6v_Щle- Ό%!st!xO;V 69TG °?زKlOۄE5B@gHōpFza[~ 櫗v:ƺ碀cE$Xf˛Qsܕh!~XS{r\qsQȝ&5箘y w߸zƙX%OXx'|-5=O{!2Tk5^UI!KXS\'1!i6m|FK&`AQ=Y|~ӂw,ODVŨ-9C`&I\5y7rm0=|e׫\Q&r_뾉up ve?&kؿ{6Ȅ@hapx2F!Д8"bAȚ\T.Z [h5 eҌX |.<"+hYCYB-Ã뜬<8zxNz 7\sqO=겇,bٟN 4ule*0Nf:dP=b<{ 0_8?iG|Jr1JiO0ldqs*cC~JTc~N4|h$O k[L G78H؃k|BG fb;§mK26UU&bl]4hHGA ]youŅ&ޤ3 cM ,za5Pu "! pߊ^@C+$ 5?Dxؗgcř : qqHTЇe/٫tl!n;XZ#m"Xo0D}Vxtf& Cfi)!\!UO!C G8i–0`QP5tˤtpOӫG/]gKێ-N˖eFݥ! }|.^Ln* E-T6Ѩw2 ^q_:yztyH\S_6W6\˹Srk8iew\BGSU B2BlQ5pOhR[B'/,%$h!+yc A0yK4FԺڻʓj鹱j'ڶ4.J[bM|qn !r,8 v'g3ήNXo^?z=+ͩS5xsyˆ@^#|1ED)d_~/ΐf  bZ&.za{!;5x,xY=3T_c\9lDЊ+1ܩ̚BPhhc}ڻgM\N(5/-'诮 (waqwg[5ڮȩ2Nt,I;]ԧC$fWFFZpעĭ*#?xاu轆TGN$u^&:d wd:tVM O;'*cdoE- {1:dBC6}{%Wy" j޾:ׄT_J2h1 Z Ld5vC SMReqmlllCHL "Iő".T_ N^U9眾}gjG{=? ĉs '?gqN8}/H;&+Շ_¦j$ʛ8NҴ)$O,xI}ܵC/ www“wwxޒ]V3 C#[a+Xr28ΦdxTm {ك&2'eyՔY"Ƞc+2H*!|+|\``S r&II:r$UiFt42X#o P+nxN=@K(S.:6_J OJD[ x4*suJuCܳn\VޒId l,|Ö:g7A KB8)\"kI@~$ q$Q 2M(ຽg>shgِY?=.kS 9*䣼4n]ZkZ'őw ⸎Lt~W B>>A\up5яG sD@"=0)|JI:-8￳kۭ F(eGHB0r7QySyTYgf aI볞oJ!#Ao3*Mn$4P ιU‘\g);=Wf#POA&`."nt4(XHj=WFe4 qQS$ w f9F6J˺n**Cp}((x/D >:IYN0 L[ tX 3YBM 9QU5u] Y~m 9τsOOPp[+ PW($MU QY3{k@v:"<0b&ٞ)U j ZiEr}C~c0ャtls0=ΩStuKײ&= "< R4y7ye0hg-,gʮ`({YB?@50{ҟD!1kO qUTmQTHf>|dRGqE5y\կ>gY \oCǟ c繒p"d(I;J˦`20e ж =rI> {3**R 9b,w.ƻ8o:zQP'3'h!BXZ@%A8jpC) V XGzƉg32`(K)KpBOF1myͣ5=8F"xf !ϋ+S#_J։A<‹'_U^QI:% "d/JZU>(Gx 'BfZGM ά:>0gWw*5˛9 UhM Id3q9+p)rBG ZZqS&0Z`,r˅>dMiAc2k,ZSi>AEkM%\xxA:@xɮ4$d׹A ^='֋fk;.&Kkv"3CPYaQLD@/( yQLH5*c0IizFөM5D MQń$/ \IR@x*<٩BS Q~"`T#+2N갣wi2@ȣΊ <%E̷`-b/)CAo, wi<lFU5tF4#%R3?gtԲ.qcbSW@me^w(g܈2QG6꿾PFl {ƒ$xvy b<ϚaDGC/OׅW_z?nkVyM\$RWG.V̎lw <0#f_'qe!"QAUW]0Hs1߰}E]'BtS!Q^UZ 떵Xk1.ؖ\zwXg}6>R)`Ou ?[.ڎͣf֙{b%1cFl{`G۹#Q2,RUf5o (/Wxd OlRp6R衽k5pEٳP'Xl{ PY e]`b ;0zH= HyQ ?5fRT#-˱r?9~ x@g3~(\싶+Xti\6ETVSD@>mDcC.0[8ώ;OYe) IxKmSs蕚B!ǝʄ{e/,ƼŢM%,ط%A&"xxYRe$2 I+H)!;fW*³ s$M Zm&}0{µ4[I".eﲳ$,!SlwJ0gމ0@I0րǞ[!m0 G>0FfknuQEpEGa\9mU@uAr8ch@sePD&TSqFyVUe.:HrKwbhCT%"k4)ꍕQL;D `S3SfQ9Rb" )5|-Dwޭ>3CJ,Fiu|n9]:aZzBO-Q²-&;!U0ڼGiRiSqtPF9rUVIψ&Ramr(\ @DF ⬔YѤq&MF;[ahjģpJd0!(D5=> Q %HEۈN#ZfhP~( [AE%LfW)mI%l+3tm *ԂF:4:V{8/KWSnpRd8|$'QudP!X'n`Il}9$)79[#9 FE9 ӋBƣE#; eC4 ~:: >zL5,iFU Nq#u&#t3DYD NIRslJ ү$B TI  =I|O)EA˿q0.(ZM:')$TRQf"dPG -yF 2sgH|ȃEY,QN*=nSZ(2C |ȁH33w򬨅 Wxc5 ӘL`x&/dZbY;!m;oFQ/GJZ0&2r̴aK[DAkUFa(sѐ#E\jA9q~ʀB8&DQUm} q`o0:z̴(?է¼Mx.BbF຋!p}$ =e!1 *_qs V ѾMZWP BF# TnulEO 1W^0kof{Q$5GqAHZf6 _JoFȣ=c&O[,ɳ(Jl 3k0tS0sf*6YVuZ=!{&{-ߠ4 pT\P 3Yp8 `Z^0~yU`Ro?Fhl~QٓHLE%:4|Y-d0)FM.ƺ?PMbJ^;Q0 g>hH`H@^b+HӦJ#5{6}_(<!$`ѪRtimBg_L)\:}:hπ/_@3U/.;oHC`"MAe"7-˦pN$uTP%ޡɿk6D.^c"-(4Um?KÃi0I]I//ʋH0C8s9[ضo{,[.N3?,H雭-TD!_76 D@}/فPᘈ02AB)Pdpi߹K]=c^2fyފOZEHTS`*D/E,خAt1maŜl _Di@ssiyp{@^Y,, }ﱳ⬳̡/ (g0SFry*}Me!Vɞq(82!RZ#@b֋ 2ϖQB=sK':3Z /ߤe-uLtն P^6u=3ڔ"+"Y958~{B o*<'7iْ,(EYEpO3x3* )\3qMHHwD hp9&OQ/@ۜ NdSurG$A6ph &}lJsMV`߉/-" Æ:U{kHpyXVpv48 6  ;\+O]N-YJFS#_>A,fuM8CKC$N持mÖSMyJk>RL$ySCV6$s&ZU%6xA\G AGf."U,sE%6V!|"ڹ k#A7jKhou* |G0Lk)u79,`^{ vA@Z}}\Z|@/OI"K"uT|th.+o!x.^G9}GDf%P (͋| 8EMko۩62Iޭ8~!sJD X纸usiI)\"<[ s\\tAEJ2BqO==X% 2uP6( 9h>%T<&a55B*xҝ6 U60/$؂`! k^CME*ܞ"_ qim٣-Q ]Z4pXBv d^SOOI6zHamoDm DMgihp}c.O:awݣ-澍hoOG\|GUA#6)MTͪK-]}H"̂5"t|t7<Չ>{F]66^$٥$ߐ54 `Zvhɰ >ϣ)SA$pތڎ_7"6c22N ~1>oVq:ϛh3;lkQ5*_).ޗְmURT<|>9cgdVD n+lGU@@Kƽu [kA~?1̃oߡhm{ŒWMTjGǂM`PZ BA/T\BOyْ^:BY8zGu!;z,XDq[)*61 xFIg!e;:a DSEZ ,i"/ .3cQG8vBlU,vLG&‡BlUbMFJ W kxaṕ>Ey0wd䜣]W4(=bE?Q>HO[Т`Kk*b|n/ ߩ#F/-T𹩪T>&'۱l˵˜Vlp6l7pK{o^`/ôRp\' 0Kq*;$k"Ft]lm˜Rm6G8>%+ay: -F.t(*>Z(#`|}N) 2E&P\;clD?9/Tnٔ6UtxOi9I{D}r90_5Bm::9^_ N%E=HGLaOUiҤyYś9 M77 S=dqjS Kne _v,sqIX/o'f/%#QRU9&\]^.]C$ih컁m¿;c̱*F$UnE{q`cp0>* Q5AGY bo?mpYnEݞ|!S囌@謮԰3}kfeyǂō ?Xe`>e|AUxU,3%y%P\Dz0*j}DЩ5zqVRљpx߭r;>!)ۨGq+I(ٻvm9_gp헸˨>tŝq6G94@fg(hCS_QP<5FEU&< s^e"]Lx7".š|g @_S]ܐ6M|7=5®276+iƺh \Lͼ!f-A21~ebh͘;z]fx i#K?? IOa88"0peCGŒY1` $^S[J,o b1Fu#i-*x:(w"ѳ[KD>lKCEm{굲^dz@9(>_-o 㲔 c8=b &Kɚ<aQDM" ˢWLZ)A=KfP\l䆘P`]p`YuBB$nHMPfQRhQ\^G g#cUýdڛQdfbL}tpo6 #::{~2T"{R- " PG2&QkO]M%pe˒Ƒ b1|)]Je^Q8~t**q\$y.2R\߭m<b4N8KcWy[_^er1Gϡ?P0d$gyKeb;줂 ׆C>R-vommY2 ]z\{`=pms;{],s K0p !+<//2˾Vz.?T<,܇Fw)xʧݫa=Fs^̝rg~ ?حk"؜eH#1Ed)wޯtr$brE{\t^ʕ+䵒g&VAOݣgG5p#F oQ̾a1EeFZEC7; H&XA.gO<Щxމc:a܌~ %~|>|fБ\ӧ-u\h|:8S@]B%aG=<>Wg?p,QH"iC\FEVG؅vmo}b7_@qe~%6{6I ;hX#]#]qd@AU8 er`Rڔd׮RJv:$'mV{۸ ԻNG1?F(kCN^7T5dwaJ[ZuA(s>!Fz~B1XpyūbtO*\so&yH \Ua \x{N+Zp$GxhC{B_8)MFUk/. Y^!ⱹ>O0Ɔ"&ͣ5 UK@`ջ[>擮mxxJeUia.ٛ>(Yen,͈0wAm#:IsH;V@@´}4iRʕ^ APD7-nڐ$>T Bt(oU QՉc%U|Wm"i4|Z! IdqmqfX)PnIr^~ۀnҩ ҈Р|yV=qݫ.& uD~]#&T_oT>|zwmF2,-VjKܘ((*:湛od2A`jt֔e,cu@YD,B' 9@yZJu2[A.m?/nJz:OǛҨE`Pn=.iBzzsR;2qD>B E{ճd _2?3I>Jvc͖h )8i+\ Uk\$j FT\Q°7Xf0NضW3ɳ=ˌ9 ?7>L J2m`Ƨ֪e:!ٻU|7L4_Ө ڸ:xMxgp&6XZ7j"+)*!PGVHLBy)-{a5mKs򌇋ɰUdU.Gfv8ѮtGwB2l?*QT0iTsMYw?̝8…Dͯǂी?PQNH0RnۅuQ2 =EKΪq +xEJε8g;60f~{o 3Gб `'4ae%g .C 4A@˜5icYA8X,\?xa !Z JGMTw¬a^ZW`1ςĠJ~lݼDO%EZBs6k]`nUHUԧ_Ut3/$vr-l chp˵w!W_ ϴ'% <B ҚeF] OڛV3Ar8%V`J0@pCS|Z݅}04901`*R' ;ޥֵKɖ:s t7@=B"'QҤ\al` ݋KD4 2*$l ,bL]I].x՟(<$9_.8MUDB!(r#PHxV*Bogoq 8m ́*qBZ-^qN={: lv كG 㶃SGK{k_UHo4!#%iYRNXt"i0tz$5fpx)qAͧZ*2U;攐P+^t<\|n{Uu6$#yX6=1G GN+JU!|MGwOdqѲDIGD>N}w0y ț!0fUy\Q"X9:"E@^L0h>Rk&6Da ax>撠*P8L0R =WxZ22lp lVyBZsbo(h@ c7YZƢ2~1W,ni>j%6ma!᳨n 62B#ܓw67ؒ |A*7nbN#4iy-8L!f˲J1wb#PUUmD{ C';#2llCZa?im\=m^~fV"N Nbڠ\hB3f]M:SF-Kz6-J R Hhљ*S@"X! hcFH2 Һ`Y.?kX'7-;X9̦p޷nc0jRUV!΅oe10'wgʗknd6 y(ˤɪt vܮ?b1s aH&1PO9"M4^櫔jҜ`A OAO ^ &ѻCpဋO͝UC16O $G[Dг`\k ĬUVX Vi}jVm)U!6mlwv녜Omq׸υu5DEaZq b.q6K}2I6ƅi@2sI[:v h9g=戅$Ӽu5ʣLʺ)phOw{ тQV0›!IV<}/ tv>CEog`KLhJ[G4lxhp@W | v>ӵh顖 I11wa-Nendj|i oBB,~eO,76)]V!S˭ ^W.zt<fj;W8랒\|[ٱ!\0,4yQdSlUn֕)#!~,)EuY4X-6z;ª Vl44}{? ^G7֧h~_Qϝ w6/`?擂Х#$V(g(PV,"#%kpŖ5t۷q^_ g4>N +UOZUc:.zc[C s k\70TeM̳ {Y%H*ADx<{Q'6ȠQw-5gx?_I.ލ 38fIy="l!!ոUoTуX)km+0NF9i'| ZlBCr5}ieW}_ 0tk$uOwr=/ ovz$ЀA&@1"a PaH !۲ Jđ"E) dؕ/r]Tbž,wys}JVOm`ki4{qdesk;[_j8Λ8)<*ikr>rΝzȽx-[O Ku%w/~֭;9ПS:$ |\[?ҀRB]/ }#"QU HK_.OZA߂s=ilB Nj"+;FYG_6c %Ix " i\4E 4Ȳ@2 _9 ~ ( )NEu @iQ5UU9G`탃=o;u:!nۻιvoFuz?xpzϺ>O Hj #؇ *%&:D(5pF~mD&FITeSTERrz.u]zޝv {!xޞK{¹ޙMe= #}=`S`$N<Aר( ~2QxآP8k d9"q|z1ǝp>)&Fg~O? < g`4+.5r ߟ".x`J :O`>-(} 7³9)#VӤ:Ʉlv~sܽ 73׃0=s3Ιl~}](0TYD²4S@r - ,vM ]EYQl@ /MfIYfAKҿI]m+Z@;;HhRE/B4SpQIHG|7iMYy6`HoA 6Z%DH8j⼨Nx^։ۜ6<}$QFӈУg*R}&\5?QҀ ^jIjx%YV_T?=Te*Qp^c ,gq^7uJI.G_4${ C<4 | fv0LZ# `6QG}B| MZ)R!O.* *C"w<9?CQp5AQTA,"頸p6d!CA@ POIiZxE3w BNh@朋\IGCoK0[4y$.0ylUsf1qnvfc|D.xH Ҏfg]4#*Ί&RDlCp5 ۺa62ʲe>!IۓX# ƴ,<#,4Xl3LJo8{>מp9tÀv33ߡ ϻJÈxH1j4> @d@T8J.;3+έdsj0 %[v2 * e>Cj LYs^=G?Ji\mcx& 4;#D`Խ×92 LD= !A 沊a#XWVؐlKV; ,F0I{F%="|gH_cTt4D0ss١58:Xi`(*$HpN;k;S̋JMH!А::3(}ev mĹfٙprM3ULPulq!87b.5ɦd $|BsY![^W(P#m3E,B6UM͚Rc**aZ*A/@-[k8UFT梩 xҢ @ S//B'ӈ‡f-,<^BGaz]b|[4D  BYU }(66M3{{{go~w}lv9\{>:DpM5,$']h<`\عP$EE,_WIW|UE)#Qtwݡ8ܢϱH@(r4AsD H"!A `ma(j6ʳɢ\;KxHCfg=˳.x^bdL=M4J*'&+#e`>$ID8RfRA8B( Ai (<8v)Ui@/xAD ĥ7j,34Y}mQDv Ī[lI}y-$v˄n;z)\# ODz LeU籔+0X ¸\,4Tbj؊I:L|tu1 kT| clyT L7xEdѕ)XʠbQ*Omp_TiϞ>55O,lUT\2>`?CNŷѬUҺLˍ tr"t~ !lYU$LUXsپ;x\PEvP̙],WF(PQCI 3V3⒅tp;56 7Zs` yAOU𘊞)*Celh_;eSE`4}f>mHJ@ UUk~s |6PIU4Fb l>a?ȸwr 6_fmI1 _GqBϲY,ҜAs`|>{ .p~Ç, !py(ngfAGeˆb%Z_d. 6Q j%{]9GX ]$ǜ'ԗكVESՀ%JeGQf8 |Ƨ'#}k+ʬJMcSiʅXNe Y0EC]>F\n#k6F1qxjڔy+e-d-$P[RDujTsA wncpsY ,c\ Fj`@\B{I S"?̙ VR i JzGG;jKvs0w7J,[_;RIE<&39`fh46[nVdgZ%n{#X͒m۾˺!3 &D2rCNk+7[4e]zS".򿲙d"Whxl#5d14mBqjX;(&[Exj<ރ~FG1JTe"KrFh([y\n2dw0 礷1eQ,C/⎑4J\s̝<,gs/8ް?}oϟ3 bb)J T>_񧸗tr7LzI"/Fh3 Rf:C{(zsoNC̟ww| fg=ZdyT[-3F}E@ӡ FE䉴6;\֬r+WiP`[OXoț,zk|a[H\S[?QX*}E_;j)(X{8*3DvDe^2pУ2VbqSFNx|YFM:mrؐ waNT8l%6AL ěx&ő0:bCnZTu$"F&hH5~^0'*kl u02p .=kOx Tz$Y)bF#_y8ʨ)㤐<&ܯR [ax?gρYYFkWco&0^Io_U툉sԹ+2{Syd:7^ ^\lJF`2ïI YFwxcHdU^*$ZP(PҤu*Tau C& `_ѾOLBD4![[@FЋpۇz3j:A)Euj|bYQ2,'J,Ls; gsM]dh#OQT&S:WqWE1 gdN:H4VyjjXs{5 3n)B"K ;lsW(~txj`8 וeO3C810P׵=؝|%, {򜱉"RK<[ V6 ϧuMX{6i4+;n ۛ|3߸C?[̕W:舂:Sl<-HwQ67t ̆kGr y%l*#F.NςѠ9lxsrϓx}bHVsr o8:sR|"CƷ\JMx_􄻄EKcS-lECU]fCtcK<]0]{4 {bA9@;(dA{2/"IY7N,~`_X!ؖOt1t9Rbd7ݭ`oe.ax)Be1p1 a CPa!?/n m00 x!x.[_w a|`xAO Z|x[%78@[Η:O,z|\Rqpl0TO S}Ӗ[AWr&:8EEQ/lM.LY()iBzKJ%|hƊ(K}U:&NyR`QSMx?%iOd/fy6VlHJ3d0:ڇg`O"&dA96۰>Io\C7iɰc矚̆iiY4eQȫ&Zʼn+n'5GY},?4ƱLEU0ks%Nhx꬝x9_DVLKLULdX-QNhr~[]|H]ȥuFڍAV[Mg"B'lmU]%uT!~߾Np;BM^_XK_f]s򆥷ս[S".:=}m J.?JiH xI /C*s)@߮AMˈ$g+Ʈ;Hбbm:߃g[hpJdU9`uEذUmRwj #{Xq&vv5ij&( dKdTҨ-lf#K #=K {EU?(Kl25=;=WF-{; C@>9GI!% /aC#A5&:,CU݊ #=BBg[VWK<sju)_ %UJ^u[zϦoݫ.Lyŕ[n|<{MU}ZF_W˫fW)B8MH"qsPn!;$tɇU.k_4%uUhjw-{Gߵ-lpa@$k/o.敎M }!{4Y#6QTy$U& tnimu^GS:B<{P8 ptBo;$j6er(wW5۟e&0g[ ʲSLݐ..IX|:+B1Tfnyw½G{K V*D0 ?6F-rTu*DP~Vg~3,˲IH&$;Ptڼ $|0G1EtNuǙ47}@F*U1( TbET03 ):]|^T$]uįm[^\AͬD~H0;d*p5S 0T8[>ڃjIs<:H***C!GZ4fї|$wotႏew0s!ZNjIՇpdO|epãcw-]8+ͭ8$%,^DsB:?%48$TIDs@SLyOt4|PCԪ7kU2*]r{KKŝT"|P``Xv*s$Or9aDo}6{]SDJ/pc+JF&Wי Cق=/$3~yO%‡ #A}t0p[\r?`PFRDΝ~JCA'0Om,IBJ_(dL ږֹ%4@1Uu0ޱoF//SɽFlL0Fek,0+ &Yv}sqw}w3~{{7{l3wޟd"|XC.w89%8 YH|ly'nR5*#{%03%& S#4ۃ!^rLE8ޙ6ʷ֞4̧Z@r}kq&;#PsoEN2 ^MԌY0a </5S LNr7BK |o*ݫQGe1c%BU?F :ѽ>f.<{r?d' t^jUde BnP̈J#C/ `}o7= 64ő e}A}7 l{qQIŠi=kpk`T &gfI0O4N B&~%* F#/¬UW*Ew-GPc&eyƂ KNsF':w`q1yԡ8,8: ?|ϙܟQOw)ɷ޾&/f3=[\󍞻fow=ܽvwmoSiQMrXzٔBs]#頋DT7 d&YB%}l5D:EVS+۰_vbہHs~ c@8QYQz9zQo iI&Ix-bJ*$3AeMĤrא?Npt y Um$[)hFSQWN+W\2ca0֒oanY(oO >! ObVKU60_ωOh$w3A,b귾J'K Bd|neY#JHlN BT~UPaVX (O,]a"ڙs {g::Qt .i.x=9PKX_jD7^V\hDyW3( z#ͩ~CG^<|e,tYȩ9D أN]^m1!8Ҩi@㸬j\yt^EڈG <M?V@45)041L&IwrrD.qn<Nťp&nƅb'h!h+2A#UUF^N?CCw5ee'Q.!)Pqڲh&D<%L~ZĦ<}[km) CY6(Y>+>#m^tTy~P]|fJNj0;RE4_mu.ɌR]͉!8U%X.+ Ot D,Ty'KɋLPKl&]Gl}G>dq/pyQQWf> ViO9AR8,,>$Cj+q44.l,Qf2K n96.l["O^+I w!҈`'˿St ·4:5"||*u%r }ߚJ7ЩdAF4b\*0U,/L5e*Av$4Y4y#Y^:Oiz#hm ll9w[e/ƒum(Lp<#1Zwl}_\:L5 u=mKsYe3wW/s~YO? 'fBNn1MMjo7ҁϷf\ Kq b/.g2~ *[%>Bx8I މe`@rzLBgj40A UECޅBi%4әgkYq{OkxM#y$NIKy8 Ϋ^cs;馦gyUWH h l`<ʦϯBPpw*%+g56'r0Py6\jLE&GD!<ڃmo먲"#-J#&Da)a$ c/8{THYd!,e.3n3p dDeyTjq6"@E);aFxe։?!³lŹJisi K0'C ˾?_c|j׸,ou0YQM6Hk@9=;i܋KPcg=ҤQ"Ց/s"ߐ,ֵz !t֛@K.4H,!cH 6R`Ic{6L$o,z;/7c$| Ga\^~۩'ʚ!9pkHKfA3Ug{H\'q)^ ΰ267AfW$r;x :. xWKҹ!ãAb1 lUNx~pEn!T/J+~:y0.*]BBnP҂ljoB|?fPCacZ؎:jxƲJ &Ɗ:˽I>QJ"Fh"B xBC#1} %g}b"^Pw{93͜y} &,0mlBqJrM4XDy.i"E5!JR (U%1iEWUP<sNsw_8?_peucxرwq8yuX&YysxmwYeFǖ>v5++N޻|xaXkٞ繶}^ſ}~w<"'w|;.}[ៗ|6_w+}O`AZ4eqnFZ! øc4)#%yhCpԸ(FѼL,c(nrᦽSG._ {?}ޔ0E,~2c~\EG,ng$@dJFIZ`׈=PIPZY?V0.U0 ێi ' '(1(p5)f{{;yx2S̝ Ƌ}:tqI6A**436 7_S`PF'eB6 u7;v>p_$kOW/*"#aѤh OPM˫`*5(5dƥ!d_*df#L!эЖJ2:}_B<ԃ|m~|r?jyx%@5XA^fQ|М#БZ&X8Ū]A6C@+ yf3eN踺Ț&18B'f%v@qLa/)&cǬSINTR3h !@XP4 !4>e,WEća5NwL %tɕE PPfaT詝a*dzB}G+#bRD̈ovi* _3g<)TO1ChAX ֬I-:1g ~t8AnfXb27]Qog1e1Q(@<) ɦBтIe oym_i 0˶I˞geH4(KzI>B\goA`(P@yM{ũ4. )Gm܄ ("03p߳<M8$+\4 x *v# IeAC5i[((% dޘH0ge|2>"|LGayG߱,s ?Vx3oy>{GTH IUӕ->7sA P;e9|zm2(&c*IYIg#!>~Se 4ĤMY j5ht:ѳW5#Ao2 `U,K(T @XP#hU"!YE |h 妨DqZVaesmAry9Dڭ Ub@ Pbw!BX,m/ma #h#D@_YdDQ BcE"?>ogsZ3~ֈ;+8F1-9Pan[6+}sknD,zK{I:3GUQgj_]IbZTИuF s_jzQ @(ϑě/]϶rWgn>np 2gӠtuX!EL%xItsf$NB= >nTe^d̒Wm"lS=1݃"+0[v)=p1 ̰Yj3U;˚sxGU[ + QxP+JsLtNB=6EAB":/ VSl 8Bff0N]U6yc  % _Bz!zHaGIh8}^STBnWE3 i`!('peÛf|FԔE PDMRyaF;w]14 Ng溿Efw9"Zʣ~Mai Q 1)F/ (>[rxQ>=3ە6ObGr0sxࣦyY@ʌ$B3Y E.qkHT88E_[{ieZNJ@vR QZ"dF]RE=T ~נN4 ،`a-#3֥ lN4Cy6j8; B OmZP0V؈F=6R&_WTD{e,DYgFҎϞcٚb],<{΃1jq6%wtl=T"|C!7`}u .ԃnl !UW4J$}yD8wZLFaX]IhvUm݆3_iK@p ~ld/%ÎW?gV˽n8c]̙U5:6Ѧl{ 'K"N²1ZVZ8yg4GAT4D#@wkVلF؏7R+])(H!r`'3NUiTF*` A|Z +-uv6&ps1lFW;HQM A-,"k`z9#a3)Y$G\tNB垶ME->"Te6Y=m nr8yhc(sj=_Xd@»l"ͦ$ A2^«m"\Uy03bgT()踨U)'pV 6`.pTZr bY*pF2 ^6h#nSaN$2lfNyAF2o'D*|# &'MDO@mhJUE2<Èy94ʧ@5Vy+,<2c&@AݥnDxZao3E8/F  IhӽNL+a|/5:yCIf9Bg}o[>zZ3mt%\PKy6A"k[\u6=0'hq(x0ѣ/ZZg}p c"(PKyK7Bbh,[\=rn?775N4M  .2Pe*kL&sd2m:\_jAl+ 1@_8qLtMD5l,ARYT;qG=H19,X#bi?Q0LMlt($2`os0c-#l2ܥfo&d &tB* 9>sG-r+8ϟωeyv /$.h&rɳ,Nh~a{V_< n-#2Ie? ֻ!ئhVsME84blPKMʔ/ѫD2BݔѻgKX_ F-;u{?=UC襦{bN)Na9݈ kT.pi"9CMҧ**a(}ʖ9裁X] gq͒A:kq&-\29DPQ?o+# 浚L6i2a; d"0HhtؚNL)A j BR)8"H)l|ovDv]S#<[޽dE[|~IpH'={2kgg Feb\DbtDཧU DɁI0g,DeyQqh?;}"p@ ĉK>~|oboo~ۂǏϮ5A}^9 09Ho/7GtP<Ʋ`Q,-& O8fr8JJ j5jgPjPvOA>ԥ*_Z=Ͼ`={oFBvlPsAe^dmn?αcd`y;"9tQQ#Yלobt'77Eelfb _W`]Hֻɿw5833Ci;4j|9O_>6`S־JQP~ <ΡF.Ti_9]Mڤj*@xY(h!&|-5nH4 t> l\ 8~9˺n1[a q-Xͭ|a6ʋ"/!`بkD業 qU{RB0C+[ gX"W0"usyV UFxƎU-g-.FWx@L&iaV0A0 F8Z]0(#Z\{bgSno>VF&4{A}JDӋƢ9;kv+m\t\a!6׏,YxU5_- N; s>MH,BXVn: oU@xXE:D"L':Nv=<+UכPU0P~Y!iV X-E}YH"0$pOEB@6^A=iѫl ki5r9kv~Kjn`ڋHP۴dOb~5`!%diۧy֙μZpNX;~Μ4_hLo$Gi4d%nn`[ OJ[E"0WaxHVZSm]>eZm) Ǽ|&+ _^gwH|;gA).)Q # HE7η8Z٬986*=4sS-PI m\7uC2y+H )pbg ="1쁢u}9F&xY#/cZ !5D4+߄6 )@!Y㞱l Ӽs+ϝ{Ȋ,Lj]-k˥5>q!X坣":I߼2/n.cPaHdQxBQ^2(IrZfzi&(^ؙ^S-=N ͅx16]Ta %/K dd\Fk*S5U11-(z"!xAD8 B0ܣEc#hH 9Lj]'v@J u#`6ĉ-!XIiG\lD@Y <bdG,e lDbm-s"zζ3:GPᝮa׊grዉp/:Q9"i \e}#T.je'띪,ecyH-CDcY*)rP6ND;_o@9bizp>Cxp44a$mu-HsL~'m#yԘ9NAn="~° Ix+<;2" V y8 -Le6]+1qA!82**L8aL5i!zTs4mX8HbB^^oV! J!թo# Q1 ө{MУZ2L_V{&3,AC$JVTCMIM#ܷ oN-jlAfR%r-De׾L^S¬_`њ`SWk'_lM7='qQмi ׀%u\QM`4@ ! $m[!ҧB60 qAgIBZ7te!Vt$p> >aD,!H.ZAeYzmSٴޛ 6Nee\8p1d?[#LRsYQ@t4 # 7Ccg0gZ釜gDDi{6BQV,9OGrEjjM**rcwrbeYe$ W5Pܜv)\l9$>{Ku ?jr.0\pl* 3G^=3y߅ /=b%^I,v!,:ҿp-0U vI>mq.3c_4jx2>S.x,TFmqD^, gQ׮E߬Ħ uCƖ"gC =oTbj!OxBb ;U j'Ebşi$:zco ԐNYjEA.OGk 9)⁅"V!Ig.铕g-Sy?-!YE=y϶֘AnYA;o<ƙ*adh {;`Q[.;)mN4)rI}="+#a8GٳNCݘ/tc̣&x9$ĵ&-Fn]< 6"@a(SqY(Pc&䋧~N]3B 4 YTRLQyq]C:a Z69ɒSU I06oK"IJ-N3\W<89OQQL Xu`"Ÿc o`xx6)-OV9R5,ne:Yqx ]}ilI((ӀZ/) Ax QNYL GRy.NyX܋] 'Jե_$5j9:ԿХd/ j/?i-p`$m%IApw5vљ(2g*5 ) sq R#X\!OiTO"7yG-+WhX˦~04h'FռBA0Bpw+<[2c}CC$LBi&otJ=Ԯ,l Q~ޤDY$̲0GinR\R_>T"ܨ:Zj:ڀ3@wYB4FЁWAiс.,s0Bymgd`Pl0hes|[Qw(vag+*DQIxႷ7GyFˋ "B E%S K4i92IfTAҵ{Q]ŮBQOx uy|d"\޻aE`$J s`Zp|ݛ4Us\۳u[_\LWV80+ܴΣ ݈S sǐӜ:b=NUs:4`5*ŷ Y~gZ]0kԚ!_Q = "B{`-@eڤ.efӮ𮴑$KuhkΰA彵) ү}AFyajiJѫ2$6GpGK Eu-@ z |, cSa'`)"DЀqCȪwF;A*V_;wf tsO' mOX4k nX͐0U_k&F(e$E٩a],L?r5 %+Ϲ𸛝cH&N*jSPs.a. z^PH8ҀpFg} rQv 'U4 ?TkSȦ!m CA;I08N%ҿk''oKChϰ}h3!]]%?o ̰b-1@h$mYx+חn+_Y1vv>s눸J, U`4S2> 4MUI/5w Q@lB8gݶϭz-WlYk/uLEx;F)a'INf^+aƨ 0xc=#a#6z\ OGr0.N75U6oO!٣WqqZTYi xTgδ̰–% I9mv+Хj.nMjMTiK*|.U{-C lN篅gTDrjow&qȚ[ O<BC53}kdW}H|b'^-hfGu|H f$B$%ق`6v0ڍl!,cebHJ.Re0.-8b$ yWsn&чr ^ ߻5w7~{K&K:-[;Nnyꢎ(,˺0;X>f^r/.^~3/_(aP_|P #+Abuwrp'|ǭ/ƒ/G@YlJ*; }`*K8y w1·48 @jBP›euFUeG/&]K-u7n_հхQDi¼t}.;EvxYbuSx2OG'dI  yqȦv "|l3%@32*|jbTuikA4FF -iuaZyq-6lI,gYD":(07x9O\&F'ahq~8)1$IAulj%QY!B;RF\-[lA=,b1/n)0aIZt*(ضCp-<!㜗i,=.NLJo<"1hThˣMA:ι͉`C`@ iWՈ>ExLH]s^bFf96ʊ0KA!wDCbi@y ԃx\ {1$O4Dh%,@HA)ld.f3S]m'6_+ ~̬"QIfP&bw/Ъ 9} ` *0cUIIRErV]APзRr'm𳝩l,#~,󺊫4CWtɟ_)x~&P^d$pU6 "V#D?e$j ߕ^tA#N$,EbS9qiZ \FkkE\fvX=!@r+@Y^IW#Qcfe3es47iTFǣ3}Zkg! X̋pPnYqF"J/UT@л1ió#,7i" 6\<4T>) goBEE]QT=[S&"Ho]aS2xi-dfaNe{4lyx+(.bR0Ap\gFtHv3p-=d18ϧQY_g!k>*,CO0UЖ${c?g@QEU%Be^ʼg^[ghQ( L!V"G:dgƊ`o!sX>%E x{6NE=Yg.'e+Lc4N^/[ a_:eW%gɒZjEш$puGIA#vm!!8@Z%*UfGKHPpĹh*E |T+&]RE0fg5:x`u:I=*29 {wV1:p[-WU(p CI%-. D)x[^Ia"֬ pQ`Y'/d9a]اOۈ!޼ۚȮHQJO0 Jevg"nUhy`-jЧYq& ttDJO[/f2UQ?n] un5Odȣ:/㴐Y`B=\ـdĬ LNݫgl#o^E\MPȈs,]Qwɀ 683/:"-(y]v8L}0fȞڴL:NpLQ 7hBԘ#kU0dZj~ƶG?I <ā-X\Z͢B8&gZ';0kT`Hm'(@BmgEya&\)F|,ѠP_1EUEȄ@z`ފ5/F5p6®-> 9<{iRa Lta#c]K_]M%}md3 QYee!Tp m|VoyQlOG?BHY;kQzV6G۩4{~Z*T)(b=?枔ok& k1eWEUiQf,ixPv2o҈9[Ë,cTMi<A^)mY ;ޖ|& 1̢Zc.¸f$#*r}zQ: ?ngʚ"iQg:cBڎkrGXP5QZd"eY Z y%rG+h~M)['g!(9*;C"H' EFx3Ahp ,aXRx:|R_cK"EyV@->,<{& !TF[#:v4WJh꣊wAF*X h@4o~ ԥ.|DVք:L!G V{"_ó߱@f"q".͉ J"m$go—1ı~;o)XzQ9MN"+B"{_ti3f^+KmFy~ s4x{-q%.eߑ^f<xw s''ƻ]&qN]RM,fAWؖFZ<HsuIhGo~ʛ.uKwI1f qŎllvhc#40vNE]f`yp~GYP2wghtg3Gӧڴ?iM$k.lPQ_x}Q?`6rIDe QZ$#xc]a-ᮍ`Cs@ O- n>:e-xE(+eBƒ=t 0q1(q[InJؗ `"G޴Ǩo\%TAE4r^8Ќ'\1rp0R5Y>sq(̫V0$ѽVA o S2E|FC6lacgXY[-*6ڛ鷐1AM5r`ϒ W΄`ҍx $F(aggPe5jYasJzpxdRhf,=# cz.k߲wdG1Ȯ@,Qgr>Z>"#LBd&!wj `S[,Fwea2;a }$!f*(>J*V F^ SC֛3g:VeBTǘ0M6p]w!z\[Pp}ta,C $;*W~Ɩ?BV)x_B!8Ƶ(G7ml4i-0ϒM[Z{UG͈eAPC &u ~΂:߁xn4@Z$uUe͆CTj~ʃ]A:w Dy/\5Y-/I"<۞ͣ} k[.7#0] QCowmyV>O΀=q$b4M\chtBW!<gY]1T#dGl-7%“"2 *,BVelZz5_DM1p"-$MoYUH#H١I6/m[l[[:)ʼBf-3mHE0F}GyB VnQ(Ƶ@Vb}ͩ Zx(91WY?M2ݵxDCL QfNrGQHjf'IϜ񼩨>ԭ&`4, ՚#>a؄A+[$Ԁwę@F9/&\0]mmwmFZQ{@h1]4CJy+Y.`JzB|tǒ/; ыF)̢.`&I6A+iWX/`dҨM4 &&-Jyʎt;rѻ5& @:QV :xj3 t?brfj B+χgo',b ʓBdW5f foG'54,Di=~ӦXBx0b vTU`"RXpqo4Bqߡsw{?{ }AX|1vq.dDGOְQGۺH錤[!ZNsgi!&NF὆@x ,OTg(aeÂ+[sy@e'\lk tjODh!#jDz~Wv߲Q)(.* y0^cMh&/ʰ,F_#Zb֝ips06:o(8 &a_ bB ˆ&.dQAzlܢ1}A0N%Ev0#)M Uos4; iSI}F9kujh>ck̏:Y)mh ϡZ4l> }sjn4;!ծojxi8ӈ\'S(:p VY^YRV Zfv4RNܣ)ˢީP^0S5`H+d:4)h#4 `,QYE!7A`L9rj<'n(u٢=^' V}Z ."%~T1>~5 u~c{, VߕDBMF>ԹaL |gc O@, e)KR%8wJN#."x5ddޣ\ڦL$0 E}gi{$8^.*Ԏ4çGMVY&=FW~EY^s)&i[5u`e&+Ô g@, k( zܠrma `w4]%rYd*4+HL4 @2hñ# 낚|ACqGj@P0`LRJX_Zdh .DAҀgdAM{&^[}m@gٳgNv;t1n$F"|ԆUWJ:GܲuY[kN(NJ|gTr/gs4\Tc>U1.΢؋/fS;,8"H @Ru~y֨ ; dڂ#Z_3=Ohs0> 1 X!@1A/{''(<{Bc֙:Hq~Pqat)K}Hcۮ*ߦp+) qevY<<$^pƦJgLn] V@H?hWH` PHhXA h4> !W*4"6 ( oG֔D+M.4z{k ";Aa[w,"JTsi,FNhrxw #YX)UЛf>StAۧ|m;v.|OhpL.TjpF; /^VRk壏jxaTq]dq@EgNniN09cJݦ; 1dR>}T= |^y/rW#gn{Ř]K!3. Hq%8&Tyk0DvM/`*q`B@<{XfA| uC<[4 iTuaĈ\BUl1Mvs>E$:` I:g _# VMrr= mzb=JkzSFd*YerBaa:v;u0i@`k5y10xԷ!̩H"#kS.µ_yBt [zr>u0cS̗M"?K6žf\KW@o(I;7Zv0,7XnR- ` e%/qFq@& #: gu0ĹL6ԎRSm! Ʈ!Wy/Ѣ CϏO.h<6I2,@ vmZ*tbӌ fJ\u\\jl1_xs&x/r_}\yL;<Ͻ!TxBpi 9DrKg5+6l!?0L/"!n K3g":90|T3AX4_W83xM=LkRh+: 943ku fMNԓ`%_[L ?Ұr &EnL26@1ZSXSѻbdDk6РX\4d^6 9]c uTr~APKuDOhoó:Ck.*dEg$4[:/2*T U RҢ# 1B2?*|*mNAfoE4AC,9?}j.<RAKk O%:4#QPR x„@b"Rz,AranA!<&7Ijf%>BCSѡ³nkQB3ҡ^a~R'`|eΏǍC7, 8|Jxvɚ{ɱ%˨ e=)ji9NO~#ɰ?qϓvf+ ףlkNS_YwqBRH._;{q+xent]1? !0oFA0THAii]*b`ߗMN6MupF/KLhgZt< A[ڄ fYRZV5 <ށ0zK3ZP:hla~6GIk h~J˱/џsՋD-s|V$8(< ɆΑHc6BLMU>4\ Es<Ic<~LۧjSu>cG"Q A[ZmN]"ŸqEEEurdʤQ 'T.>b>#g5"e#17YUu \p )pL7y4[Zұ/}kQF'IrjxITb:a0iv8ö"e> Ј na/&OVKؓ8_ 82MVv6[Iq9`ur$iW,DaK{ ۳=Uqy]t dC0EZH;$ZdSKhpz.u@Ʈ{=SaDwDۂE#uEu %f}촚YJ01C"cJT)o%U=8;Vq1kv}Bl7 xq;NMN[r!Rwld<)֦ ökܤ"}W~HB lTĩF*QYY}#@0-;>Ɑ/h4]ֈ`1c/P`sx G:\ǛSOr{"ږE "#kh-KAe7;{%s+lh[gl,I>2!8g|R_uG @M995 3-ۜK}^=g\aө| Ԛtg5oI[ #ǍB 蠶8aʑb$"gɄII>M%aV5Gy-N&7*Б̞/rc)_e\Wm@x4xFvAmY'BE/oE򌋨,qM:g&ҔbhNԋHkئf XhRЩyUT#^d B,,LTWyQOq"yblL%5DqSHMd>Rnm6Z[)FZvx#c# a2/`"Lry٨'bzE/Vx*,RaT(4C5""MK &8\9?FU~"1#$X58\"()H` ^uy$ Q= ~Z-ॆ\c?D+Xd@w1# &$x/U-:s]r+q:,{_dᱴ8 *TY!̍_Q_=ѕ8K|EcOpxQD3Cflf+B]]B [ VҬ)F.m'^ibk`f?fe\gQ!횉'bAG,O' ̭ ;m8CGxEAǕGF }O.{G6t }{B6C G02wc8#u6#Ty-6|=On?#8|<;]w[x<]+_-2QFJ6c| 1g*Xe9ΜR^u5t;a-#UeȰ]Gpן-&Մ<}znq-$ɭt跍Ě *Bv:{BuLtu;Jvl:x.GvQ(oc$h-!5v;"4‘M& K0m)$V6idbb9TF^phQ&RHz1s>0׈o% e,TZL4][?G؂< DF+=ͰӢqSUY1 0CSSMI:f7:Jƻ2kT{12Zd#/Jtיic[Y:q2't834]Hq8avS!T7'S5vpkOě!dm*lB}mRζ5\&4BXɸY}QX*Nh]Q* qliF6׬ moBC2}k$W}ߢ + ;gu'_ݧߔ.B 2”6CV8Ǝ#w1 / 11qqWB\8r>P]q*S)BP@1=sZs?s炿gq.ɹs4}e\E}5~=W.,UUB-ҹs;O<8pN<}dLg)>a~I8 %{.OzU?/^u=|u~_;BAQ'I085-R0  CͳGN[n[// ,/s;{--8>$mx#qT'Qe@8N;8Jtq R! g ›LUuYG\GB"$B# 0JCTEVui%2SB?lQ`(/,A A H4|G <^3h uR<ʔ#P5; #+~Pg?d@@jD,1# k-\w |al J)p]|8'Yd9Y(ƕo5' `ȎO:bo[{ٲDᢟgu\U%!N󬇍<LoF<y&^# lF"0B4Khn<ѕ BMo#F!%".śKHHFtt=!hU"8(O*N،  | 4Q1Wv06rj7$qT@³"G[ZW-E(,.@W~ ,,WT[mG@'z ԰Ń!Vun@.cD X7@>f7!} 0^(@'eYé *8:a3wH}P!zށMH)ESj`qCv``4oB½=FQ%E\44`>esrfS# ޅ%t|N,'!4 @ 2PQ!0FbA8IVu8]A?53:4 iܮڞY?$`p{ ?uspqƨ*AP)UxG¶B]pf-7 T48n"Pt6<.A%säK8ӷhaЩ4"Pyb35 % ҃G>{6yR@eaA= 68x1@@Z/JH AEo=Bx6, ϫ|gNlzwsf3;P];$wj;28&|h֪:.$*Y(Hx>-(hYTl 4!r:PV_@TDCtB%Do(/ F-*v4ʷ%P&N}pIG2 y`( D |[PpO"DpG/됰ѨmU]Zh~=FNl?el,dip@%mK X5-\E%ZCRs ?;{yފwd Ԕp`Xg%GCX Ҥ.3Jc3 "h>FJl,]4@Ӳm%w]T`П qZ[#5,쨍DlD$CzL(S[Dy=pxH P":o1@TdYB0 FsN’8n=,6l*?kGI9̷A;5>I+AJw<5ԦYFem p꬚XlT:A{z`#ZU Mlgb Zو\r85md3<(&!khk jK] ߀.N#,iFXwޏ6! /-lwv#˟Z%?)h i~]UUxF! g$0eU<37gq\ H3^waCr[ 6 " IF#^7["m[؃}[fG?h[,ЂBd¦SUN߽G&N| < Z &#ml%SЎLsfv2.{ ($Q - 4C@a -N=[# _FFF+sNN؜c 8]#fnS=dp<\Ty&6;\qG!* 7T, PYYFfʂlk?8.2V1 8*} nc|F94S?WA52eE:;2f US a臐yRef{&D6H`E:NX1y?'}^klOE"ѲL"BKx&CO "ȳ$ Á߲˶<{qrR;bv8!t[+#J8tcUVUBUDQ?ĸl*N:L9&)EI1f g ۸,۶Q!E׫-oYy/`Ppvg3DR&[ uozՖbB-ԁ'b)h_M ʴ3 ZX/w 4,G㞂,*S0kQ͚!?jW[(ML @׷H*,";:# ±&N0k,f]TLl5Q\. lB(:  V2A. cEy 5W"MaSɔ~L`&V ~lUD@&DXG, 2\yQ$BIct&"7 6+ݗ^d"{{#77FlKVOJQC@0e=ߘ)_G1xֱ( =bkn Nh BS!fws۫j^`Ԩ2'y ^k¬0kB}Y5ͣtoʃey+\hXԙC`%kҹp}٬f; ͉:T#hecea)J3ׇ žoO=r :{=kwُʇ#(63̻(4|U V<*Da?cnlo0(xZ6t3a@!Юq5Xg!Jv9d飅\KM./<Ҥeb+6nE e@ 81,fa?)B&_tXmmokM5;.':ɗ `2Re_AiEmjZӳiVjNA])$چm>jPv B%KmQ3ps8bG ;aGz;on-߁:\ObK w`Dok(>_ůFu8N z4ʙN\v<6Bܐ7rO >c>;/Rdf^v( & 4^/oxk o WL4 Dp?xsL -_pDY؈4*!+M"tƝyY=|nkaP_4+lܖ2PtP S6iN?/0/qLglpgIhM3 b説8/z^BJ(Y,?ɑo~tMm˳msWX]nE^Q/ZIUi,fW&kHm{ƿ˻B'}81W3ő˂F]#XUeepGX NEOo1SMrG[ a 6|B 54vfq$˵zdnWւ5 O ' aca粝p홑. &>8EaNޡ ;b0)y =HHl/9,ʻ _} hJ<3Z%/_z{%wf{MSؑXX6@`{½<\)?d9egY!H6jU~{ckJ F#WE/R˽;a*(>t'CKUN:rγjE{Sޓ- BNA4xEw*DGQ EZn) ״BgMkrDTАc׋G`h;**@?p&^Sy"DNjRN2d*ei=x&IJE ^AМo]WH**| }HAakyQ u*!ۈ7t,.Mߑi%PssT`F} ㅩ͓!יqbã/OB(Z谔PC%;% ?̛RAŬ*#L[ iϵ!w^߅g46XuLĞJ1xЬ=;]# #㒅EpE,up?40B,,qT4m c iA~ =ڃFpRj3G [zg4k; $DRu"4 `-Ŧnݍ = ^cDE.BР ihq ##HT%' +օk,w>;/[,ߺ`g粗_TW:TdD%JCYYs^T!-TF9^D#Q!@h1I>iNdz;b$bV CnT< V {˫>Q!!!zB *"pRFˈuDU~\#1;˫eР#YKݓ]w+||q:fK .Ewkԩv *@Fmr<_]89K_eGĎnE]O{`GeURjbuycq"J]Z*":.p% Nf߭հS^cGD_`⣯[^*v{&aF=?~[1(e 9MDmPt>Nb!C^d|u:N% ӪFseF| IC HFh3 0.J,K&}h@Bc \Yi *`ۍi.лE @oz˿4}S#{45)](awCuGA?nTu\.t+鈚= u+ٔ(^b1ڵ`D讅4UhZE8"OBMޮN)\Lo2q2)\4l)3qlmE$Xgd:wS_;y8_GwEU}/Wn.z2el'[A#gǁךbwo}/,pLm۵{^YJm`_3:zLHA8A0oM xyg#d#TpG $\DCy?hUD l"T]8߶ITcU+9RdEYFE)wH"HUXĔQI!`&:o2R0fp];g?`Эl* Nm8;=붤nP`< ^W_g l,T$bEd I˷.c~ZL>g ]Ƿ37%$̷逥ͣDS^: ^ آ˂V8_l:ܴKA kD1LJ•yRGJY>܊\C!VUA'iAYQ᰾VGml,-g@2dF囯#N>M' )a!slO@*188;*к!7ѨM2ܧ ;x!0`V8Nӄe.lRƝ~pB0v1-N ѓ7~>,ň_0Ƶ-–L-~ OBB^wUsE>w<6pA -[ea3X]U_CulhKG>&9^ӨZUnXc>bvK_dhnS~Q41F73*-[M^-l7ZEWkOՔ-NR9)Xr *llT(ӺB{7ET4YlE~K(`iH\!EF/cKa[*_2FF* vkz;Q` S=;R1J`wת AH 4`f@|CJ)5bζtly#J$yWO7 ?<83,Cగ68l>Y0̮Wܴ38J")%,zc2 |boHC 6LlbvnTXء; x1 8z `&Y[E/DOy}.-H7h [ՙԲB.UĞ"")ٯőZֵѩ8@B$B`9TȱaDfmxaE 71ID79m<-6tk-3.z_]ZEc' 9ZJ师g .W.^!V/>ۂ>.0 H*Z"k9 iT/g6^ؾ^v]{z_*"`B<g"!7; \|$jq[\. :)jٱ fd`gjʾv`cH@ $!e{&jfr#NE(lus#/RߪlM<8D>fՂ`1NvZ'iQQ!XmpG[!kަ7-C#RjTഷi3oӰ .Dj.0ైy@E"xDH2wv4ls߮϶ $D?8 cY Ux'tdEYUgC`l1TD&z y;6`"p(C1ME/z؃,^ tѬ\s<86JBC2}yey]_3I辯gεٗ[I Y,{@$Q-4 %k;`tA1%3΢&1UUFYOrwι~|w???MΜ{;sߙH<<8|sMonr{s)6QHxyY=̙#?hv[GGG񾵴=s=u7O<Y<K3?x~}gj/³A7aFW!aoѾ}t?߻>;;>:mxj>kO_C il, Cx<{B&0*pAV*33m?qx,qP)2DA  B}5ercu_K:> cB䛤(M\%;0 l g60CI$ X&qXنp]>gfFR4dA&\*y.w; rX} [A^cUjӸd356!.!!qkd{,JA^gFهMDu$ y\1C0[z4,R}tZ-, u$^Fg33(*A"[KF@xb50JOSڱ2;0GA4σ #$ZwPKݨPM\AnR>>._|Ð⩢Jj*|D !I2'YՑB^c6|D( v6;`A"|M7*j{ DwRu4 agʰ-թ|(<}<$NR BP쥠B}!fӀUxkFiE,KlNRB&۵{kҩE" bGZI>*@ T@<Ԧ\qG `*d><ŒZ.g+$]x,^Eta[7_8v`YtT/Q@Mu{Y`!JGa(TqT|F lsilJ²@4фiOČ_Eļ4 `F}~EB(!*,TtAwөv DAI 4ȯ4"6Qh(|̤QyFE(H`{ 1 8\³W'_$c` kC"ւ@w. D YKk* ު223jPH|T_#݀Aۂ-af B)Jw@Z떍QzPs/5E(q P$i 2}.n6K)/PA! $݀GE+Aelʠ, P҄PQf<{GStꏘ|m4k&y|3hIjdO|*:ux1Q 6#0 `ɲ.3"| V[`,kt`B*e![e`(*Qf>%-&m4ӤD?+!XAbFK1@WH2&ʝxU-oBE'hܢ  2}\igM$»491dYB 5Ch$y,G٘vAbrV>s`XR_٦ڵr 7)mT}~Ի4Ȁ-Ƣ ^Fh`YKq.[9~xJ(E}zt6V?Y t!ng%q@N4!g'aQgDF*X%B h=SS 6z9Ǚ"Neb̾I d{%s%< %Ef EVdynen; J]w#u[TI%owLb u$i_+yxZX kpVMw%Z $,SM"D<oJ>RrLM]/g4 i8DHC#1ԮR>;5Pt 9at3MfM;rXZb > ~MEyleq,T ]><\&a ca굿ٍ5Oa)~ǭOdi`,S$S=:} ~QhDA 0͆J%u:M c5_^7 LA^+E ] ]|hAq{|@0V.|- e خcoH@ʆ= ".,K{)̈́WV+$FCbN`"K}@a4lp0 8xҌ[;Iܓ~fŵo NS,~m,G4W|Iчq/w**ASM 1F46ЯQY)gY3U!H2S2,J.<ԨY+@ݩA'fe$TUOy!8k_Е{\Ao2zlqho՘pwfYO|rX:6ʵ˕r rj598tI U!je \>(kQZ 5"gW0 ~ D~rJ#}u0o)ir ??=/_Iڤy/(i﷌_MLt~K!Qo0奰?.REr]G Q)pTtbAEG YZ7 ;jVUC b4(Qa*}\BUOJv_wa)bWf&hPJYFq@z/LBLA]w-E do`'HFa-hhh!hO8V qqe97K(0'`'TF9|,#5`k09A˯! X%D% FcyPl<O òSPCwpBq墿d ؤskQt$|Nl?c/ڔe"unȞeÁp xFUujJC N&?þ A"JZFT>S+h0?x*Je1 m]- ~5;Do wh@a# ߑ„x H h\+-a3SPrhF??i`mU1ؾ0*0Q-m[s)5o^:sv9iyH U=wpZ`ܥ^VuzZXND$o2PhC;+j~IbIDL|ªKG1(ր#z3#p)7f;k\ӄZal3[:4 DgxzG6+F? 7y#$\=@cP<@V,kҚpg9A"LF-m5EW,QWb%Hb\ cGcƽp^rrwpe*ah1 FEZv`^θ=Ň Aҝ8VnM00n i s$ 1m?Ooۑv'['8D4LAI 1OB_YЬҞ̩ /lkdgZF7i1`*"A%W}Xӝ`GȆ 8wf!'`|fJj N90f˝"pF3ƀ@s O[^dA}"Hpg/7`#œ(ZB_s8i0OPX&4ؚ26 LDFmF6K B |jafm q3(6EE10B"eSS~jh{=w1[+{aٮb5smsb1:mu>QĞOzR|f(k#p)ĭ6),"QViң#}O.*umzXun^;+g1=|D߽\\9v A2KhuIfvtQFOл+дK9, ґgSgHcP0u,5%N0A@I> rۤ v A~\g 40}a \qb^v 'ko2lз2KyIe:T]AhÐ/O ܤe.r;w´MAeLJMHoڢCY \Vm; xQ2 ,P;  Ql$rz0slp:#:IV2 [Z!G-NJ@IicEF2~.7կ o@x<m|w ?Ww%3['Wf Z8&3H w߮M?b 3PyRpcm n#]/~!aDᦄK슒>d0^<0txU/af=ogKd}сj6Y$F=p$~RV!VǭG0q2dW=< " ԀpvEl*H)jS#qb?[)~lalI1~ 4ѶŸVH*7 D !(ebѶp b==--ϥK]\&jN<Ԅ!ؖ B|Zaf*Vۣ(b:B1ym.`z[Gzp}-gXa]-. Xb\8rl떕mۺh-lw zMRn.CeL6;Jv4-+!Vq7H&\:wKQF:'+J>Ke-l׀ۘEEeCuPj|o0,-LzRp:x^pUp^/ "fˏ%ԇ^k+,K\Hl>y6_ *!&Ѷu78\Q ѸjO QEPN Ϛ@d&\UN!ˎGn݂%J´<ͫgeR=i0̬%aN~= +v- "؆B&ZNw7dS2Q*zp=c;E6R%eU ^:՜|$!ұ­#5Sp$Ak&20 W9:T:c@t)91.'tCѤ 4<* A&bF`|(^t* UD,~Ly y.`YtS#_/!lZֽf&N0gXLדIEQ&: lzC Q2Kq&%N@QBt@/*$+x]Nri(tک?RIA#:"߶^ jR|y[ +D( k)Dk T=<\'$s\W7y2Dgp(Mc-?esYQ2_-=am,T# -T`pE=Op9|x7!V@(n aq Xj1+Y6RM'C(z}B)[6@ݮ:/4ucHZLŶ JJS6SL`(qم%e E/~K'p_T$Ѱ2a\!yȐkQ"Y>lmuBm^kDףz'y,kQ<ktk9z+N:r$|QjccwcH YxwQlD͍8|6P_f(#P5cb\ElzM,Z{ b![&"QjN?wPrgϰph6bXP$lz$Է+tgWjX֧P,)(^9i7I<0T=f"-^bB9^^ȅ ש\L1ȶQ ŗ^9L +r,H(pOMkP(ڊEI- =po{cPWc#b"JrxZXyޗ۲vpq_ѬP\̄%ƞ2?TڣNbԽcYJyR|E9jZixRo0ny:Ig 6ѾijرZEDɠ,泍k8uFdU)6,EPP%Ox~8d<4wxyQkj mT(䢆Q'~"aݢ2FGt#5B#ЧunHDP .cerS-,B-bY&\b\0&C93z@ UW ۗgarR+0E w16CzκBu@<ѕ HA&AfKZ;~{5m4t q_kkD@&x<-m$H%B Utx36:Gj BeaV nt@\:D^A <ˋKoߢr\c_\XK/Xn5x IqoA؝ckR2pĪo(B2rT$"0E.& d{]<8aJvaUo*R/b2zleNGDX#3a.Q xʄ"*DCը6iXPPgHJu^|eG(:3q V"ՖA@E!^Qo[UȨcumNe o&]X&j JpŋgV:-`,($G7ݬb*,Aj(@JJyd$Sqra-mFf?=]Qq!k˥$ZK֠8\lF,xPHW[ {} }x#0Oi'iTz6@+8v|Fl7y캶]C8Q[ xHlGA&(C98^j1 )^`:8OECh))O[o;\u2d3IOJ?E^$ְR%u|߭QqqeiNtPIFVSFJoYn l(10זH+z*=@Jw.)zB"-9cۭ9r67@{j<..I1pavkJGg%쀐ߡ}x-wggB<&M/w_8d;{ɦdv}⊉ayrXOvxrmReTlj{8e]k_|5m2K">eY(@ c]w#`ӷVBM76rh 0 `] ?:LECD{?o+oBCdeepTools-2.5.0/deeptools/test/test_corrGC/paired.bam.bai0000640000201600010240000000032012757050136022471 0ustar ryanbioinfoBAIIx"Jx"-17xdeepTools-2.5.0/deeptools/test/test_corrGC/sequence.2bit0000640000201600010240000000045412757050136022414 0ustar ryanbioinfoC'Achr2Ln Q ֿjT'=*{{j2cM :! c2Ei(\ұ_zMKN: >Z42::z̚J%b7)+jj h2 i"b*o$0=?>o`"֘9 ^o" ڃ꨺Ji:xL؆ p -xB`j åI7s#**(deepTools-2.5.0/deeptools/test/test_corrGC/sequence.fa0000640000201600010240000000200312757050136022132 0ustar ryanbioinfo>chr2L GAGTATCAGGAAGACCCAGAAATGTTGCTTGACCTCATGAATCGTATTGC CAAGGGATACCAAAATAACCCTGATCTACGACTGACTTGGTTGGAAAATA TGGCTAAAAAACACCGCGAGCGAGCAAATCACACGGAAGCAGCCATGTGT TATGTACATGCTGCTTCTTTAGTTTCTGAATATCTTAGCATGTTGGAGTC ACAAAAACATTTGCCTGTTGGAGCTGTAAGTTTTCAACGAATTTCTCCCA ACACACTAATGGAGTCGGCCGTATCGGATGATGTGCTAAGTCCCGGCGAA GATGGTATCTGCCTAGGAAATCATTTCACTGAAACTGGGTTGAAGGCCTT GCTGGAAGAAGCCTCCAATTCTTTTCAAGTTGCTGGCATGTATGAAGCAA TGAACGAAGTGTACAAAATTCTAATACCCATATGCGAGGCTAACAGAGAT TTTCAAAAGCTAAGCAAAGTTCATGGCAAATTGCAGGAGGCATTTAATCG AATATCCCAACTACAGGTAACAATATTGTGTAAATTTTACCAACGGAAAA TATATACATATTTATAAACAGGGTAAGAGAGTTTTTGGAACATACTTTCG TGTTGGCTTCTATGGCGGAAAATTTGGGGACTTGGATCAGCAGGAATTCA TTTATAAAGAGCCAACATTGACGAAGTTGCCCGAAATATTTAGTCGGCTT CAGGTATATATTGCAAATTGGAAAAAATAGAACTAATCAATTTTGTTTCA ACATACGTTAGAACTTTTACACTGAACGATTCGGACCGGACTCTGTGCAT ATCATTAAAGATTCCAATACCGTTGATATTAATAGCTTGGATCCCGATAA GGCTTACATTCAAATTACTTATGTTGAACCCTACTTTGAAACATATGAAA TGCGTCATCGTGAGACATACTTTGAGCGGAATTTCAATATAAGTATGATA TGAATTAAACAGATAATTTAAATCGaaatttaaaattataattttaaCAT deepTools-2.5.0/deeptools/test/test_corrGC/sequence.fa.fai0000640000201600010240000000002312757050136022670 0ustar ryanbioinfochr2L 1000 7 50 51 deepTools-2.5.0/deeptools/test/test_corrGC/sizes0000640000201600010240000000001412757050136021072 0ustar ryanbioinfochr2L 1000 deepTools-2.5.0/deeptools/test/test_corrGC/test.bam0000640000201600010240000002306312757050136021463 0ustar ryanbioinfoBC[sree``pp 23 *+/*IMr 2&&\@ @lpC! DBC%}[d[VUvHuP3y}|9z ~˯D0Nf\C}} PӢM %6umV#1 ʄQ^[!h_B#"=X2{o4Nk؎y,Nk8gJpm![~ ;xNVWN۞@DmNp;>F B 컨JGѮv+@xA&3Ő܀ d&-1t ;Oz1]4&׏ `*Sk uW8 r`dy ʜ:4yjrM U'!(NToRu)bRF%pOäaI6[8vm|XY,x\8ހ?@qWb ¤ Aؙ,LLİ& _Mzp޶ȟK4+‡)&%$Wۯ٨SO,r$N@Ȑ5%HPj `ł辀8R h;[M:`@qv81>!f<^9aۣUaV`+bB: 9.A89嬟B:הY,Ɔn5E7!+Ĝ#h< !WӀM;~PuX˒2#ŕJ]uMIy4I,d7XgUW~H0a 1PpFHJbθ@D2Meܻѕh@)J2b_R7mq2 ֟1; I ֙/u0Y`1E{B. ,GE{VUHi?SWn@ 4!V8nXo[?iC +dyE*'d&ۍ.,S@.5ވ\h@f?cU¥`b`gm*mAyƵn7+E;SiW>QS @c^]|Yכm6;_#E[Xk@_C{kcA 9֓0Uy)QN3]y [f,8u3k˛8d@wpPqW>6PٟbQ ˀi-4 (VuR28y =Y~lD%l<˪M;o 0*` V <\.!9~ =9hbSif.Ʀ<⽾8jkYM]@6VWMSuJӉ[veZdImں}@oݻh~R{V{<h£s?oT&j u}:!jt7~<lY&] t@[0`xTF(%r}av&~ƴU#!Ƥ*"TVL@#p=V9ЗV_ /d@aҪ1^:kzSqs@ix#ß1ګ ޼=Cv2hZc'&k)it:AuP(JY[)]97ly%p(pV2nדI(2廈 <'""0hlWvͱÔGZ+Ce5ֺrdՕ;nxP 3]DZk^BzjX@!:8v[Dܴ.x׍!Q$N"UB\z`˜4nEUgktׅݎd7qr+c$M%'pMU.A{IkÝ{_k*G .tIQP]R02Pc4y yXg8ڔf/s?X8 jVMz>GM7g6N3iY@$c=`w =v na* *6.\{<0g*ύӸYEcnڎ[w')ꈩǸZj8oy{6ihw? 떜 ':JA̍CI_لLeI^Caz4ô>mѱĪy-~qbCk*8hfH}J\CwO,"k=VujX`oo!x^6,Q\ /hmX]\8~C6D(8QH]ɗ01כ @( j4[$WKzu:BR/$LH\SJ9voP qa`Մ0ju@FԜNwu&Te慃e-KLx ASPnGn@C U@0 y> l Hʀ H'Df{8Ķ$XNLnϮVnĜ)֥SJeJ pfٺnb;,J%uS|,?g~z9&f/\s k :KV:wJ!zG "\~:NlHA(L\U"OMޕTaoד /'ן/(!/?8=߂{bt?g[xt uWI+ Ȗk`ԗNJ%qJb DMǭ@Uy1Xh?$vSa: =@ 57 YfE˴^6yiFz{CѾ !BNˤ58!ӹp un`H/Y„*9b*- _Ⱥr\q*Ԕ;M籈o:ϝO+*dB8 2BݏMNffU"5i؀h4hno m-vsP$4XR0ۅb8~EE0+tB3j!^-Khd_Cz[?m`Gbj]{}bAe 8t~7h\\Y *ϑ]@j:#`oe DL )M!RUW1k€66S2w]Ľ9G* [.Ci`<-$ 9jSz2*A ,G4@!@q"zDh^SI%._$yUvgZ"^SxOV'ŴȎ4A2})D$ &ٛ:YսxjUuY&,-n¶wn@H6WB#ᙵ}Έ~Ԫ. (bM_ 6 UPM@cRɹ߂!x;l}!y9ݗ 2=E$_ݦ!gO8(v +pY0EH SJk_;/=b)$'i<֤X6r\ vz!${d/c(JA5u!@g!gXP#kM!*3޴oq–UCZaBc dB U(BV{8{ӳ5/4,!qL3se@t}U]{<L&4#Tv: ~%jrgك7``+L|L)3 #KBr9e0{cx]*35G޴*V+­r.'g)vtMįdmS <ˍx5aDkǻC`B/GJlbMq0+Ml D:|f^^^*!ጆS"q(pNf_&qd 4e˲S ufp[?|;8l1K G=2 }Ղ"(BٲMboN~U!{AGn$O E3 '$yxeS1CurX%"tF0]Tᅍ*ῢ.߸ \PVcubp €&4fQlH`aHԷE1}X_0$]EcMyH!TE3 pHH¡vrMEc)k 9z8el괲Nx }mQǩ9KׇsujO1 ~Bxa˝~xTRU!8PoؘU*ak`*BҪm/tpq%OB*>^B =.DWڤ*SЄ6Q:ruwoicĮݟMY(ײV t :'zt2bOa| ]ǦzMЃ(*-cWlE\(c{E]-#@X&fEp@r5yr 5܀'u߽_6P@lkZ͎TDQBigQ'Įk@a3+T:bK~݃V /ԃ A Huێ/0ëpWSU}R)8xBL/:]Xۤ ZA7Yy1vt*LH EDK8=z>;˼HWWO9 6:Y*Ԧu P@:I<] sEP)X7094{ eY-+c68D FsuN/japM,Mq;ٮHp`.W+GYT;3 .$Fo.81~Xwcd)Yo_tN!{9Ʀ>`T`]t4`'e{(J\o}s!}gmX!$u]wS׽mWrh^}YVUfzgcZbT bQ3"#Hzt>.9Э#w}v}>@ęH\+{j ]F*5-k3vT`B]t>Jqr XS8ҍ t,ntvBq\u!:t`k G&VPWD]ГORR,ЂXWef֕GnG^&L=ny,pCDSٿgJY3*O?I #3'qG3^.U}:Q͘%/ \={ o@Ȕ_M!pq0]s:י+~h*uxDnvN?i [ =+VlE] YkVYn| T<=fr$M^+Ys;_l mV$ZM0) )\'nmxs=RSw 1V֩ I-:!vʋ_q|S*lg)d͡aYk, k#ĭ߰QV ^6}iǝ88;pp>✹/#| |'F &s;eê.SS0U;z97~`O̰AY:is뿱P:VWMkݎ.qw[HeɚnMd;!2m[]!^eߥ߶oa[0??xw7e;_߷sYcy)%a7{_$?=u-O3bT76wex펟U=@6bU2ׁJ712eؐâ,"+:WKql|;t~[6.KYV te՘K8#AxǓB0׸g-[ɂk@%eYwGt5S>%UqdSzF< o[xW]x˰d!s1=!0Dٙ#K|g:_l諪T @$e~h5݃#pqm}1k<>Ч-1]2DK zA"ÆXL!=|XA s 0>=.>*Vx3뮀KvwP}W̗Q#|JJIfl >r`3VE^3in\vYR#߃qᖜVP/UظNLYզ);$V~/"|e\ S1%ņ1ڛЋgx?8}e-&F?[)~m]`O 9>^MW0gT/=&^@K3 %P>6SKrMlqk8d%yĿNYfBCdeepTools-2.5.0/deeptools/test/test_corrGC/test.bam.bai0000640000201600010240000000014012757050136022204 0ustar ryanbioinfoBAII\3&J\3&\deepTools-2.5.0/deeptools/test/test_corrGC/test.sam0000640000201600010240000011312012757050136021476 0ustar ryanbioinfo@HD VN:1.0 SO:unsorted @SQ SN:2L LN:23011544 DD61XKN1:97:COBJ7ACXX:6:1304:14465:187787 0 2L 2 255 51M * 0 0 AGTATCAGGAAGACCCAGAAATGTTGCTTGACCTCATGAATCGTATTGCCA @@?DDBD?G XA:i:0 MD:Z:51 NM:i:0 DD61XKN1:97:COBJ7ACXX:6:2105:11023:179557 16 2L 12 255 51M * 0 0 AGACCCAGAAATGTTGCTTGACCTCATGAATCGTATTGCCAAGGGATACCA BG?CEHGIF@GGJIIGB?<9CIHGHHHHGAEDFIHFGF?;?AFDDEDD@@@ XA:i:0 MD:Z:51 NM:i:0 DD61XKN1:97:COBJ7ACXX:6:1304:5656:150699 0 2L 17 255 51M * 0 0 CAGAAATGTTGCTTGACCTCATGAATCGTATTGCCAAGGGATACCAAAATA CCCFFFFFHHHHHJJGIJJJJJJIHGJJGGJJJIJIJJJJIIJJJJJIIJJ XA:i:0 MD:Z:51 NM:i:0 DD61XKN1:97:COBJ7ACXX:6:1304:8200:170238 0 2L 19 255 51M * 0 0 GAAATGTTGCTTGACCTCATGAATCGTATTGCCAAGGGATACCAAAATAAC ?@@FBDDDHHGHAHHIJCGGDFHIHGHGIJJJGGIGIII3DHIGGGHIIJJ XA:i:0 MD:Z:51 NM:i:0 DD61XKN1:97:COBJ7ACXX:6:1305:18486:172550 16 2L 21 255 51M * 0 0 AATGTTGCTTGACCTCATGAATCGTATTGCCAAGGGATACCAAAATAACCC JIGJJIJJIIHDJJJIHBJIIIHHIIIJJJIIJJIIHGFHHHHFFDDDCCB XA:i:0 MD:Z:51 NM:i:0 DD61XKN1:97:COBJ7ACXX:6:2307:2321:170436 0 2L 27 255 51M * 0 0 GCTTGACCTCATGAATCGTATTGCCAAGGGATACCAAAATAACCCTGATCT CC@FFFDFHHHHHIFIJJEBGGHGIIJJIJGGEGEHIGIJJJAHHIIHIII XA:i:0 MD:Z:51 NM:i:0 DD61XKN1:97:COBJ7ACXX:6:1207:5255:137547 0 2L 28 255 51M * 0 0 CTTGACCTCATGAATCGTATTGCCAAGGGATACCAAAATAACCCTGATCTA CCCFFFFFHGHHGIIGJHIHIHGIIJIIIGGIJJIJJIIJJEHJJJJJJJD XA:i:0 MD:Z:51 NM:i:0 DD61XKN1:97:COBJ7ACXX:6:1304:3130:106740 0 2L 32 255 51M * 0 0 ACCTCATGAATCGTATTGCCAAGGGATACCAAAATAACCCTGATCTACGAC CCCFFFFFHHGHHJJJJJJIIJJJJGHIJJJJJJJIJIJJJJIIIIGJJJI XA:i:0 MD:Z:51 NM:i:0 DD61XKN1:97:COBJ7ACXX:6:2306:8891:14840 0 2L 32 255 51M * 0 0 ACCTCATGAATCGTATTGCCAAGGGATACCAAAATAACCCTGATCTACGAC =;?BBBDDFHDFHFBBD4B>@@G@?3A;DGCED XA:i:0 MD:Z:51 NM:i:0 DD61XKN1:97:COBJ7ACXX:6:1205:9633:61290 0 2L 105 255 51M * 0 0 TAAAAAACACCGCGAGCGAGCAAATCACACGGAAGCAGCCATGTGTTATGT @@@DDDFDFDHHFI1C:DDG>EHIIICEHIIFGIAEHAA?9?CFF>CADC@ XA:i:0 MD:Z:51 NM:i:0 DD61XKN1:97:COBJ7ACXX:6:2108:16953:173164 0 2L 105 255 51M * 0 0 TAAAAAACACCGCGAGCGAGCAAATCACACGGAAGCAGCCATGTGTTATGT CCCFFFFFHHHHHJIIIJHJJIJJJJJJJJJJIIJHHHHFEFFDBCEEEED XA:i:0 MD:Z:51 NM:i:0 DD61XKN1:97:COBJ7ACXX:6:2306:11917:55163 16 2L 105 255 51M * 0 0 TAAAAAACACCGCGAGCGAGCAAATCACACGGAAGCAGCCATGTGTTATGT =ACGHC@FGHGHHGGGGGC@@ECC=CEBE;=.;;@ XA:i:0 MD:Z:51 NM:i:0 DD61XKN1:97:COBJ7ACXX:6:1108:18039:70045 0 2L 112 255 51M * 0 0 CACCGCGAGCGAGCAAATCACACGGAAGCAGCCATGTGTTATGTACATGAG @@@FFFFFDDHFH>DBFGGIIIIIIIIIGGHE@6=F=DHGEAA7@CCHCFH XA:i:0 MD:Z:49C0T0 NM:i:2 DD61XKN1:97:COBJ7ACXX:6:2302:8293:92003 16 2L 113 255 51M * 0 0 ACCGCGAGCGAGCAAATCACACGGAAGCAGCCATGTGTTATGTACATGCTG @JJIJJJJJIIIGJJIHG>IHJJJJJJIJJJJJJJJJJHHHHHFFFFFCCC XA:i:0 MD:Z:51 NM:i:0 DD61XKN1:97:COBJ7ACXX:6:1206:17788:76420 0 2L 117 255 51M * 0 0 CGAGCGAGCAAATCACACGGAAGCAGCCATGTGTTATGTACATGCTAGATC @@@DBDFFGHGHFIGGGIIIEH:ADGHEIGD*??DEA23A:C=2+B48== XA:i:0 MD:Z:51 NM:i:0 DD61XKN1:97:COBJ7ACXX:6:2301:9302:70963 16 2L 118 255 51M * 0 0 GAGCGAGCAAATCACACGGAAGCAGCCATGTGTTATGTACATGCTGCTTCT JJIGJIIIJJIGHFIGJJJJJJJJJJJJJJJJJJJJJJHHHHHFFFFFCCC XA:i:0 MD:Z:51 NM:i:0 DD61XKN1:97:COBJ7ACXX:6:1108:5503:182542 16 2L 120 255 51M * 0 0 GCGAGCAAATCACACGGAAGCAGCCATGTGTTATGTACATGCTGCTTCTTT 0?DED>GFB@GB8CDDFFF?FEGIGIIIAHGIIIGIIIIIIII9EGAGIEBCGEGIGB XA:i:0 MD:Z:51 NM:i:0 DD61XKN1:97:COBJ7ACXX:6:1102:12979:59008 16 2L 138 255 51M * 0 0 AGCAGCCATGTGTTATGTACATGCTGCTTCTTTAGTTTCTGAATATCTTAG JJJIJJIIJJJJJIJJIGHJJJJJJJJJJJIJJIJJJJHHHHHFFFFFCCC XA:i:0 MD:Z:51 NM:i:0 DD61XKN1:97:COBJ7ACXX:6:1206:9329:69872 16 2L 138 255 51M * 0 0 AGCAGCCATGTGTTATGTACATGCTGCTTCTTTAGTTTCTGAATATCTTAG HIIGIIGJIJJIJIJJIGIJJIHIJJIIGJIJIJJJIIGHGGHFFDFFCC@ XA:i:0 MD:Z:51 NM:i:0 DD61XKN1:97:COBJ7ACXX:6:2103:16418:25318 16 2L 144 255 51M * 0 0 CATGTGTTATGTACATGCTGCTTCTTTAGTTTCTGAATATCTTAGCATGTT H>JJJJJJJJJHIJJJJJIIIJIJIJJJJJJJJJJJJJHHGHHFFFFFCCC XA:i:0 MD:Z:51 NM:i:0 DD61XKN1:97:COBJ7ACXX:6:2306:20617:39460 16 2L 147 255 51M * 0 0 GTGTTATGTACATGCTGCTTCTTTAGTTTCTGAATATCTTAGCATGTTGGA JJJJIJJJIIJJJJJJJJJJIIJJJJJJJJJJJJIJJJHHHHHFFFFFCCC XA:i:0 MD:Z:51 NM:i:0 DD61XKN1:97:COBJ7ACXX:6:1306:11689:51296 0 2L 148 255 51M * 0 0 TGTTATGTACATGCTGCTTCTTTAGTTTCTGAATATCTTAGCATGTTGGAG @@@FDDADBFF8FGIIGIDCFHIGBHHGIJJIJE@GGIJJIIJEIAHDHHI XA:i:0 MD:Z:51 NM:i:0 DD61XKN1:97:COBJ7ACXX:6:1304:20062:21791 16 2L 151 255 51M * 0 0 TATGTACATGCTGCTTCTTTAGTTTCTGAATATCTTAGCATGTTGGAGTCA JJJIIJIJIJJJJJJJJJJJJJJJJJJJJJJJJJJJJJHHHHHFFFFFCCC XA:i:0 MD:Z:51 NM:i:0 DD61XKN1:97:COBJ7ACXX:6:2102:19935:152156 16 2L 153 255 51M * 0 0 TGTACATGCTGCTTCTTTAGTTTCTGAATATCTTAGCATGTTGGAGTCACA JIIIJIGHHGIIIGJIJJJJJJGJIJJJIIJJJIJJJIHHHHHFFFFFCCC XA:i:0 MD:Z:51 NM:i:0 DD61XKN1:97:COBJ7ACXX:6:2306:17010:6596 16 2L 153 255 51M * 0 0 TGTACATGCTGCTTCTTTAGTTTCTGAATATCTTAGCATGTTGGAGTCACA JIIJJJJJIJJJJJIJJJJJJJJJJJJJJJJJIJJJJJHHHHHFFFFFCCC XA:i:0 MD:Z:51 NM:i:0 DD61XKN1:97:COBJ7ACXX:6:1206:8566:197557 16 2L 158 255 51M * 0 0 ATGCTGCTTCTTTAGTTTCTGAATATCTTAGCATGTTGGAGTCACAAACAC EJJJJIIGGGGGIGHIHEHBGIIIJIIJIGGJIJIHEIGHHHHDFFDD@@? XA:i:1 MD:Z:48A2 NM:i:1 DD61XKN1:97:COBJ7ACXX:6:1307:11048:127938 0 2L 161 255 51M * 0 0 CTGCTTCTTTAGTTTCTGAATATCTTAGCATGTTGGAGTCACAAACACATT @@@DFFADHDHHHGGIEIHEG>IFHE?FHHHGAECFFGFEEHIIIIIEDHI XA:i:0 MD:Z:45A5 NM:i:1 DD61XKN1:97:COBJ7ACXX:6:1204:11281:93412 16 2L 163 255 51M * 0 0 GCTTCTTTAGTTTCTGAATATCTTAGCATGTTGGAGTCACAAACACATTTG JJJIJJJJIICHIJJJJIJIJJJJJJJJJJIJJJJJGJHHHHHFFFFFCCC XA:i:1 MD:Z:43A7 NM:i:1 DD61XKN1:97:COBJ7ACXX:6:1105:16101:180301 0 2L 181 255 51M * 0 0 TATCTTAGCATGTTGGAGTCACAAACACATTTGCCTGTTGGAGCTGTAAGT AEF?GHEFHEBBBD:??FB XA:i:1 MD:Z:25A25 NM:i:1 DD61XKN1:97:COBJ7ACXX:6:1307:14338:192440 0 2L 184 255 51M * 0 0 CTTAGCATGTTGGAGTCACAAACACATTTGCCTGTTGGAGCTGTAAGTTTT GHGGI?DHIGGDGHIJJGG XA:i:1 MD:Z:22A28 NM:i:1 DD61XKN1:97:COBJ7ACXX:6:1103:12859:144897 16 2L 186 255 51M * 0 0 TAGCATGTTGGAGTCACAAACACATTTGCCTGTTGGAGCTGTAAGTTTTCA HIEJIHGIGHFGGIIHIGGIHECEHIIJJGJJJIJIIEHHFHHFFFFFCCC XA:i:0 MD:Z:20A30 NM:i:1 DD61XKN1:97:COBJ7ACXX:6:2107:7805:110890 16 2L 187 255 51M * 0 0 AGCATGTTGGAGTCACAAACACATTTGCCTGTTGGAGCTGTAAGTTTTCAA IIJIIJJIIIIGJJJIJJGIGJJIIJFJIJJIIIJJIIHHHHHFFFFFC@C XA:i:0 MD:Z:19A31 NM:i:1 DD61XKN1:97:COBJ7ACXX:6:1102:1861:107928 0 2L 192 255 51M * 0 0 GTTGGAGTCACAAACACATTTGCCTGTTGGAGCTGTAAGTTTTCAACGAAT @?@DDDDFFBHHHJEGIIGIGIIJGHIJJJIIGHJGHIICFHIJIIJIIJI XA:i:1 MD:Z:14A36 NM:i:1 DD61XKN1:97:COBJ7ACXX:6:2308:20330:196190 16 2L 192 255 51M * 0 0 GTTCGAGTCACAAACACATTTGCCTGTTGGAGCTGTAAGTTTTCAACGAAT D90)JIIGHHEEFCGBJIHIIIJJIJJJJJJIHGJJIIHGHHHDFFFD@@@ XA:i:0 MD:Z:3G10A36 NM:i:2 DD61XKN1:97:COBJ7ACXX:6:1201:12265:85344 0 2L 200 255 51M * 0 0 CACAAACACATTTGCCTGTTGGAGCTGTAAGTTTTCAACGAATTTCTCCCA CCCFFFFFHHHHHIIJJJJIJJJJJIJIIJJIJJJGIJIJJIJJIGIGGGI XA:i:1 MD:Z:6A44 NM:i:1 DD61XKN1:97:COBJ7ACXX:6:2308:10209:45972 16 2L 201 255 51M * 0 0 ACAAACACATTTGCCTGTTGGAGCTCTAAGTTTTCAACGAATTTCTCCCAA GHGIIHDIIIIHG=GGIIG@JIGHCFFHIIAH:DDGGGDFECGFBG@AGH>>D XA:i:0 MD:Z:51 NM:i:0 DD61XKN1:97:COBJ7ACXX:6:1203:19077:54250 16 2L 245 255 51M * 0 0 ATCTCAACACCCTAATGGAGTCGGCCGTATCGGATGATGTGCTAAGTCCCG ??=)6(-;.@4CBB@=B@60)AADDE?@?DFDEE?AC:DCAFGGIGIIIFIIBEE XA:i:0 MD:Z:48G0A1 NM:i:2 DD61XKN1:97:COBJ7ACXX:6:1201:1270:36522 16 2L 251 255 51M * 0 0 ACACACTAATGGAGTCGGCCGTATCGGATGATGTGCTAAGTCCCGGCGAAG EEEEEFFFFFFFHHIGJJJJJIIJJJJJJJJJJJJJJJHHHHHFFFDFCCC XA:i:0 MD:Z:51 NM:i:0 DD61XKN1:97:COBJ7ACXX:6:1208:4869:36164 16 2L 251 255 51M * 0 0 ACACACTAATGGAGTCGGCCGTATCGGATGATGTGCTAAGTCCCGGCGAAG B@AA;D>FFEFFHHJJIJJIGGGIJJJJIFJIJIJIIJGHHHHFFFFFCCC XA:i:0 MD:Z:51 NM:i:0 DD61XKN1:97:COBJ7ACXX:6:2302:8813:117992 16 2L 251 255 51M * 0 0 ACACACTAATGGAGTCGGCCGTATCGGATGATGTGCTAAGTCCCGGCGAAG EEEDCFDFFFFFHHJIJJJIJJJJJJJJJJJJIJJJJJHHHHHFFFFFCCC XA:i:0 MD:Z:51 NM:i:0 DD61XKN1:97:COBJ7ACXX:6:2306:2156:189168 16 2L 251 255 51M * 0 0 ACACACTAATGGAGTCGGCCGTATCGGATGATGTGCTAAGTCCCGGCGAAG EECEADBD@FFFHEGGBIIJJJJIJJIIJJIJJJJJJJHHHFHFFFDDCC@ XA:i:0 MD:Z:51 NM:i:0 DD61XKN1:97:COBJ7ACXX:6:2108:20676:200337 16 2L 253 255 51M * 0 0 CCCTTAATGGAGTCGGCCGTATCGGATGATGTGCTAAGTCCCGGCGAAGAT ####@EDBFFEHEE;>IIIGHBJJIHHBIIIIEJIJIHHHHFC@+FFD?@? XA:i:0 MD:Z:0A1A0C47 NM:i:3 DD61XKN1:97:COBJ7ACXX:6:2303:4499:87063 16 2L 253 255 51M * 0 0 ACACTAATGGAGTCGGCCGTATCGGATGATGTGCTAAGTCCCGGCGAAGAT @EEEEEDFFFFEAJIGHIHHBCJJIGGGGIJJIIIGGHHHDHHFFFFFCC@ XA:i:0 MD:Z:51 NM:i:0 DD61XKN1:97:COBJ7ACXX:6:2301:12873:140362 0 2L 254 255 51M * 0 0 CACTAATGGAGTCGGCCGTATCGGATGATGTGCTAAGTCCCGGCGAAGATG CCCFFFFFHHHHHIJJJJJJJJJJIIJIJIIIGIJJIIIJJJJIIHFFDEE XA:i:0 MD:Z:51 NM:i:0 DD61XKN1:97:COBJ7ACXX:6:2307:13419:129801 0 2L 256 255 51M * 0 0 CTAATGGAGTCGGCCGTATCGGATGATGTGCTAAGTCCCGGCGAAGGTGGG @@@FFFDDFBDHHBIIBAHGHEHCH??D?DAG@FC?DBDGGFHAA>DFEEIIJIHGJIHGIHG?GGGGIIGGJJJIJJJJHHHHHFFDFF@CC XA:i:0 MD:Z:51 NM:i:0 DD61XKN1:97:COBJ7ACXX:6:1208:21153:74484 0 2L 260 255 51M * 0 0 TGGAGTCGGCCGTATCGGATGATGTGCTAAGTCCCGGCGAAGATGGTATCT @C@FFDEFAHGHFHGIJGGHEDGGIIGIEEGHGGGIIGGGFEBBDD@CC>B XA:i:0 MD:Z:51 NM:i:0 DD61XKN1:97:COBJ7ACXX:6:2101:13440:96989 0 2L 260 255 51M * 0 0 TGGAGTCGGCCGTATCGGATGATGTGCTAAGTCCCGGCGAAGATGGTATCT CCCFFFFFHHHHHJJJIJIJJIJJIJIIJJJIIIIJJIIJHGFFFF>CEEE XA:i:0 MD:Z:51 NM:i:0 DD61XKN1:97:COBJ7ACXX:6:1104:11297:23938 0 2L 261 255 51M * 0 0 GGAGTCGGCCGTATCGGATGATGTGCTAAGTCCCGGCGAAGATGGTATCTG ?@@D1BD8DHDAFGFCBGGCG8:@4@A@# XA:i:0 MD:Z:51 NM:i:0 DD61XKN1:97:COBJ7ACXX:6:1302:16303:101241 0 2L 261 255 51M * 0 0 GGAGTCGGCCGTATCGGATGATGTGCTAAGTCCCGGCGAAGATGGTATCTG @@@DDDDFHGHFGIIIIGIIJIJJJIIIGGFBHIIHEHBHEG@BF;3?;B> XA:i:0 MD:Z:51 NM:i:0 DD61XKN1:97:COBJ7ACXX:6:2103:10328:49800 16 2L 262 255 51M * 0 0 GAGTCGGCCGTATCGGATGATGTGCTAAGTCCCGGCGAAGATGGTATCTGC @C@BDBBD=FFFFC=.888BCIFF@B90FEEFCF=CFAEIB=,B1;;; XA:i:0 MD:Z:51 NM:i:0 DD61XKN1:97:COBJ7ACXX:6:1107:9046:65823 16 2L 273 255 51M * 0 0 ATCGGATGATGTGCTAAGTCCCGGCGAAGATGGTATCTGCCTAGGAAATCA DJHGGHGEJIIG@JIIGGDEJGHHFDJJHGHFHGHHGBHBAHFD8FFF@@@ XA:i:0 MD:Z:51 NM:i:0 DD61XKN1:97:COBJ7ACXX:6:1205:16702:86065 16 2L 273 255 51M * 0 0 ATCGGATGATGTGCTAAGTCCCGGCGAAGATGGTATCTGCCTAGGAAATCA IHIIFIIIIIGCIGGIHF@GIIIIIIIHEFCIIHFB?GHFDGHFFFDFCCC XA:i:0 MD:Z:51 NM:i:0 DD61XKN1:97:COBJ7ACXX:6:2207:9123:81043 0 2L 275 255 51M * 0 0 CGGNTGGTGTGCTAAGTCCCGGCGAAGATGGTATCNGCCTAGGAAATNATT ?@@#4A22AAFHFGEGFHGGIGDGHIIIIII9DBF#-DFF4?<@C<8=FC@F9CF=7 XA:i:0 MD:Z:51 NM:i:0 DD61XKN1:97:COBJ7ACXX:6:2307:1821:56847 16 2L 291 255 51M * 0 0 TCCCGGCGAAGATGGTATCTGCCTAGGAAATCATTTCACTGAAACTGGGTT JIHIJJJJIJJJJIJJJJJJJJJJIJJJJJIJJJJJJIHHHHHFFFFFCCC XA:i:0 MD:Z:51 NM:i:0 DD61XKN1:97:COBJ7ACXX:6:1108:6855:132514 16 2L 292 255 51M * 0 0 CCCGGCGAAGATGGTATCTGCCTAGGAAATCATTTCACTGAAACTGGGTTG JIJGJJJJJJIJJJIJIJJIJJIHJJJIHBJJGJJJIJGHHGHFFFFF@@B XA:i:0 MD:Z:51 NM:i:0 DD61XKN1:97:COBJ7ACXX:6:1307:18891:60022 0 2L 298 255 51M * 0 0 GAAGATGGTATCTGCCTAGGAAATCATTTCACTGAAACTGGGTTGAAGGCC @@@FDDEFHHHHHJJJJJJJIIJJIJIIGJGHJJJGIIGIIJDHHJJJJJJ XA:i:0 MD:Z:51 NM:i:0 DD61XKN1:97:COBJ7ACXX:6:1101:19397:5078 0 2L 299 255 51M * 0 0 AAGATGGTATCTGCCTAGGAAATCATTTCACTGAAACTGGGTTGAAGGCCT @@CDDFFFHHHHHJJJJJJIJJJJJJJJGDHIJJJJJJIJJIIJJJJJHII XA:i:0 MD:Z:51 NM:i:0 DD61XKN1:97:COBJ7ACXX:6:1205:3808:46142 16 2L 302 255 51M * 0 0 ATGGTATCTGCCTAGGAAATCATTTCACTGAAACTGGGTTGAAGGCCTTGC GGHGGIGIIIIIIIIGIIGEGGGHEHABIIIIIIGHGIHHDDHD;?DD@@@ XA:i:0 MD:Z:51 NM:i:0 DD61XKN1:97:COBJ7ACXX:6:2301:2533:6592 16 2L 303 255 51M * 0 0 TGGTATCTGCCTAGGAAATCATTTCACTGAAACTGGGTTGAAGGCCTTGCT GHIIJJJIJJJJJJIJJJIJJJJJIIJJJJJIJJJJJJHHHHHFFFFFCCC XA:i:0 MD:Z:51 NM:i:0 DD61XKN1:97:COBJ7ACXX:6:2304:17062:148239 16 2L 306 255 51M * 0 0 TATCTGCCTAGGAAATCATTTCACTGAAACTGGGTTGAAGGCCTTGCTGGA IJIJIEIIJJIJIGIHIGIJGIGJGJJIIJJIGGGGGIHB=HHFDFFF@CC XA:i:0 MD:Z:51 NM:i:0 DD61XKN1:97:COBJ7ACXX:6:2308:2095:33008 0 2L 307 255 51M * 0 0 ATCTGCCTAGGAAATCATTTCACTGAAACTGGGTTGAAGGCCTTGCTGGAA ;8@DDDDDBH>?FHF:F>CHH@EHIGIIIIIEFCF3:B?GGGBIHAHHAHDFFDF@@@ XA:i:0 MD:Z:51 NM:i:0 DD61XKN1:97:COBJ7ACXX:6:1107:15167:131846 16 2L 366 255 51M * 0 0 CAATTCTTTTCAAGTTGCTGGCATGTATGAAGCAATGAACGAAGTGTACAA GEFBHG@IHEIGIIJIIIIGIGIFCIIHCGIGIEIIGJHGHGHFFFFF@CC XA:i:0 MD:Z:51 NM:i:0 DD61XKN1:97:COBJ7ACXX:6:1108:1279:80195 0 2L 387 255 51M * 0 0 CATGTATGAAGCAATGAACGAAGTGTACAAAATTCTAATACCCATATGCGA @@CFFFFFHHHHHIJJJJJIJJJHIIGIIJJIJJIIJJJIJJJJJJJIIJI XA:i:0 MD:Z:51 NM:i:0 DD61XKN1:97:COBJ7ACXX:6:1206:17772:153344 0 2L 387 255 51M * 0 0 CATGTATGAAGCAATGAACGAAGTGTACAAAATTCTAATACCCATATGCGA @<@DDFFFFDGHHJJGIJJIJIIDFIHIIJIIJJIJIJJIIIIJJIJI@GH XA:i:0 MD:Z:51 NM:i:0 DD61XKN1:97:COBJ7ACXX:6:2102:5591:82195 0 2L 392 255 51M * 0 0 ATGAAGCAATGAACGAAGTGTACAAAATTCTAATACCCATATGCGAGGCTA CCCFFFFFHHHHHJJJJJJJJJJJJJJJJJJIJJJJJJIJJJJJJIJJJJJ XA:i:0 MD:Z:51 NM:i:0 DD61XKN1:97:COBJ7ACXX:6:2301:16432:177637 0 2L 394 255 51M * 0 0 GAAGCAATGAACGAAGTGTACAAAATTCTAATACCCATATGCGAGGCTAAC @@@DDDFFDDDBHHGIG>HCFEHEFHIDHHGH@HIEFG>FIHEHHGHCEGB XA:i:0 MD:Z:51 NM:i:0 DD61XKN1:97:COBJ7ACXX:6:2305:10443:61453 0 2L 395 255 51M * 0 0 AAGCAATGAACGAAGTGTACAAAATTCTAATACCCATATGCGAGGCTAAGA CCCFFFFFHHHHHJIHIHGIJJJJJJJJIJJJJJJIJIIJJJJJJJIJIII XA:i:0 MD:Z:49C1 NM:i:1 DD61XKN1:97:COBJ7ACXX:6:1305:12300:195423 16 2L 396 255 51M * 0 0 AGCAATGAACGAAGTGTACAAAATTCTAATACCCATATGCGAGGCTAACAG IGGGHGADBF@IHBGHD;IEIHBCIIHF?AAIHFBGA)DF?HF?ADDD@@@ XA:i:0 MD:Z:51 NM:i:0 DD61XKN1:97:COBJ7ACXX:6:1301:2252:57537 16 2L 403 255 51M * 0 0 AACGAAGTGTACAAAATTCTAATACCCATATGCGAGGCTAACAGAGATTTT JJIIJJJIHHJJJJJIFHFCIIGHJJJIHIIJJIHJIHBHHHHFFFFFCCC XA:i:0 MD:Z:51 NM:i:0 DD61XKN1:97:COBJ7ACXX:6:2307:15958:126504 0 2L 404 255 51M * 0 0 ACGAAGTGTACAAAATTCTAATACCCATATGCGAGGCTAACAGAGATTTTC @@CFFFFFHHHHHJJJJJJJJJJJJJJJJJJJJJIJJJIIIJJJJJJJJJJ XA:i:0 MD:Z:51 NM:i:0 DD61XKN1:97:COBJ7ACXX:6:1106:8340:77588 0 2L 414 255 51M * 0 0 CAAAATTCTAATACCCATATGCGAGGCTAACAGAGATTTTCAAAAGCTAAG @CCFFFFFHHHHHJJIJJJJJJJIIIIJJJIIJJJIIIJJJJJIJJJJJJJ XA:i:0 MD:Z:51 NM:i:0 DD61XKN1:97:COBJ7ACXX:6:1206:20077:11499 16 2L 416 255 51M * 0 0 AAATTCTAATACCCATATGCGAGGCTAACAGAGATTTTCAAAAGCTAAGCA IJHIGEJJIHDJJJHGIGJIJIGIHHJJIJJJIJIIIGHHHHFBFDFFCC@ XA:i:0 MD:Z:51 NM:i:0 DD61XKN1:97:COBJ7ACXX:6:1203:17030:154608 0 2L 425 255 51M * 0 0 TACCCATATGCGAGGCTAACAGAGATTTTCAAAAGCTAAGCAAAGTTCATG CCCFFFFFHHHH1FHJJGIJJJJIIJJJJJJJJJJJJIIJIGGGHHGIHIJ XA:i:0 MD:Z:51 NM:i:0 DD61XKN1:97:COBJ7ACXX:6:1107:20142:132171 16 2L 429 255 51M * 0 0 CATATGCGAGGCTAACAGAGATTTTCAAAAGCTAAGCAAAGTTCATGGCAA JJJIGGGGIIIICIJIIEHGIJIJIJJIGHGIGJIGJJGHFHHFFDFFCC@ XA:i:0 MD:Z:51 NM:i:0 DD61XKN1:97:COBJ7ACXX:6:2105:20333:148776 0 2L 435 255 51M * 0 0 CGAGGCTAACAGAGATTTTCAAAAGCTAAGCAAAGTTCATGGCAAATTGCA @C@FFFFFHHHHGJHIJJJIJJJJJIIJIJJJJJJGHIEIJJIJJIHIIII XA:i:0 MD:Z:51 NM:i:0 DD61XKN1:97:COBJ7ACXX:6:1207:11431:60533 16 2L 441 255 51M * 0 0 TAACAGAGATTTTCAAAAGCTAAGCAAAGTTCATGGCAAATTGCAGGAGGC HIIJJJIIJJJIHHIJJIIHFJIIGIJJHJJJIIJJJJHFGHHFFFFFCCC XA:i:0 MD:Z:51 NM:i:0 DD61XKN1:97:COBJ7ACXX:6:2108:9521:60699 16 2L 450 255 51M * 0 0 TTTTCAAAAGCTAAGCAAAGTTCATGGCAAATTGCAGGAGGCATTTAATCG JJIIGJIHIJJIIJJJJJJGIJJIIJJJJJJJJJIJIJGHHHHFFFFFC@@ XA:i:0 MD:Z:51 NM:i:0 DD61XKN1:97:COBJ7ACXX:6:1202:8970:170602 0 2L 453 255 51M * 0 0 TCAAAAGCTAAGCAAAGTTCATGGCAAATTGCAGGAGGCATTTAATCGAAT CCCFFFFFHHHHHJJJJJJJJJJIJIJJIJJIJJIJJJJJJJJBIIGGHJJ XA:i:0 MD:Z:51 NM:i:0 DD61XKN1:97:COBJ7ACXX:6:2107:8693:164773 0 2L 457 255 51M * 0 0 AAGCTAAGCAAAGTTCATGGCAAATTGCAGGAGGCATTTAATCGAATATCC @@@FFFFFHHHDHFHGGGJJJJJIJJJIJIHGHFIIJJJJIGGIIIGGIBF XA:i:0 MD:Z:51 NM:i:0 DD61XKN1:97:COBJ7ACXX:6:2307:18419:157090 16 2L 460 255 51M * 0 0 CTAAGCAAAGTTCATGGCAAATTGCAGGAGGCATTTAATCGAATATCCCAA IJJJJJJJJJJIJJJJJJJJIJJJJJJJJJJJJIIJJJHHHHHFFFFFCCC XA:i:0 MD:Z:51 NM:i:0 DD61XKN1:97:COBJ7ACXX:6:1104:16588:94026 16 2L 462 255 51M * 0 0 AAGCAAAGTTCATGGCAAATTGCAGGAGGCATTTAATCGAATATCCCAACT JJJIJJJJIGGIGJJJJIIIJJJJJJIJIJIJIJJJJJHHHFHFFFFDBB? XA:i:0 MD:Z:51 NM:i:0 DD61XKN1:97:COBJ7ACXX:6:1207:4817:5073 16 2L 462 255 51M * 0 0 AAGCAAAGTTCATGGCAAATTGCAGGAGGCATTTAATCGAATATCCCAACT B9B4B4@B:**?4EEDG?1A@F?ABFF>FA?=03A=:=; XA:i:0 MD:Z:51 NM:i:0 DD61XKN1:97:COBJ7ACXX:6:2107:17894:130557 0 2L 465 255 51M * 0 0 CAAAGTTCATGGCAAATTGCAGGAGGCATTTAATCGAATATCCCAACTACA BCCFFDFFGHGHHJJJJJJJJJJJJJJJJJJJJIIIJJJJJJJJJJJJJJI XA:i:0 MD:Z:51 NM:i:0 DD61XKN1:97:COBJ7ACXX:6:2303:2851:98881 0 2L 555 255 51M * 0 0 TACATATTTATAAACAGGGTAAGAGAGTTTTTGGAACATACTTTCGTGTTG @BCFFFFFHHHHHJJJJJJAFGIJJIIGIIJJJJIJJJJJIJJJJJGIIJJ XA:i:0 MD:Z:51 NM:i:0 DD61XKN1:97:COBJ7ACXX:6:2304:12883:92184 16 2L 563 255 51M * 0 0 TATAAACAGGGTAAGAGAGTTTTTGGAACATACTTTCGTGTTGGCTTCTAT EECDDBDEEEEEDBCCDD:DEAEEDEFCFEC9@@:1DE?D:DDFGGGGGBGEHDDH3;DGGIE;DD XA:i:0 MD:Z:51 NM:i:0 DD61XKN1:97:COBJ7ACXX:6:2106:16981:166296 0 2L 743 255 51M * 0 0 TTGTTTCAACATACGTTAGAACTTTTACACTGAACGATTCGGACCGGACTC ?@@AADBDHFDFDGHFAF;@BECHHII@EEHIGGDBFEFF;FHEGII;AF; XA:i:0 MD:Z:51 NM:i:0 DD61XKN1:97:COBJ7ACXX:6:2108:11645:6736 16 2L 744 255 51M * 0 0 TGTTTCAACATACGTTAGAACTTTTACACTGAACGATTCGGACCGGACTCT JIJJJIIFIIHHGIIGIGGIJIIIHGGIHEIHGIJIJIHHHHHFFFFFC@@ XA:i:0 MD:Z:51 NM:i:0 DD61XKN1:97:COBJ7ACXX:6:1207:13167:93216 16 2L 747 255 51M * 0 0 TTCAACATACGTTAGAACTTTTACACTGAACGATTCGGACCGGACTCTGTG BCEDGHEFDDGFBGHFBIIIGHGG?GDFDBFBGGGHGGFHDHDDFFFD@@@ XA:i:0 MD:Z:51 NM:i:0 DD61XKN1:97:COBJ7ACXX:6:1307:17649:158836 0 2L 749 255 51M * 0 0 CAACATACGTTAGAACTTTTACACTGAACGATTCGGACCGGACTCTGTGCA CCCFFFFFHFHHHIGEIGJJIJGJJJJIF@GHGIIJIIIHJGGJJJJ@FGI XA:i:0 MD:Z:51 NM:i:0 DD61XKN1:97:COBJ7ACXX:6:1101:12267:163597 0 2L 752 255 51M * 0 0 CATACGTTAGAACTTTTACACTGAACGATTCGGACCGGACTCTGTGCATAT @@@DFF?DHHDHFHIIJJJIJGHIJJIIJJJJJGHIGIGHEGHI=CHIDGI XA:i:0 MD:Z:51 NM:i:0 DD61XKN1:97:COBJ7ACXX:6:2102:12127:14270 16 2L 752 255 51M * 0 0 CATACGTTAGAACTTTTACACTGAACGATTCGGACCGGACTCTGTGCATAT JIIGJJJIIIIHJJJIGHIJJIIJJJJJJIJJJIJJJJHHHGHFFFFFCCC XA:i:0 MD:Z:51 NM:i:0 DD61XKN1:97:COBJ7ACXX:6:1105:19675:113812 16 2L 771 255 51M * 0 0 ACTGAACGATTCGGACCGGACTCTGTGCATATCATTAAAGATTCCAATACC CGGJIJIIJJIJIGGDIIHHG@IHAAJIGIJIIIGIGHFHFHHFDDDD=@B XA:i:0 MD:Z:51 NM:i:0 DD61XKN1:97:COBJ7ACXX:6:2308:3713:14646 0 2L 772 255 51M * 0 0 CTGAACGATTCGGACCGGACTCTGTGCATATCATTAAAGATTCCAATACCG @@CFFDDFFFGFFEFDBGGHDDGEDDFGGGGGEHGCHGGEGIIJJJIEIGG XA:i:0 MD:Z:51 NM:i:0 DD61XKN1:97:COBJ7ACXX:6:1202:10930:167853 16 2L 773 255 51M * 0 0 TGAACGATTCGGACCGGACTCTGTGCATATCATTAAAGATTCCAATACCGT GHCD@HGGFHEGHGIHFFIIIGFGHDGF*D8?DG7BGFF@ XA:i:0 MD:Z:51 NM:i:0 DD61XKN1:97:COBJ7ACXX:6:1207:3046:69048 0 2L 784 255 51M * 0 0 GACCGGACTCTGTGCATATCATTAAAGATTCCAATACCGTTGATATTAATA CCCFFFFFHHHHHJJJJGIIJIJJJJJJJIJIJJJIJJJIIJJJJJJJJII XA:i:0 MD:Z:51 NM:i:0 deepTools-2.5.0/deeptools/test/test_corrGC/test_paired.bam0000640000201600010240000000446212757050136023011 0ustar ryanbioinfoBC\srec``pp 23 *+/*IMr J(22504.FV 30ܣ%GBCVǽ[RaDž#;< 1؞10ޮVkVR ("ٺ,^*P 6Pl)BG?4yx;h47}9sZsս^e}Ǻh{{~x˲o|_~$<[YlGM-|۲duKO>r^dQ1P8kF]cL0N$̺ïguyYh+ lCr#yOnn$, BȒ4^(~]DV*v};|'vGx(P(oQ,.y,ѴE)JΑ7^帵WBPQf;{wlJΣ<"n_Wy+ȇԽ8JߌU1[ʥx5k VdY&dYyqjHn)喖Yad ,ϓ4(iajH["+IM uΕsL<߱,{( :LfQϒ0dt)`bMK*F4alVf\AQJG6+#6w&w 2j97BEQ(\9beL(9z;0HD9˽࠘p%8lQl4+dz][ʪBp{|44 ݍ H|d T˶헕[ץkGܗ])+3+cU\cU(R&:k #e1Ӷl+?W1~2%QAfE6GO$x?rv#\"v9oAroO$]Ӵ SeB) wj0\nveLY9 AB)e66.gsϯKqŋ(xF׍cN X^OEB/tJ9Ftzt(ᶖDupMҲy](ˋwֻc%'PMA]Cϥ䄗#=a5gfx%iY,\tw !PIET5R{W3* WA`IIR5!"`M a4`f_π*߶s,[f,EN<,Pʨta>ꡠgC 0@uga4jg.T3\P,gi됹6b4jeE5AL þan1ɵ(ih;rE/TcG=l( av b $_ͮ^i={ݻE,~G&=j:u'K=FHq/jY>6dZܾ7F1.i'*DZB~")a,j)a-}!IsZУ%S /-'~[?5t,S08λZRٲ7+i)7mD,aMOEpR6]ep-BB¸}VcqpX{lӼy| QgC1G5Iؖ 8\ae_LSO3+,HpXt^4z.%M*J _I?7@-m]mRR6QҨ!{8`a5§neeG޻>i<6gfxn]]@uJҫs&W < ^@[˧w^f0_vյ]QnjA5pn:pI&LXNdo]lBCdeepTools-2.5.0/deeptools/test/test_corrGC/test_paired.bam.bai0000640000201600010240000000475012757050136023543 0ustar ryanbioinfoBAIz]2 J]2 12]deepTools-2.5.0/deeptools/test/test_corrGC/test_paired.sam0000640000201600010240000001777012757050136023040 0ustar ryanbioinfo@HD VN:1.0 SO:unsorted @SQ SN:chr2 LN:5010000 HWUSI-EAS616:7:89:1518:3543#0 99 chr2 5000027 255 36M = 5000355 364 TGTAACAATTTACTTGATTGTTCTCAAGGATGTGAT S\dbdcfaaccbbcccc^dcdc^c^YaaabaaWdaa XA:i:0 MD:Z:36 NM:i:0 HWUSI-EAS616:7:23:12543:6958#0 83 chr2 5000081 255 36M = 4999776 -341 CTTTGTTGTTCTCCTGTCCATTTCTCACAAAGCTGG hhhhhhhghfhhfhhhhhhfhhhhhhhhhhhhhhhh XA:i:0 MD:Z:36 NM:i:0 HWUSI-EAS616:7:6:10857:18740#0 83 chr2 5000191 255 36M = 4999866 -361 GTTAGGGGCAATCCTGATTCACAGTTAGCTTCTTAG ggggggggegggggggffcfdgggggggggggdggg XA:i:0 MD:Z:36 NM:i:0 HWUSI-EAS616:7:93:7807:15274#0 163 chr2 5000304 255 36M = 5000676 408 GAGAGGGAGAGGGAGAGGGAGAATGAAGCAGGAATG hhhhhhhhhehhhhhhhhhehhhhghhhfhhhfghh XA:i:0 MD:Z:36 NM:i:0 HWUSI-EAS616:7:89:1518:3543#0 147 chr2 5000355 255 36M = 5000027 -364 AGGTCATCAGGCTGGAATTTCAGGTAAGAATTACCA R]bT]`eRd^db]baY`W_W^_\]\_XZUZVVNVHU XA:i:1 MD:Z:34A1 NM:i:1 HWUSI-EAS616:7:21:17769:5446#0 163 chr2 5000385 255 36M = 5000496 147 TTACAATTGATGTCTGGACTCCAAATCCCTCAAGTG hhhhhhghhhhhhhhhhhhhhfhhhhhhhhhgghdh XA:i:0 MD:Z:36 NM:i:0 HWUSI-EAS616:7:49:8992:4457#0 99 chr2 5000385 255 36M = 5000496 147 TTACAATTGATGTCTGGACTCCAAATCCCTCAAGTG de\dc\fffdf^cdfe\cff_ffffffdafgcgggg XA:i:0 MD:Z:36 NM:i:0 HWUSI-EAS616:7:21:17769:5446#0 83 chr2 5000496 255 36M = 5000385 -147 TACTCTCAAAGCTTTCAAATGAAAGGACCCACACAC ghhahhgghhdffccfhhhhhhhghhdfffffdfff XA:i:0 MD:Z:36 NM:i:0 HWUSI-EAS616:7:49:8992:4457#0 147 chr2 5000496 255 36M = 5000385 -147 TACTCTCAAAGCTTTCAAATGAAAGGACCCACACAC hehhhhgghhgchhghfhhfafhhffhhhhhfdfff XA:i:0 MD:Z:36 NM:i:0 HWUSI-EAS616:7:86:18020:6752#0 99 chr2 5000560 255 36M = 5000906 382 AACACCAATCACATAAAGAATGTGTCTCCACAGAAG hhgahhhhhghfhhhhhghhhh_cghfhhfhchghh XA:i:0 MD:Z:36 NM:i:0 HWUSI-EAS616:7:93:7807:15274#0 83 chr2 5000676 255 36M = 5000304 -408 AAAACTTATCAGTTTTTAAAGGTTACTGAGGGCTTG hhhghhhhhghhhhhhghhhghhhhhhhdhghhhhh XA:i:0 MD:Z:36 NM:i:0 HWUSI-EAS616:7:64:3102:21101#0 99 chr2 5000737 255 36M = 5001136 435 TTGAGGTCAACCTGGGTTACATGGCAAGACCTTGGT hhhhhhghhhhhhhhhfhhhhhhhhhhhghhhhhgf XA:i:0 MD:Z:36 NM:i:0 HWUSI-EAS616:7:36:16424:18394#0 163 chr2 5000820 255 36M = 5001193 409 TGAAAAGGCATACGGAGCAGCTGATGTTTCTCCAAC hhhhhhhghhhhhhhhhfghghhfhgdhhgehhhhh XA:i:0 MD:Z:36 NM:i:0 HWUSI-EAS616:7:50:18110:21009#0 163 chr2 5000822 255 36M = 5001123 337 AAAAGGCATACGGAGCAGCTGATGTTTCTCCAACAT ffffccafacfffcfahffdfaffc`a`^`ddfdh] XA:i:0 MD:Z:36 NM:i:0 HWUSI-EAS616:7:111:14171:9899#0 163 chr2 5000822 255 36M = 5001123 337 AAAAGGCATACGGAGCAGCTGATGTTTCTCCAACAT hhhhhhhhhhhhhhhhghhhhhgefhhhhhhhhhgh XA:i:0 MD:Z:36 NM:i:0 HWUSI-EAS616:7:114:18552:5841#0 163 chr2 5000822 255 36M = 5001123 337 AAAAGGCATACGGAGCAGCTGATGTTTCTCCAACAT hhhhhhhhhhhhhhghehhhhhhhhhhhfhhhhhhh XA:i:0 MD:Z:36 NM:i:0 HWUSI-EAS616:7:8:2829:6484#0 99 chr2 5000835 255 36M = 5001214 415 AGCAGCTGATGTTTCTCCAACATCATCCTGGTGTGG hhhfhhhghhhhhhghhhhchghhghhhghhghhhh XA:i:1 MD:Z:28C7 NM:i:1 HWUSI-EAS616:7:4:16767:6127#0 163 chr2 5000856 255 36M = 5001242 422 ATCATCCTGGTGTGGGGAGGTAGAGGCAGAGGATCA hhghhhhhhc^edeec__]_cfccfdfffW_fdad_ XA:i:1 MD:Z:7C28 NM:i:1 HWUSI-EAS616:7:66:4289:12506#0 99 chr2 5000868 255 36M = 5001183 351 TGGGGAGGTAGAGGCAGAGGATCAGGAGTTCATGTT hhhhhhhhdhhghghggghhehhhhhehehfhhhfh XA:i:0 MD:Z:36 NM:i:0 HWUSI-EAS616:7:86:18020:6752#0 147 chr2 5000906 255 36M = 5000560 -382 CCCCTAGCTTTATGCTGTCCATGGTTCATCATCTCT hchhfdhghhfghfahhhhhhhhfhhhhhhhghheh XA:i:0 MD:Z:36 NM:i:0 HWUSI-EAS616:7:23:8152:13433#0 163 chr2 5000926 255 36M = 5000988 98 ATGGTTCATCATCTCTTATGGCCCATATTAGTCATT hhhhhhhhhhhhhhhhhhhghhhhhhehhhhhhehh XA:i:0 MD:Z:36 NM:i:0 HWUSI-EAS616:7:103:13675:10395#0 163 chr2 5000926 255 36M = 5000988 98 ATGGTTCATCATCTCTTATGGCCCATATTAGTCATT ffffahhhhfffgfhffh]f]fddfd_fffdcfff\ XA:i:0 MD:Z:36 NM:i:0 HWUSI-EAS616:7:106:13391:17723#0 163 chr2 5000938 255 36M = 5001303 401 CTCTTATGGCCCATATTAGTCATTGTGCCATTCAAA hhhhhhhhhhhhhhhhhhhghhghhehhhhhhhhhh XA:i:0 MD:Z:36 NM:i:0 HWUSI-EAS616:7:23:8152:13433#0 83 chr2 5000988 255 36M = 5000926 -98 AGAAACATGTTTCACAGCTCCTACTGTATCCTGGAC hhhhghghhhhhhehhhgdhhhhhhghhhhhhhhhh XA:i:0 MD:Z:36 NM:i:0 HWUSI-EAS616:7:103:13675:10395#0 83 chr2 5000988 255 36M = 5000926 -98 AGAAACATGTTTCACAGCTCCTACTGTATCCTGGAC f_ffcfdddcaV`XZa[dadcaWcadddaccd[fcf XA:i:0 MD:Z:36 NM:i:0 HWUSI-EAS616:7:116:8653:16765#0 99 chr2 5001011 255 36M = 5001141 166 CTGTATCCTGGACCCTAGGGATGCAACAGTGGCAAG hhghghhhhfhhhhhhhhhhffhhhhgghghfhfhh XA:i:0 MD:Z:36 NM:i:0 HWUSI-EAS616:7:81:1971:19006#0 99 chr2 5001026 255 36M = 5001396 406 TAGGGATGCAATAGTGGCAAGATGTGGTTTCTGCTC hhhhhhhhhhhghfhhhhhhghhhhhhghhhhhghd XA:i:1 MD:Z:11C24 NM:i:1 HWUSI-EAS616:7:39:11820:4528#0 163 chr2 5001051 255 36M = 5001401 386 GGTTTCTGCTCTTCATTGTGAGCTGACTTGGCTGAG hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh XA:i:0 MD:Z:36 NM:i:0 HWUSI-EAS616:7:25:4767:20646#0 163 chr2 5001115 255 36M = 5001378 299 TCAGAGAGGATAACGTAAGGTAACTCAGAGATATGC ghhfhhcaahe^d`ebfddc^ad`dada[cVb`^^c XA:i:0 MD:Z:36 NM:i:0 HWUSI-EAS616:7:2:14523:20268#0 163 chr2 5001116 255 36M = 5001234 154 CAGAGAGGATAACGTAAGGTAACTCAGAGATATGCA ghghhhhhfgchghcecfchhchhhghchchehhhh XA:i:0 MD:Z:36 NM:i:0 HWUSI-EAS616:7:79:5441:2939#0 163 chr2 5001116 255 36M = 5001234 154 CAGAGAGGATAACGTAAGGTAACTCAGAGATATGCA ghcghfhhhchhhffffaffffacffa_f[fafcaf XA:i:0 MD:Z:36 NM:i:0 HWUSI-EAS616:7:50:18110:21009#0 83 chr2 5001123 255 36M = 5000822 -337 GATAACGTAAGGTAACTCAGAGATATGCACAGGAAG \Z_aa^XY^aa\aaaa\^S^cd^dddYccffb\f_f XA:i:0 MD:Z:36 NM:i:0 HWUSI-EAS616:7:111:14171:9899#0 83 chr2 5001123 255 36M = 5000822 -337 GATAACGTAAGGTAACTCAGAGATATGCACAGGAAG hhghhhhhhhhhhhhhhhhhhhhghhhhhhhhhhhh XA:i:0 MD:Z:36 NM:i:0 HWUSI-EAS616:7:114:18552:5841#0 83 chr2 5001123 255 36M = 5000822 -337 GATAACGTAAGGTAACTCAGAGATATGCACAGGAAG hhhhhhghhhhgghhhhhhhhhhhhhhhhhhhhhhh XA:i:0 MD:Z:36 NM:i:0 HWUSI-EAS616:7:64:3102:21101#0 147 chr2 5001136 255 36M = 5000737 -435 AACTCAGAGATATGCACAGGAAGTTGCATATTTGCA afghhhhgghgehghghhhhhhhhhhfhhhhhhhhh XA:i:0 MD:Z:36 NM:i:0 HWUSI-EAS616:7:116:8653:16765#0 147 chr2 5001141 255 36M = 5001011 -166 AGAGATATGCACAGGAAGTTGCATATTTGCAATAAA hhhhhhhhhgghhhhhhhhhhhhhhhhhhhhhhhhh XA:i:0 MD:Z:36 NM:i:0 HWUSI-EAS616:7:66:4289:12506#0 147 chr2 5001183 255 36M = 5000868 -351 CACAGCAGAACTATTAGATCCAGGCACTCACTCAAC hghhhhfffcfddfbdhhhfhhhhhghhhhhhhhhh XA:i:0 MD:Z:36 NM:i:0 HWUSI-EAS616:7:36:16424:18394#0 83 chr2 5001193 255 36M = 5000820 -409 CTATTAGATCCAGGCACTCACTCAACGTGGATTCTG dbddcbfhehhehffdghhghhggghhhhhhhhhhh XA:i:0 MD:Z:36 NM:i:0 HWUSI-EAS616:7:8:2829:6484#0 147 chr2 5001214 255 36M = 5000835 -415 TCAACGTGGATTCTGGGCTCTTCAGCTCTGATCTCT ghhhhhfhhhhhhhhhhhhhhhhhhhhhghhfhhgg XA:i:0 MD:Z:36 NM:i:0 HWUSI-EAS616:7:3:9592:15607#0 163 chr2 5001227 255 36M = 5001568 377 TGGGCTCTTCAGCTCTGATCTCTTTAGCTCTGATTT hhhehhhhhhhhhhfhhhhghghhhhhhhhhhhhgh XA:i:2 MD:Z:24C6C4 NM:i:2 HWUSI-EAS616:7:2:14523:20268#0 83 chr2 5001234 255 36M = 5001116 -154 TTCAGCTCTGATCTCTTCAGCTCTCATTTGCTCAGA aagggggffgaffafcafeafaggcgaggcgfeggg XA:i:0 MD:Z:36 NM:i:0 HWUSI-EAS616:7:79:5441:2939#0 83 chr2 5001234 255 36M = 5001116 -154 TTCAGCTCTGATCTCTTCGGCTCTCATTTGCTCAGA gdd`baWfafedd`ae`dKadfcfffaaffdfffff XA:i:1 MD:Z:18A17 NM:i:1 HWUSI-EAS616:7:4:16767:6127#0 83 chr2 5001242 255 36M = 5000856 -422 TGATCTCTTTAGCTCTGATTTGCTCAGACTGTCTAT fggfggaffffcefgaffddf_^ggggeggfgcgdg XA:i:2 MD:Z:9C6C19 NM:i:2 HWUSI-EAS616:7:106:13391:17723#0 83 chr2 5001303 255 36M = 5000938 -401 GTCTGCAGTCAACTGGCAGTCCCTCTCAGGGAAAAT hhhhhhhhhghghhhhhhhhhghhhfhhhhhhhhhh XA:i:0 MD:Z:36 NM:i:0 HWUSI-EAS616:7:25:4767:20646#0 83 chr2 5001378 255 36M = 5001115 -299 GAAAGTGCTCTTTGTCAGACTAAGACCTTTTAATTT gffff_ggaggfaffca^_a\ffd`afgcggggggg XA:i:0 MD:Z:36 NM:i:0 HWUSI-EAS616:7:81:1971:19006#0 147 chr2 5001396 255 36M = 5001026 -406 ACTAAGACCTTTTAATTTGTCCCATTTTAATAGTAC hhhhhhghhhhhhhhhhhhhhhhhhhhhhhhhhhhh XA:i:0 MD:Z:36 NM:i:0 HWUSI-EAS616:7:39:11820:4528#0 83 chr2 5001401 255 36M = 5001051 -386 GACCTTTTAATTTGTCCCATTTTAATAGTACATATG hhhhhhhhghhhhhhhhhghhhhhghhhhhhhhhhh XA:i:0 MD:Z:36 NM:i:0 HWUSI-EAS616:7:29:12313:10611#0 0 chr2 5001492 255 36M * 0 0 AATTGTAAGACCCCCGAAACTGGGGAGACCTCCGCT fd]aeecaaWcdfd_ffffcZ[aaa_\Z]`Z^Z___ XA:i:0 MD:Z:36 NM:i:0 HWUSI-EAS616:7:39:11820:45288#0 16 chr2 5001701 255 36M * 0 0 GACCTTTTAATTTGTCCCATTTTAATAGTACATATG hhhhhhhhghhhhhhhhhghhhhhghhhhhhhhhhh XA:i:0 MD:Z:36 NM:i:0 deepTools-2.5.0/deeptools/test/test_data/0000750000201600010240000000000013067415120017541 5ustar ryanbioinfodeepTools-2.5.0/deeptools/test/test_data/computeMatrixOperations.bed0000640000201600010240000005622513006372703025137 0ustar ryanbioinfo6 85676989,85677423,85677794,85677953,85678135 85677191,85677492,85677875,85678032,85678736 ENST00000369605 . - 2 132147908,132150911,132153531,132154661,132156972,132157308,132161487 132148228,132150976,132153694,132154768,132157146,132157423,132161955 ENST00000295181 . - 11 43829708,43833609 43831590,43833917 ENST00000499066 . - 3 48630451,48630606,48630992,48631223,48631648,48631879,48632244 48630515,48630720,48631126,48631306,48631801,48632044,48632337 ENST00000444531 . - 22 28687762,28689134,28694031,28695126,28695709,28696900,28699837,28703504,28710005,28711908,28719394,28724976,28725242,28730419,28734402,28741768 28687986,28689215,28694117,28695242,28695873,28696987,28699937,28703566,28710059,28712017,28719485,28725124,28725367,28730548,28734727,28741838 ENST00000382580 . - 7 76510427,76510902,76511656,76513083,76513946,76515044 76510737,76511052,76511882,76513163,76514076,76516521 ENST00000334348 . + 6 154086506,154089825,154090951,154118682 154087785,154090178,154091472,154118969 ENST00000522555 . + X 153444719,153447747,153454393,153455541,153456264,153456492,153457136,153462609,153464987,153469145,153470449 153445464,153447909,153454508,153455766,153456364,153456651,153457228,153462671,153465055,153469261,153470587 ENST00000334497 . - 3 154121002,154121941,154124409,154129573,154149388,154152771,154187684,154191288,154194643,154217868,154225855,154240369,154253115,154254719,154255330 154121235,154123075,154124449,154129719,154149445,154152932,154187837,154191418,154194718,154217958,154226010,154240579,154253183,154254824,154257827 ENST00000356448 . + 20 21197461,21198728,21202313,21213535,21213910,21218146 21197576,21198804,21202372,21213592,21214022,21218289 ENST00000433213 . - 18 28009803,28011845,28013682,28097062 28009872,28011992,28013909,28097229 ENST00000430882 . - 2 215476666,215479921 215476730,215480248 ENST00000414756 . + 16 35195778 35197544 ENST00000564059 . + 10 73496494,73498297 73496906,73498541 ENST00000620559 . + 14 105209285,105211121,105212112,105217543,105218997,105219150,105220068,105221647,105226068,105226250,105226633,105228819,105241264,105252506,105256517,105272720,105286295,105300445 105210588,105211293,105212164,105217800,105219053,105219232,105220130,105221914,105226161,105226290,105226760,105228913,105241414,105252579,105256549,105272894,105286376,105315589 ENST00000546474 . - 1 68375326 68375663 ENST00000434209 . - 20 43916166,43955147,43973366,44006546,44051305,44054298,44064776,44065711,44066729,44068649 43916208,43955272,43973432,44006792,44051545,44054526,44064857,44066107,44066857,44069616 ENST00000372999 . + 22 20318118 20318749 ENST00000608275 . - 15 60456764,60466593,60468060,60476062,60478567,60479002 60456794,60466713,60468162,60476167,60478650,60479107 ENST00000561087 . - 12 101280127,101281115,101285569,101285748,101286320,101288959,101290136,101290732 101280327,101281196,101285636,101285881,101286509,101289041,101290274,101291427 ENST00000551825 . + 19 5894676,5896452,5896904,5903611 5894854,5896575,5896997,5903756 ENST00000308961 . - 8 88032008,88046668,88056127,88074604,88116506,88118699,88167668,88186475,88197157,88327074 88041795,88046784,88056278,88074743,88116718,88118861,88167973,88186598,88197306,88327488 ENST00000286614 . - 2 218217140,218217371,218225919,218228737,218234351 218217254,218217544,218225954,218228850,218234398 ENST00000420104 . + 1 150067808,150068629,150072165,150076232 150067950,150068764,150072226,150077029 ENST00000497638 . + 1 114716915,114718612,114719578,114720538,114723882,114725220,114726210,114726982,114730257,114730507,114732603,114733731,114733988,114734441,114736757,114737470,114737962,114739691,114741526,114749820 114718216,114718745,114719742,114720717,114724002,114725333,114726386,114727090,114730422,114730648,114732816,114733857,114734117,114734523,114736855,114737563,114738072,114739890,114741673,114750190 ENST00000438362 . - 15 51884555 51884653 ENST00000384753 . + 11 126283105,126288442,126289664,126290461,126290802 126283153,126288573,126289833,126290585,126290897 ENST00000467006 . + 2 241150466,241153482,241157806,241158483 241150547,241153604,241157862,241158807 ENST00000473017 . + 12 121210064,121216954,121217133,121221912,121222093,121222946,121228532,121228724,121228962,121232413,121232610,121232996,121233522 121210298,121217002,121217281,121221984,121222166,121223043,121228613,121228866,121229099,121232507,121232676,121233092,121234070 ENST00000359949 . + 2 58428384,58656649,58695633 58428464,58656711,58696055 ENST00000455219 . + 17 43006724,43012178,43013046,43013266,43013475,43013775,43014107 43006968,43012277,43013194,43013373,43013662,43013882,43014456 ENST00000415816 . + 5 38429891 38430160 ENST00000513087 . - 2 203380307,203391045,203394699,203395658,203402575 203380384,203391143,203394846,203395780,203402734 ENST00000451591 . + 12 122976884,122978359,122978752 122976970,122978569,122978830 ENST00000545976 . + 19 10637643,10637855,10638226,10642366,10643278 10637747,10637929,10638315,10642451,10643528 ENST00000591194 . + 19 39264381,39264964,39265108,39265490,39265718 39264531,39265036,39265252,39265565,39265817 ENST00000607083 . + 11 118999040,119010763,119011220,119011938,119012148,119013231,119014213 118999109,119010830,119011311,119012003,119012254,119013262,119014346 ENST00000580556 . + 11 83459507,83462001 83459924,83462149 ENST00000529159 . - 12 55684857,55686201,55687970,55688201,55688843 55685288,55686314,55688096,55688300,55688891 ENST00000557555 . - 2 207868581,207869807 207868942,207869915 ENST00000421964 . - 10 86968191,86970199,86970475 86968605,86970262,86970915 ENST00000372013 . + 16 71525232,71526119,71536659 71525364,71526312,71538746 ENST00000338482 . + 1 2590925,2591556,2591931,2592654,2592832,2593813,2594384,2594789,2595275,2596008,2596560,2598206,2598653,2603883,2604146,2605557,2606247,2606973,2609338,2609669,2611280,2612126,2629330 2591089,2591633,2592027,2592720,2592966,2593962,2594443,2594893,2595359,2596107,2596689,2598300,2598790,2603973,2604281,2605623,2606366,2607069,2609419,2609831,2611340,2612204,2629494 ENST00000504800 . - 19 39886265,39887118 39886585,39887292 ENST00000595713 . - 1 24625410 24625513 ENST00000459380 . - 8 12738028,12740873,12743163,12755923 12738144,12740996,12743282,12756073 ENST00000530693 . - 17 82900541,82903404,82905935,82907760,82909284,82911757,82920555,82921500,82923651,82924938,82926399 82900731,82903478,82906053,82907821,82909307,82911789,82920618,82921577,82923733,82925057,82926439 ENST00000574422 . + 4 158171348,158172872 158171489,158173318 ENST00000587787 . - 2 135638617,135638738,135638895,135645378,135649086 135638655,135638789,135639122,135645527,135649331 ENST00000443537 . + X 74278373,74280930,74281701,74292426 74280494,74281085,74281848,74292600 ENST00000429124 . - 3 33277465,33297663,33373091,33373259,33373577,33373846,33375287,33377272,33378102,33378684,33383988,33385500,33403233 33277515,33297725,33373160,33373355,33373704,33373921,33375418,33377333,33378147,33378741,33384201,33385728,33403662 ENST00000463736 . + 8 46792064,46792608 46792320,46793064 ENST00000509929 . + 1 44988233 44988725 ENST00000411837 . - 6 44127553,44134560,44135016,44135327,44136348,44138479,44139466,44139707,44140251 44127678,44134743,44135096,44135366,44136439,44138517,44139609,44139759,44140328 ENST00000532634 . + 15 57720294 57720928 ENST00000567865 . + 19 21788879,21793516 21789100,21793860 ENST00000593824 . - 10 35195146,35206894,35211253 35195214,35207051,35212923 ENST00000356917 . + 17 8144993 8145071 ENST00000614952 . - 1 226870183,226871261,226875364,226881887 226870505,226871404,226875550,226881970 ENST00000524196 . + 2 2729907,2730775 2730093,2730957 ENST00000457813 . - 16 88803212,88804544,88804761,88805439,88805723,88806020,88806485,88807050,88807280,88808114 88804059,88804667,88804898,88805637,88805869,88806121,88806674,88807203,88807482,88809258 ENST00000301019 . + 12 6981293,6981810,6982675 6981632,6981904,6982783 ENST00000620843 . - 16 84459258,84461694,84467303 84460893,84462999,84467361 ENST00000565700 . - 4 77030782,77039742 77030970,77040100 ENST00000513373 . + 2 120090482,120091554,120093248,120100243,120100698,120101588 120090516,120091661,120093276,120100286,120100814,120101627 ENST00000489017 . + 18 71932492 71932796 ENST00000604699 . + 8 15688913 15689562 ENST00000506768 . - X 49177988,49178271,49179250,49179692,49183733,49184624,49184825 49178179,49178475,49179388,49179806,49183917,49184710,49184898 ENST00000432913 . - 6 111661759,111674498,111694374,111694627,111696276 111661947,111674630,111694528,111694704,111696524 ENST00000467921 . - 4 77720237,77726166,77728853,77731386,77742140,77744717,77748315,77756861,77773080,77774529,77776270,77819303 77720643,77726369,77729081,77731538,77742295,77744875,77748384,77756951,77773166,77774712,77776392,77819376 ENST00000504804 . - 1 24323039,24334644,24336481,24337077,24337635,24337991,24339667,24342114,24342693,24342891,24344896,24346552,24347467,24350057,24354373 24323117,24334706,24336827,24337151,24337789,24338103,24339762,24342273,24342772,24343025,24344931,24346641,24347553,24350122,24354488 ENST00000528064 . + 11 10591575,10593491 10591612,10594023 ENST00000529471 . - 18 13059181,13067830,13068093,13068358,13068851,13069088,13069737,13071038,13072754,13073008,13087016,13087530,13089451,13092376,13095502,13096183,13099475,13100304,13103508,13104983,13116373,13117584,13124631 13059312,13067956,13068237,13068422,13068991,13069181,13069856,13071212,13072845,13073185,13087277,13087646,13089565,13092527,13095681,13096307,13099581,13100512,13103588,13105079,13116503,13117643,13125034 ENST00000430049 . + 16 19417695,19430412,19439959,19444080,19449541,19460234,19463279,19463775,19466081,19469680,19472087,19474124,19477439,19479430,19481369,19486944,19487192,19490394,19492149,19494261,19497120,19497919 19418092,19430640,19440826,19444250,19449631,19460334,19463367,19464024,19466233,19469825,19472243,19474276,19477518,19479528,19481465,19487020,19487326,19490568,19492228,19494366,19497163,19499113 ENST00000542583 . + 14 76151934,76154353,76166662,76171842,76173545,76176622,76177891,76180763,76195877,76201690 76151991,76155025,76166727,76172019,76173625,76176690,76177931,76180849,76195972,76202788 ENST00000312858 . + 14 104773790,104774937,104775075,104775651,104776658 104773980,104775003,104775207,104775799,104776694 ENST00000554826 . - 5 72816671,72848384,72851243,72861807,72865595,72872638,72875614,72877227,72882466,72883063,72887069,72888077,72889785,72891809,72893138,72893376,72893615,72896457,72897055,72900005,72900973,72903708,72905302 72816752,72848498,72851319,72861914,72865729,72872720,72875737,72877346,72882527,72883232,72887222,72888303,72889957,72891896,72893246,72893535,72893703,72896556,72897151,72900081,72901073,72903783,72905429 ENST00000523768 . + 3 149812707,149846010,149852515,149872028,149895472,149902071,149911977,149921133,149960055,149960739 149813353,149846140,149852596,149872154,149895560,149902162,149912083,149921227,149960136,149962139 ENST00000392894 . + 2 89078009,89078738 89078310,89078784 ENST00000517571 . - 19 37594829,37598375,37599625,37611512 37595095,37598456,37599752,37613387 ENST00000589117 . + 5 74693474,74696692,74696995,74705218 74693704,74696739,74697106,74705257 ENST00000510820 . + 3 14402575,14416411,14443627,14445716,14447581,14457949,14466515,14467852,14468087,14472204,14477204,14478465,14479084,14481670,14484866 14402847,14416453,14443863,14445851,14447816,14458082,14466650,14467956,14468212,14472317,14477342,14478568,14479185,14481841,14489349 ENST00000613060 . + 7 141649130,141651524,141652786 141649333,141651609,141653065 ENST00000494053 . + 2 74264147,74265103,74285772,74290243 74264299,74265264,74285902,74290705 ENST00000432728 . - 9 35812973,35813444,35813643,35814898 35813338,35813549,35813784,35815021 ENST00000461169 . - 2 169529754,169530586,169531351,169540050 169529926,169530701,169531490,169540117 ENST00000490590 . - 16 86490267,86508654 86491004,86508877 ENST00000593604 . - 3 157149286,157149484,157149835,157150064,157150281,157152176,157153035,157156935,157158865,157159404,157159791 157149385,157149596,157149977,157150169,157150381,157152241,157153156,157157083,157158975,157159479,157160178 ENST00000477127 . - 12 51382334,51383460,51391600 51382509,51383582,51391675 ENST00000603482 . - 19 11420603,11421127,11421676,11422470,11422700,11423876,11426143,11426445,11426682,11426872,11430698,11430898,11434772 11420947,11421212,11421832,11422627,11422861,11424029,11426266,11426571,11426784,11427040,11430776,11431020,11435104 ENST00000356392 . - 2 55313828,55315927 55314123,55316051 ENST00000476903 . - 2 86604599,86612158,86620329,86622660,86623815 86605418,86612274,86620469,86622827,86623866 ENST00000477307 . - 19 35059058,35086955,35099204,35106228 35059778,35087100,35099387,35106304 ENST00000392227 . - 17 4945666,4946627 4945997,4947469 ENST00000574872 . - 10 126413868,126416799,126417715,126421786 126414738,126416911,126417808,126421879 ENST00000456514 . - 22 30522798,30525349,30525610,30525825,30529086,30529288,30531902,30532524,30532796,30533995,30538826,30546628 30525109,30525519,30525750,30525932,30529170,30529349,30531998,30532713,30532856,30534039,30538902,30546682 ENST00000402034 . - 5 154049601,154051736,154052919 154050017,154051943,154053002 ENST00000519928 . + 5 93741639,93743002 93741689,93743500 ENST00000606528 . + 22 45718422,45729424,45738730,45740368 45718493,45729590,45738839,45740800 ENST00000483549 . + 8 114282135,114284218,114287721 114282294,114284514,114287996 ENST00000519248 . + 16 2091822,2092046,2092479,2093543,2093810 2091906,2092188,2092592,2093738,2093884 ENST00000562425 . - 1 154992588,154992901 154992786,154993111 ENST00000481758 . + 6 32934628,32940752 32938965,32940984 ENST00000498020 . - 2 109794684,109801782,109803431 109795076,109801850,109803539 ENST00000432606 . + 1 966501,966703,970276,970520,970685,971076,971323,972074,972287,972860,973185,973499,973832,974315,974441 966614,966803,970423,970601,971006,971208,971404,972150,972424,973010,973326,973640,974051,974364,975008 ENST00000379409 . + 6 61630232,61652254,61659116,61661281,61678886,61680886 61630501,61652317,61659150,61661364,61678947,61681049 ENST00000511849 . - 13 30713477,30735550,30744059,30752051,30755943,30763943 30713841,30735675,30744159,30752122,30756025,30764425 ENST00000617770 . + 1 161206408,161209192,161209482 161206597,161209313,161209727 ENST00000473321 . + 18 28146232 28146703 ENST00000621223 . - 16 2148623,2149940,2151568,2151694,2151855,2152819,2152988,2153318 2148978,2150051,2151610,2151761,2151908,2152885,2153222,2154110 ENST00000562735 . + 5 175492206,175509060,175510108,175511450,175512110,175513462,175516613 175492267,175509202,175510207,175511526,175512196,175513590,175516662 ENST00000502865 . + 22 29231017,29231457,29231592,29232255,29233378,29233613,29234136,29234304,29243444 29231140,29231508,29231682,29232402,29233468,29233666,29234199,29234349,29243489 ENST00000433143 . + 21 27638692,27648664,27653355 27638923,27648765,27653491 ENST00000426418 . + 17 6641026,6641752,6642248 6641227,6641834,6642357 ENST00000571957 . + 6 41683978,41686089,41687093,41687752,41687907,41689730,41690662,41691000,41734312 41685078,41686237,41687169,41687809,41688028,41689811,41690917,41691235,41734401 ENST00000403298 . - 9 76611376,76637534,76638185,76644738,76652482,76655422,76692073 76613373,76637549,76638288,76644912,76652683,76655502,76692200 ENST00000223609 . - 17 1843919,1844577,1853100,1854138 1843998,1844686,1853189,1854274 ENST00000571725 . + 11 64224800,64226049 64224970,64226234 ENST00000540472 . - 17 41619445,41620535,41620658,41620965,41621592,41622949,41624077 41619688,41620558,41620879,41621091,41622511,41623032,41624296 ENST00000493253 . - 20 45416109,45419294,45419503,45420135,45420331,45420527,45421382,45424215,45424495,45425573 45416343,45419395,45419590,45420223,45420429,45420693,45421583,45424381,45424579,45426042 ENST00000279035 . + 17 41966740,41968067,41971891,41973474 41966887,41968740,41972031,41977731 ENST00000393892 . + 9 129612268,129613106,129613434,129615483,129620602 129612454,129613251,129613597,129615644,129620743 ENST00000619117 . - 10 132351606,132355789,132361456,132365423,132366845 132351753,132355886,132361575,132365550,132367001 ENST00000472556 . + 12 52782649 52782839 ENST00000547968 . + 14 23953788,23955034,23965761,23965931,23967210,23968756 23953916,23955212,23965832,23965983,23967266,23969274 ENST00000559632 . + 14 24146809,24147522 24147221,24147570 ENST00000561103 . - 16 69799045,69840125,69842023,69871803 69799295,69840263,69842120,69871865 ENST00000567986 . + 9 119511668 119511760 ENST00000616497 . + 14 102928829,102930164,102930405,102930575 102928955,102930327,102930493,102930591 ENST00000559789 . + 15 49155770,49158844,49201161,49217189,49235850,49239220 49156016,49158968,49201250,49217313,49235941,49239330 ENST00000560654 . + 1 19608113 19608568 ENST00000457263 . + 8 26547668 26548463 ENST00000524123 . + 10 37600795 37601368 ENST00000448191 . - 17 44769985,44771583,44771755,44772266,44772398,44772856,44773013,44773260,44774294,44774491,44774697,44775211,44775393,44775583,44776126,44776744,44776898,44777165,44777471,44777694,44777951,44778151,44779221,44779738 44770048,44771669,44771831,44772333,44772466,44772931,44773085,44773427,44774379,44774582,44774749,44775311,44775465,44775676,44776207,44776795,44776962,44777265,44777601,44777863,44778066,44778242,44779239,44780610 ENST00000587773 . + 1 58084418 58084559 ENST00000441183 . + 14 52646191,52646374 52646287,52647124 ENST00000555069 . - 15 71167024,71185404,71188815 71167189,71185506,71189016 ENST00000566268 . - 2 26848423,26898495,26924886,26927252 26848497,26898760,26925045,26927401 ENST00000431402 . + 17 49844056,49847912 49844157,49848017 ENST00000608380 . - 14 105858334 105858412 ENST00000581354 . - 11 4832132 4833072 ENST00000421277 . + 6 29657209,29659318,29666151,29667642,29667903,29670173,29670700,29671171 29657297,29659666,29666265,29667663,29667924,29670221,29670721,29671185 ENST00000396704 . + 6 27126078,27132524 27126462,27132548 ENST00000606923 . - 3 9649504,9653620,9662266,9669431,9671047,9672684,9677316,9677983,9683177 9649742,9653769,9662375,9669492,9671170,9672758,9677387,9678058,9683728 ENST00000430020 . + 10 131092390,131098305,131104264,131116798,131134378,131146505,131163121,131166796,131260258,131308210,131309152,131311293 131093318,131098424,131104354,131116934,131134448,131146660,131163210,131166885,131260444,131308391,131309299,131311721 ENST00000368642 . - X 103585562,103586218,103586653 103585624,103586291,103587526 ENST00000494801 . + 12 104286994,104288930,104289465,104311289,104313244,104315776 104287109,104289040,104289542,104311412,104313317,104315832 ENST00000531689 . + 9 20726285,20740235,20758089,20764868,20770031 20726348,20740340,20758191,20765073,20770112 ENST00000605031 . + 1 26182054,26182360,26182479,26183203,26183345,26183728,26184070,26184213,26184400 26182082,26182402,26182584,26183256,26183414,26183830,26184141,26184287,26184409 ENST00000528001 . + 7 75953988,75972412,75979450,75980338,75981516,75982223,75983519,75983737,75984776,75985057,75985578,75985922,75986158,75986336 75954180,75972461,75979579,75980488,75981606,75982322,75983636,75983856,75984958,75985207,75985849,75986068,75986241,75986854 ENST00000454934 . + 20 19693266,19694684,19695435,19696543 19693462,19694924,19695516,19696727 ENST00000598694 . - 2 218893220,218899190 218893267,218899581 ENST00000489887 . + 3 9362841,9365015,9366907,9371059,9374515,9377818,9380502,9383198,9384211,9384523 9363127,9365320,9366985,9371536,9374646,9377888,9380618,9383309,9384335,9385702 ENST00000452837 . + X 71368665 71368968 ENST00000611704 . + 13 27621885,27648378,27650041 27622009,27648453,27651549 ENST00000489647 . + 3 112990446 112991153 ENST00000609673 . - 12 111513473,111518248,111519831 111513539,111518427,111519967 ENST00000481331 . - 1 111449483,111456085,111456629,111459456,111460916 111449581,111456249,111456755,111459636,111461026 ENST00000483994 . + 8 103213410,103219464,103227988 103213594,103219554,103228166 ENST00000521926 . + 7 100336078,100338178,100338772,100345864,100349730,100351251 100336220,100338264,100338889,100345968,100349887,100351900 ENST00000473757 . + 11 66312852,66318833 66312992,66319237 ENST00000534065 . + 7 44566001,44566447,44568117,44568902,44569129,44569808,44570014,44571491,44572346,44572573,44572889,44573582,44573835 44566079,44566524,44568223,44568992,44569203,44569903,44570128,44571736,44572437,44572744,44573050,44573744,44573925 ENST00000431640 . - 16 11756321,11758430,11761405 11756370,11758539,11761662 ENST00000570862 . - 5 35675601,35691036,35692569,35694287,35695734,35697689,35700495,35704553,35705650 35675992,35691256,35692724,35694348,35695796,35697793,35700752,35704662,35705791 ENST00000504054 . + 6 32038582,32039109,32039355,32039545,32039748 32038811,32039248,32039457,32039647,32039756 ENST00000464325 . + 16 4797741,4797937,4798070,4798568,4799685,4800497,4801502,4801913 4797840,4797987,4798184,4798667,4799781,4800578,4801585,4802184 ENST00000586336 . - 22 38111871,38112503 38112305,38112855 ENST00000463287 . - X 78945420,78947814,78952192,78960507 78945495,78947863,78952335,78961954 ENST00000171757 . + 8 143817978,143818192,143818372,143818958 143818075,143818285,143818534,143819037 ENST00000528999 . - 19 42300088,42300170,42301949,42302231,42302436 42300092,42300287,42302039,42302325,42302777 ENST00000601865 . - 9 136483494 136486066 ENST00000354376 . + 8 97691018,97713661,97719048,97722878,97724599 97691188,97713769,97719189,97723035,97724652 ENST00000519293 . + 1 152663395,152664084 152663429,152664659 ENST00000368784 . + 11 213035,214229 213418,214516 ENST00000526557 . + 1 43023548 43023637 ENST00000516994 . - 2 25328632 25328744 ENST00000408518 . - 19 45128568 45129030 ENST00000589460 . + 3 49416778,49417817,49418970,49419259,49419709,49420210,49421491,49422103,49422360 49417718,49417973,49419151,49419405,49419788,49420342,49421572,49422271,49422753 ENST00000273588 . - 12 133037393,133041277,133047954,133048752 133037554,133041482,133048081,133048818 ENST00000438628 . + 11 61329956,61331542,61332907,61333603 61330074,61331691,61333008,61333775 ENST00000543627 . - 17 43528498,43529134,43529503,43529883,43530106 43528743,43529236,43529676,43529952,43530434 ENST00000586826 . - 2 101309449 101309534 ENST00000578474 . + 21 28872190,28876311,28878191,28879869,28882159,28882984,28885211 28872739,28876491,28878333,28879953,28882250,28883071,28885371 ENST00000460212 . - 17 42968725,42970288,42971606,42979169,42979377 42969186,42970342,42971696,42979268,42980349 ENST00000462157 . - 5 90410032,90410499 90410304,90410669 ENST00000546238 . + 10 32928192,32929821,32932505,32935491,32958144 32928264,32930044,32932600,32935558,32958227 ENST00000488494 . - 4 185678422,185678795,185684753,185740000 185678547,185678822,185684842,185740330 ENST00000452351 . - 1 231925833,231940927,231943748,231944922 231925950,231941050,231943959,231945233 ENST00000456782 . + 17 551633,553379,560425,562502 551950,553462,560573,562686 ENST00000572607 . - 6 2245776,2248836,2263600,2269697,2271815,2283498 2245930,2248926,2263684,2269799,2273417,2283774 ENST00000456943 . + 15 56634037 56634167 ENST00000614892 . - Y 6837706 6838252 ENST00000433995 . + 2 73271196,73272186,73273014,73284159 73271510,73272302,73273129,73284431 ENST00000520186 . - 9 112380079,112403994,112405623,112418859,112438430,112441698,112454012,112459448,112470431 112380180,112404158,112405722,112418958,112438625,112441770,112454162,112459577,112472405 ENST00000398803 . + 16 35640028 35640582 ENST00000566449 . + 2 108493300,108499552,108507559 108497109,108499754,108509415 ENST00000480863 . + deepTools-2.5.0/deeptools/test/test_data/computeMatrixOperations.mat.gz0000640000201600010240000017270513006372703025607 0ustar ryanbioinfoWsubset.matMs,r _!;K-;'=AUmt-YK[#7" όLIҷl 2/n_-??o??__kAwo/D?Z5?ϭ_H"aLXaٝI鰪Zy?o_ƠovҨ?K?\4z?u^J5qۿ/+ε|Otk/wK??׿SOg/kS˿_?WvUoξ??Ԛ Sy[ 1sO˓8oĸJzS#4$ ZE~* ɭi¯엠C摫ATe%:>~4ZN%prY84UvN-*L#*FQTPq+%Яeοr+Hʚ +bir,+OojΣNwo4%`4AFx-uD-^9y#H]oZm zAum _`\<V_5 1kzV<kRe8C«7Bp@e~ iHQ,P^eϽiXuf_ 4HB2vJe$F?1\7tm] ;#ՙJigJO!ל,[T5h$Լm!+5[ֿ)%5̥qK7_[ƒOOqڊχo&1j9r>̾!Rڑ}v*=}xnS4)Fe~`]wY $ du&$rt Ymʼ1;s9,K :R`Y2Cb(yqX)?=#AF&|sxO5s*/+yriPS ů|#G#sA#0rD(ۛI/ ͅM(CyYKJaS9sl7?|n9ׂV20000000000000000xxNODX_!ԲR >As95\f)D9hG}] U7t*"ěP$,^>5n"!;= |?pĽ)30a6')Ӣ"DUJ8Cbk^2qƉ`?86Y.HP2,mʞ t:QQ Tٱ@T@w#qѕNkQz邚.!J#8f G: 1Le4\v62!JyU g1_Hbءb:MS :dyt<udZSfT 8Dύ AYUށ`W22Hq: U$% T;#=悇?Ҡ.3f|@TdR٧6T_TCku7i32T\V\Y@Tdm;uKHs*VT>PnnN3: \m`````````x`gR-տ, /y .Ṝʮ/=^ɭކ@0. Qr?\4O%7yz92#ؼt$zvlJ,Q_^JZ0(τwf"ILT.{xV!׈Ű 7׋6B(rg.ފʼnPiQ* MFkm^>D16.g}o5c]J^>'-3H-a*(\E:4dNJ2Eƭ~JѮ; :A_( ~ oZH_Q0l;֫8k_%vҗkQUe%SP2Qr2Ub?z|3000000000<R(Bv9wH>vGՔ֨DCCiB(5br 8v>.Q+dG=_5]TnBmK|BZO)^U]H1Qř\;V\ɇBH:uZ^:VZ^(ˢpCB_\G%I9g1Tv`G{]y$͎}Cv]OZ.v4rK6ft Tɨg#$@04FdF)ĺًHԾu*d% J{娨p+g7m ##UMVm&ʗKPQgdkc~Fh йfBditABF%OE~ʳmyvI>I,!;#qH+U Lb̃)&)0bЃڃjiV!,sJwDwFwT™)%* *t/eH?`u(pOZ3> Yc6Yl.1=_nKwz=%(;h83f 21zƟ#j9 e;m|7?| Y>'r+O\(Ti})نn?g1r /#J%CQBBL哳Ol ~,] <j!ޅR=U1$A!HQ9(@ݫ`>@0o7np :D'6D 9t'*75vD:zѹB*hu -{a!JvU-!xJp'UJtPx~nkՇ+ <&1ߋqDti{{_..iU RJ|\BWiru_\G*2uë @kU: iC W^3~i*D=nяKоA* 6':N_WJZ?(Pk,̧rHՇ^HrZc"Sii+dri#>^B[.(ЕMS6N; !$QܦW'yRќ5R@V:}{pk9Iv#(( wW!XM4-]syRxM g~*u ٗfR3=zi3?Qke!bIGZ)8HWyĺh ՍtD''X قMJ3]t;U\s'MF3J 91Ԣ [~MKꝫLr C17ZԽ|N(JT|ZW< (\,Π.wʑъ꺭*+rF|i4趑i%LQ*ku# -Uڸ;\uC ԰Ms^wnة]_ Su*yeA>ȍ؏W iQS&mė ԢT.W*kf0Np,~([wJ@W6܁#w毒yhumCe`````````````ps!qyikH)z1o)PVkuJB=W}n ^ESd;C(VTqG](?>@%tGc.M5k5!5;lZȋ{摋DŒY cuevL !^MGr1!& SbN(=8(PDuIl:1~D/>ƍؘXᢟ^'}ʡ9ɊHJ/N`?Y~Qgы۟nTE-Q wT(m5000000Vp <3?ys-/ DjDCBu%u&TC\4׺Rɍ*" hsrCVWUAC|OS<'&7˱W vExO5]x)ĮM)-kfr!/9%]ΞO9k99յc/Zs)')kŭ-w}yexv'_e.}s|27rqȕsܙTSU !mrL)𺓕\( .!Q]Uȅk#&mP!T A۵(=XbtA[(.L3;uSi?Cdt%H8DZ|yކ O`օsŴW_: ,xW]ZfC<i|ކap#$td҇uV333 wբ:nGϵzx"^e@;0TΒgm[EȼJVYUvFv9,m+PWy泰ҡ 9}3Z2ۣ9׼yj+=hj=_ ZuX~+Щ\xLOQ&1=NBf=2u`ؑ\JiꈂWfvrAbxrT!ūM703Tzw.1PxZ^f^ugE4000000000000000000000+׉B-嗅BrVZp+ev\V1d^:vV"y[ڸRr.A%%kG?ꠀ:juP ܨR?`ΣdSo?oj @to/~س=&zf|o03xI~K:zGǯEQeOn|dž =WlEMjf+NBlנ2Ϡe]XVX6-i[4E@+ԣɡC& Q}lqr[ؼ!JsrK9)_$Mj;}{DFyG#\1n?%!s>Z^vٱSy8 |O~ 0lbql];1fL4bˇ85Fʲ7A^F܁BL[I0QҸ$a&UA+{0.F_H7aqm C!@of=ہԾ3ЕƤ0<{qL|DDiK:`bqiHH)t*3+il_VIJcΝbkh\(#d)ۋJ8SW@ JdJ(&@;A,&Fsswcr` \F̦z,DAre!\ ˴Q9rI9Qe[1eeQ"L7=)MQEy]ŃU)}ϴBS>ĶNFUڃc`UeTwmMF|Qw*~@|  /<{/ W9w9N2t5FNX;Eo!cʅm?ςgvO!Jk_{9@ {j%{G0*CWbiRK=_urŏ * O6rYXn[t 7|$㫐&Z\NOc#eqؘ8d_JG8bԭ/-B4έR$if,G%g@I9 \^"q,$i49,óUEfĢCg&(tbPB|i\WB.b# jjU#O@T(d}tY> F+")q@#ḥ/Fǡ4Ε2`9wG @n/it +£y${Q1`P p o4Uy!^dVϵԎ1SdB!\(5yhZVɒ}JjqZ>Ɏ[B$c 0aU)]$iD%#4PkjC9dJ)eQ!f=oƃc`` Od+"DY}.Tו2S{閃g{Hǜ:eٚ/g)PQC%VZo%N>0n7lG~$D%M%, d 4$Ar=ۨYr*—;ըU7(kp vdeW],_4 Q{Kң`̲.(DUߊ~^G-ME0*RuکHTrZ8D$JZ?iA62til!AUv^I2p6+[LYp7dx8Ja:-I$ſP`T?(cp7XMccl2,`c۩")\q=ɗ+neً= #@l e(PvD1!TS B*]u_>WP!*%|~1 1 @-,n=PreK])5{a͚wJ{ϑ9J騭F\-d[3&x |0[ ~$()o2ߜGΦ~M-g&Wu>$Pjnmj~/tʳ>q FS.\|/=&ZF^y-/.5?ERHK\]]~IFVzY]Wa5 Jno| Z=7DǑ^sy&צWQo/tlҰ9v>f߹+#`&ߞ4xh~uxmrbq)as~؍Ϸ:c G┸)$7nA R dC q^|'Vy΂|{mZ1},(!86 s'r¯ײ"k(%oҫލaS}HHˊk\q%!?BOWUFQL@H]aI򉩏e4hk7}̰{wIbep(RQ‰!!qDIJs[Qr(!:rWt+#H d1*eu2#Bh2|'Ib/36 I+o.J(~U3`< 0J2e )]K"~*Ud[G 3fHCIÌ)Py^F Q)&6H./S[Qw?Rca~_|+o>000000000\(BRʃ|q+n9q%.BчNXk/ BzH(iGP;GǧQG<姣WXWW)U DT#^ QUH\UPVQYkC S)գ<\EV˃NQ,ڀ\TQT$D]hC|]+pa:ڳ$z,f,?BBΜ,]9m G{D!g(^⥛]wބ]Xvm4K(%;j;%!t-(2MQ4]`%%G ppw329 #2 S#=eL1OHIF7[6JIZ\ ՛y`~uC۱:9K*څOcmb󋖈XmUG3%JIBZtNr> 3/H@K,DխΗaXy&UADuj:2~ K& kQirPйb̽Ѵj````````````LT|5`aT=B=X)~ TIĥd^HhBC-.PZ idϾaZޛ5ZEY.}~rٹ^ZR/H9SxUkZ;rm0m%W 1)`fU v_.GT~NT$;6/y%|ТRJ@FTkٗ{P7I.HU7k‹Z gL9i^Xuy %s8xx*p+C/gPY(fj]h;J>eRj.-,Pj׹T r>c?cH҃`49$v8O&s\FB CB)2Z>g+Xyn`$54ivsV0@9`6$6000000000000x8xOJ9rB٭P9٭iZ6J -wɭL5;E\ {1w`Σ|Rm3fߵ6< 6G>@]> +}Z>U6Z~ؓ7*va6o{ཟػ'xpz{Cwŋ n,ۮYp.Yװ;L%)sByB4:^ŕrV/8C\^g.Pʚky#JTz"^Q)Rk\+~|Cǻ: r<)}v9}O:vgms{Ka|KnuW]f.!э(^鬋ik&W$D.$bIJ%9e7 /iP I#6s'W IKOU~䑘|m` \."m?'uH $dcǶYwHPPx\0 (3S$.݋;pLip.HI ֫/ CfP|(ꭢLeJ0\6l2sɅE MJZ6Fu8U23)ysf/1K\n gK%܍9|y;fδ2I)p?.m_lJv¯JNRrAA  J3W;(H ~3cBBktwZzջ@'N/ Qv`#; l|]B.Dt,궳GЊ3W3"~<Ӝ}ވCxU9?{,z${BavŢy}ʳWLrVFBU:a*+e܊#'*{ewf̳Rg޻)ώ~v4v$;,֢ (<&5ٕh ^ri1δT(riDH8CU݄\Z g\/!SuJW`K)2ԸR>P]{29bvo |wc;ȣCЊ#rvr..pS# o1?Ȓw>;J>UNw>7_!sw띫t"ؗ3_Rۗ%ozv:MNsF;)3\ ;·D*eepPWuU|.94Xbu b] B/|R=I(5*'%ӲI+JTp]renRN+pȮCv|QBϕBR%]Cr^i i% q%J:ܣR.au.'=$ z 'ɎZ7\VMirw:(ޫ%g@Q$;YZA`G Iӕl]&LP iøMLoҟI| 5r8_u&s}T =4RQW% >俑6nL''jL$ivi_\4m{#zIsny4&KwD{ǂ:Qk I\^yv[G*9F纭]G|14op>g1 Cl6 > >0y?Zκ50000000xX=N7uWqh7Q*ĥ0wPI|XxFŸ+\<~r]gԢk-UuxikU |XNjW%ql@T@%7ҴI:ٝd'92],U/!z]<_PN#H]3>R"hyTq1;)p'*;ڥsPn鎄|ߕP)< ;IJ}ۑZxg|9 |Wg R.gZx$zS}ާ |h 2NK6eDpKUt'vLQ``~RSK d[6-_^(>;l[^o'>r1a|b )q BN|ZE^J,TiQv!^[ CteԖSuxԖ 3-]6N4j%\z(9lJ~Y.z\a@OIu+E> {U= mk5o$/G,%{\Mɨt(m/%$v\ULڎwM(i !|LG=Hȥ5‘k깊`;o, ~ȉ!y"i{nEӞ0yAbZމDN%i`@.س\Ҋ ?upi[ |3WIZD8AG~\6 i:j鎓\(01&OwQh;֕2s1 d¤I9$W>W^E1,V"$Kb-^ ~E⹘e'deDb {i(Iڕdh2f7(I^2DP9pTύUx`6ApnF/6˹PU9( ZyB)3j],)ORP4y.\%1VlCq@@Qhl)UV2Kcoi#673Q߀'9؃{6"%j{Z \z{w/0.i '/n*3le300<-jwZG|1 N8s.pV寫~5l[t_*>Sg_cL~ k]}Yz* DV)pQ[((^N+)rpٙi3ӽ-*JuROS[Ǒz)!? RȕH(9 \NkznRY|w-ColO Q;DI9{ )9%_%VNv.&{Jې=y$1_>kGBRq;DAuP]nCwsK)uY-i<5Q9qP@E2Q>t(SBta~Zk씣@@m k? jɢvIxc|]ou*u]NsFiQs)7itTRQPyqzJh/~ri2ԮfJE}М:E/J yzf`GZKvj>h4;ֻW(1Cvr;2C,\;Nj}Se{h1JT*iJ=H&gOW=~B~4D{Փb X(F_TZ[UokuUN,W3Ò($sȋ#U4Ps@мԴxesΐ="/ݖ!= > |^m[=dُ OCK_6e5UݜdE2I~ ;D2D\.Q_ 86r&Dxɕb%ew=X؇:u8!A/z9/ 3"Ĵ ~80 dqPcHP R2S'~*w.sY"-u hRɋ!H] Ae8U[~Wɗh^_0 U䳎^NKnNyP~rUrG`< oAn4C,Fi [)| iM@cc"峞3 #d󵡸ٯUL}LdQ<.kpskJIJBI:wЀcNϏ?ꦏg*O|=g.|[Z.Ps{i24vhWach\~$cR.%`x啳!(O3~[2g|FަD[JF]Hu9dSdֹ4 Wy@ ŀ1)QWmh )jQ gOу~(UZ@wG<<%IΒ_e]w$q S xԅ˖QE0 -ڵQ̗d.-3gոڷ ?A)PtV_Z b Y$$ƪfI$䀑|[ Z[17m\tq*dC-@iʖ"'{\[xֽ@Pj!lEqটYۚś1 '!M;OgN%M? GR7JY)l!D Oc I1 V],{O"C*%L~Ud[0& ÞAcX1!3Xꕧ$/K;gX!y N$2,$}$2SS)CT2e>8؝  H[!b ''qO9m6ӹȅ4R)cayiٌ]8ALJQ Z!k++sL2 TQs R=?<6ζ.@%W;;0 '¡t1wHa@dg M vଁgr#,FCSeO:F\W? W9^zj=>Z .WFJEyvV7fWU*>~J_dVBv\Gr4WɜnLJ46oT/}#M|d=@Vj<0\v6n^~@]G@?p{jWMyu rCuatMDS_%3ֻcZٹ냺B 6`x&91_sY .74QE1ԓ#Rrvc400000000000@5@ޭR=K. W7-WVihl\Vx\r[g_ RLx4#,#5/j8cl~=Dfv-ђƉzQiF~8}6OVj𵠆jlLd}3Lm^+BFb]ňc7΃OexU4K"K"=8lm|#N$2MY+(pxt912Fq(2]½D>E[0; N^D+eJₑK$i SʦudSjxչ^U4;t^EvNS4.ZUTQo:1H=]ҕU90`z8Ebd"UhEŀU/A_o|ѯ3=mTHexd``pIE:6Pדdk^y_K+TJ=qңF:sZurEfHuWu\CC֏VGH]cpm c)w@9 j}1Jxx /\G1~꺥x9JQ2#s~{%hkDfoI>LO/KPR DcQu9~uj=*ԓݏSb ~, P_FOQP#?O@, ~*<kH%4*rN>x4bKt#63='l's G&ΐ76z939\ D| K٥2r4҉!+>bd#c`p/JV{l)&;QK];!>Wi^;_ˣ+qFjXNPI40000000000000000000000000YL䝏/L.+PYW4_)FN1+ELxؖ^.9vD}p9uMv]GZzFܲsl'q7 1.JrX ةSvD= F I#-JQA+4}.80; ms{.S'0HBJ3ѻw\nPكr#-lNtfܑ,Jm%˓U#vQ|d򽬍/ı_!rJbW|/9^U16szK<oJ!ƞ7LPgf$9JA_wbWGא:Gl<AG Qs< e$z,%PjEE,: .cL 'sS%"M>dWCU!{eMs.KA9 igF>{ UgQJUd(AwӃgZq@ Ψ@&$t(IJ`z]~7sMb*ek;%:1yeQUbDy&/z4yޝ:WbGglK6w.fBx9 o5|yD.siFԔZLSg$ڰ9iOR;Hbl )ٽDy谴1BJ֢(.ȕ<=8&ouEgm7*j6`ư/:4_*<~tY2J5&L%(QY/9UnugH씣t7#WEթgmsח %]0 G[^pT%qyא+&ç?{Kyh mfwzGf200qs>OiN8^3z%JD!D Ctgv{uܡVcOf*<\^6O`|r1ɵ@v:W̬ <"N/gG=H|UW~{9&(]L\Eێؼ el:$~&hd)!DP5yG0r~^VԥdF=`ȼ385+cK5,3@{Df]`,m65v/[]-9?X4W!~*)~v>ri=$ܳk%Q!ZaԞs/yywkOnG9>K(9^W[ uh-P驢1T靔.}j|\W3/?א-US|R[`1..S̾F)*rOZUVpQ@BBq\:eu@I҄M2@ԎJτ DI]΋6uT YR~UA-!|(g'A]ً`3ւrfۥR/YU~y QgWBcR @?OAX_'-Q$FKSo>][ܣDNtp&*P/ Ux*e(&!YT $D+$ab bhBIܓblC`V hR\.GM1P3( d 4 ѹTLcTW2h?tKj^bQ!C1>{$u4>8F*XSBvOZtA$F4CC|/;c 0~8)(^`3=:e42PΌR~Jznڱp!V=hgUȌ@f9hSZiT;eFbLкɺi93L/ B%,5rDey Ȝw b5qxMS8wi޺)Z1=Me-רX::$iRk6XP_gWVqoNܛjT{sj9Ŗ7'Y.񡷂hgϽ9Z {kR a@MBߛci4thC4tx)~gm#j== => ~rÇj} Ԟj)QmKxМ[~ ~lW;@nϰeƻ+iH)sy:I~!ql/b+o eHSkº<UrPJh%P*C=P]!H,ʬP&yBL@Z*< E2 BQ4HVQD0eչFŚȾ$ꖗ,~ݱ"/&ii~(M^ޥv1|+Ͽjy&1m6&z^~"jb=j ZPn*ȁR,^%f'ra>$pa'[EcUiQW0!j$7N/#7s bqWĻx_^$P˲3H#ZUr'/cYGCb/bDeIAlaTD2͋hI]q5s)GPnǒ8Z(&<K\xǖ,&$D$vhi:%L3$QX81HVƄ8,<ƏKc$_4#4Yf90 -4a6w`4CC-1K":KDtq<vQ9HFuA1785@)98fef4'4HE 2 .l S,fb 𝺨l/̰^ ADMҊ&,`H#e b{YZZ #XZ+g>8QPmKFsvk.l~v,1fq4h sS9 zE=S~ 5&K]k^w{n:}\1ӯe?|Y:6veY| GH4t%졗LJ?ބb+TB Q[K,eMӳ¿r~"!<(iWGeԫ W.4ky\oiD͌ӈbl9me -_ܣ8 hVFᰫA"gWZB>8£iw~Ck~Y)viRٞ0Ę!18iLٝ>Og˕"d$6 > 8/uLm NS|זݰ} /'ig_fQ2Dy8%O3y0) /kmm}!^4iWʝ щl hݘ㼸CYUD/+:Mc2Wf?֫QG\Wmq"R:4|XMWa81:gYYtu@a``````````xl S/+W(i>uKOC+מSC8}U;'C]g````````Yo>s+rŬz@ԑ/UvK5M.|6׊S@-Zv.D.j!V!f 䋘YN/ԚMx+lMk;I#q_"_.gP{Y0ŗ{H&Ԯ+w\S :An/>2oro끾./]n2W{ z? Wqٽ\+V¨?}E~xYRʙitڃ9[ϐ}nw7UsGd5sQZc";m6$׎^PuWN#N/.\ƨ#8Ҝᙞh9Σ_Z]qe#Jix䈅F:#]q]v)&'j_ͤO%~֑w_u*yˑf'R$WljٟC򻅯#9rNԲE6Wèt9 jM2K+dթwiNe4m?yLj\Ty40,*~E/ʔ-d݁tY?^ǹnҊ qBbWd$-u#J`tJA#JJ<2SQ؏4Z ^2Kv(I^m1n$k]2"JW,Ƃ5'Za9d4'\F?$32ZM@ '*Az#|LjʐC4o;X& )Ud}J 5\EBw{i.:B6;\4閆Nĭ1|;EPWg5m- X^: QXxVꦟXwj^h\*mF8dR{4̃&H+te@ǕR(#RL2_qe;ًSRWS[;|Әa$Q&*{,W6Ë='1u 3 95#X'ȼ,_J\f7'Q"3:.k,J퀔{O2IH%NfQ}[3c8B<&8 xp=QYN&2"%qXf Bƻ{Ţ]T8 "a}S wW@,(N͢W עnX:J J \X5 V2 gĄ#TӶ] +j4 _XyJSWVK􃩟oN^L&RʃBkaƱq400000000000џ=G RzRdSq n3dbNM3Do\߀=>KKdh)^SqQ[aSDg%C+l]Qy32C Cx[^h ZmW[?[̌w;G`wN^"J++ɕm bH!Zk=Jւm lיs%r&LVD.irF4l[`;6akQfv*bXΦH<=%\kL/ |[Q \]^{94Rrt9rw _rd((<\xfx(L&Lȃ7:oa t> ʤbIܡtӯ"sJHO4WV(y;A-b(fC 3Lc҄|ˍ\$~[2xDg^~BKb Ȯ>]'Sٵ`;McCm/6_uܘHCwCw(Cvx#= ׏)'T}xY _.R2Wh1=$J ӚƒsӰF=Mc/9s^TXJ\(Kג9['mvZ3]|+pvJ5*ĞkTQ- .ЈJErq"<6Q3Ӫ壯UU oW-S 8J':Y$ ٓ>EL4acϙXfݚ^D7La =260,@SŖ_X ?slS֗:lBL9M9iJ],`U/CXsn`RojHTKhT~p3wh)<JS|u/+BmY)\ϝB#]j@ԩK qZ> yW\JWjK{SgQR~ԛoK8F\73&M%~_xiH.:띾8|v<0fT~40x(%,7C:>xJ z1 ~0E_ff30S)Z=u5tqMH\CɱqȚ\T#K#~:c :PD'VT۲R @Ykߗ︠LTQ6JwTcR6F^ZWz6yq|0ɉk}G^C 7ɣ5Yzϥ뒧vZk, ڿF+˶DܫAD s,uie WN1js_AgLkN:#T&8#EĒ+ 1=X jr}^!u,7_v&VVlgϪjTm61ӻ'btths?b(ׁ:ZBN|{^\r{s[w4Sv*="FN&WV7,swhkõ!b0v)JJVԫ;1Uv=Hs 6``D &(JHSˠ=\,x%K]7 IeX: ظ~ȉ8QTMC-cra5Qx$Arr`"ɉ20XdtڽSќ2D_p̢p*c(F0H ͊.K`q+dQ4J0Y8nRWQ;,$VTLRu*&س1q*v@K]PKO& dEj/[ԃLIP)9_%Q z8b 0g.XHX&2waABdc!YQ^FPd?d'=dF^hJ#ݝl데2˴Fz9b݋u+aeOJb!2Єޙ@Ԫʁ~LR`%G4?jGhRrA"4 ˩TJe:RRaFzڿwh``````````````````````CSΥl[>=\V.;^SŜsOC}Rt!^ %Uga9N6Y*?sÅ`d>h`y{WklȁkA ƒwm#$En8e8?ջ#ꑺ+O eH%rإ&d)y/Jy f%+@ɬ}PLEIv(aɇsَ75ޫ Z Hv}`H/$v(6lf "nI]34_wwOmL)sׁ6ȇ5Lo]YM0OVjc@e\x:wZչSZQLDDqy#_V*JZ< GlMt] z$>XV7;U|@s4ubvF 7nCx}v*yv4۔YT g<|`^{O9gvRZ[!dZ).SI@!a8/!wוu /.Uruq5DMuʣ|1+P\[(O1;\dRoWQAox%Qu+F\(-jVMտOJf!\jlYOg֕mGԾytDT3+egjͿL+S1PKCҢ^չA~|r@k3.r!í9Eie(~x} *q#3P 6f.8(ju.(C`I̒d]PzX/xԅ,d>cc YOgLTMi;3A"*VMz8q)3zƘ)cˬBˬ}G/LM6 iwƱ=k10000000000000ۃ6JoucBnMW]Rֿ|+5d7k8Gv2Zs>mqV׽ l8"N9#uw%^?|.|i#y4Q|wx.O$ǗS3ӈFlAӍT9g3+ǿ6B^ {R +D.RyJ12J ̮9s/9x%ʽFɑ{ $7@BjuZdXL0x70200zb<\<"8^- S|(?=J9R^(iuH˱ޯ㚽d={ȱZ\2\?zj?C'd*Uk`i݁+Hm Hs1]uޒ@-%(ۚ|8ynl\tU_|$_/Cj@ 5E=`H8S`)v@U_|`<<#ΐ"hi5=\p༔k$<(ᶒH;2$Vy$.I((' |&!9HL,2QBg9 !6HdH-u]_wR$~ia%yk $.CUki4ۮp萋6!.Rjn)6uEYix$ GB&̚JQVBS ^}jUx˳.$Ey(}!]ݐ(n%"HM\FyhhsQd& ?ji)^"J^ܨ:kC6u ~~i"ic1VM%m1QIhp q/1U_d l Э^#uY/T~%W.\WGEҫ6P띞Pjם2#UWjIX[Q25W+)p ypvof^MR:ҊZzICT3!=+(@.|99>ҒJ ,_7G$fS!˷7_xv!/}ܜ~e;pg:S|rJgןE< O=q})(E|P\o~jZ|qx.O5JK͙|JBua a.CTF?zV%w>)J_5ǟ1Tl`````3~ z=mq=A;ᨶ'8  J9*}nuw08.X6ڴ^iuqxCX9K_e9__y9jg^ZNEIvˀ3,:G lQ=i&_ Aq~8ZyrfQU\xBh5!Jʙ8գ0 E2nKele8S?E e RNt[ypN* Ĉtˇj[騹j7x̡;`K`cj:R-NEӛ~m瀯kWg=APyvi=mHOݻ˝ 9;8^ʼ*͑#&q/16_=>ɾE8"N\upEIOvʉ6 ЮzŽ *ՠ{b&{ Gl`````agG>*yPȡFl(Glrwdc~c4ΰ^o<`| oyN,p!o qȝ8!6إ?RDTR_ak{ͅ(u rsr'%+Q$dͶ O})Q,zɌ5ՈHx.犺uO4 __|i+I]gx[d}~Н ćcErAf_ >}X<(y.6uo2%**7Z:.}N9 ǶV^@]_̕QQIZ'r4S>OlPډLEChsw$\9=%Jޱ痴eVm_ 5r)e )m1rEG=+aTn+\&HttԎz*y'$m $_ץr6{G@څf |wd>9ݍMQr gdׂ n @w T jxHXޤ]G iteGaU0/ՕGĸJ-W; H{Ppn+pƁ\0B*V\ֆ3:|\jpϻ>h 7mO:G{@p2,[=SՕD|ºpT3w~HJfl9\KI5Rrˆ́(ƓF*d;<|iA3~ f? ~,X07`ocyJ;R.X{l&WGl^F\bkxz+Tꇟ````````````@%(@+4.@wl#ko{&^a]uG;{T4x;iv(TmBqLuT[)sx\ߊ=oE)F~=DbW9r;RWs~) _VWhN+xW|zHl뭞+\J)\mes؆F>P] 60000000000000xtٞ |ŐG.ĺ_SNipy|>PBȾ,9oSW_{jΥz.NΖ=m>cr^(mC. (GP.%_%m >pKd(sHBTMu**ХQ#JB:G6|9(+c ׉ᕗSLX_wDz ^C_̌31<S[y!PsҠx.|G+pu^w{5|<<gJOTTK ƺ@j @r s=%Wzz̮Zk[+,-Pȧ5V *Fu!)ijVQ3P(..+z+8V$?Z><]”ފ±z+"ފȥ"؅w]}JoMƔF+ZrD~Mr`&o|!?cwq-'/tFS=V_/-c?n.M|߮^\ߘ$o{սn<\m!m27-m l8\|mνnO9&@Y\(8Qq~JO~rή5t8LJ0JT069IydqtWކ-PZzF[#$7z‘CH~4l?-3S!E UQf]h{.VqQeI2Xu/d\rB8Ĉ/T (ݮQ}[*eGR\TAiLdt5켱w4'̺^2ncT)8R>TzU1x-+P^)e````````````L)@7G^235O_3Rm+_f````````````@N}$>?+ϑS>E7uy{KFbkvEd>@w/;˲8k~‹6NIEٮ1M;M))xmە nTVDvv(|t}UjOw}h`@{.Zȗ$}L F JSbUB`ge-RKxITЯ(#8 8r͎owd_ &0eVhE20mL,x1&*Of$(,&*éCTIlҴ* ^&hQ˶B]A(*ft6R`#GF1ɢ3i04]ȋŴ"Y|.kҩnKÅ#Ӗ|XfX(DU[2w%!_*x1QCt/g4`ƣqb2mmK.z-i T!q^\J4 $"\jᕱ6?R@s6jEwզҰh#@EEE]NC*99L6TKsꔍs2j6>(u4 )C˞Fҡ-N^$WًD9K_VJ޵R~Ħ[SPCqtтG5g|E(r–:6.gHb.nI[%R4g~;-uEIRd~ەsStdfNiIRϭVQA#JvK&Hc*$ɪs#o(.!B&!|O*}}CH7'DHG2n zcҊ*gXNu\͋,4uM$bZsk[PpqE|}mԳ FtYZb4:m(BǧޘM.!F?;VY'&#LcuSu06aSaF) b7zO۶Oka.gD Ϝ/jGT:@cq2 8>ʑqĐ셜 G֪|Ne/Ul TpXYfd6t/moW j1s4(I֢E KQ'LaJr{-iwZ2PUnTւQ6@̃31J 2d}Hl@E072tF1mLN9لnB/Ɯ /^ͪ ;^:>{*B^@S;{Trp|ٸ,FS@ ~y ~Pι|Lቖ*1uj̝r S5wJ\*( a˹p)TW ):H]UyB_)Cf^dyǐeĞT!aGD*24TC@9W9!sa"O1zrlhj OCrt}>P&Ʌru3}r(LڂV(a񹇐+dO4/h8d {TܻyE- G5vjfwc64M^騎< |. 6HЅ(GfI ƽXܧj+zTORcV t ZˡjC7\h-mLEG{֐'r|q~>={aAW{e(>M1d`g{4}Mˁ G?l6x\vc$=ɼ4|iX?W~QW%e8c1~V|mEk~7":ةm|1 R,6=ܐF+kQ, "w7,j 9lϝqP)68I v7*99_MP8W["ϨF4:AVJ>ę٩t' zyFmTQ OEWBb4000000000000Br@ R4#ux7ÝÅ׀} * xq4rcn`mᙟhPEzh.C{h`````````````````````````bq%*b';Q? >\l yw!ԐH4000000000000(a@y yW.W8Bhm|KU|"|jQ rV'7~ q,|Q C1w+)I+4?4Я*] C@ ߃ >嬋h{*~E]-~V·M%?EN_V tMѧwj`````````````````````````y_weJ.N!)X nBMr0rP#G iō")V7?o-eR|J)WL4]J*veb;#@8 %V;"1ԋD6P *}q&WemH9I~R-#9 j2EXw!4(/QEr8ILdvr)@fUkA& [tZyiEL/%|PDPܮMҪ.gG;J(JUvU 9ՕHİ@:V4y.7ЋE4%j RҪJТhHww#kz7ŀƊ() WiNDg![E =T:J<;I(dym$GZgJOL$/o WejX\kY㽧y߮4=rr@tz\k죽40000hsYx1 ~+ Q@9r4ÁRe~+ o%K|1 ߴw@rBv}!InQlwj 0@ӇR]wu{A)~?S|TJq@r3᳟ݟ _ 3=q.Auw 804£7 0 CR(K{M.Α400000000000000000`׾s;A|)٥RD}bZC\v(FSl/ Bha`````po n˙;@(T^EQ*_rʮtr$Lst91dVOQQ.dKYUjH˫d]rD U}彚s?)W\]~-ɤ2qԃ[n~%Ԫ{8{@b@~u b\Nlj J3U|w+F;,PBl!BέP r’k;@Օk RW.P]![Kja]Cңj<) yZ[7yB] .Xr'ɜ<ŗGZ<wsBeWc>q99X#*LR FI\t)ĞMgIZL\"͉$]fA'b塺fPGip<.N[dokW >n &Oۃ%R\QFnn_kuW R.7-:di;rY |i66 &Ѕ[toq=?ء6u4JXtn`YGk[ͳ1.`f#E+CX׭; qx^\|+&D%[yi2m '3p"BFi;"dQuAf$Cá F:i%ʐ[p:O( 1 '0p[~تZޭ%7U66"Ul<h^d!ap`KU9,CQ]mB$<fuImNaUE'LNA\RNvefeުncTQ h^Db TD*͘ᕢ6 \ym-sy)4/C>p|'0 ~_J(0(զEjݹFP 5y}ݽu"8TN}斧CwKs=&٩ZNCf2"g!M#:>v:l0E"@lD(mێ**?CׂNqzQԏzsFM>cG n󠁁烽30x_X_:Ot xE7g OSHTeGr8\K^-|}Dcׇl#sd 4'{/=qѲr$o-Eiqdc@.*]*žy8E  40q( É-|q(ipO#d)}PTGXr,Cj70re2)K.i_+pv ENGITA> ?-9eKc( !С[kQ5& 8q"23bc-|Y66#ԭؤJ|]Up@.F ;K'%u SFbkʣp!^xj<rtT朑p.Nyg`1rQjOpv@¯]䡱;g.PRfp/!D D Ԥ߈)zlKBP2WPX~6ܤaui<15%^h-_嚢]HH.%1Ac'.a?*M͑.@̅%tJiRLۆA. (mLQh3,ڎtw 򭀻W@Z@9'ҹt6DxpY)Em @WzҮ2vKct]@xϽ) VeVQc %(bx?cQZcQNpG-w8-U^V*ʙW Щl4O#/9x[7䌼5<&|[\׷v#8=0:{#]J\[я:ܳw7<;i8Wy *jکڳ=quY;iEZv[^#HhIqN%_j V!B/ȣ $q  GL 9JLM 2)Prт!N+/A:.̷Ȫ헻m9n>p{ã?b{Ņ+mH]6 d?ỹ'L\3U T!m_Uc ទ(E];˔5Z>N՜=)gx7Mشe’&]6ev&G#7FkI%.p*; D*k7?g)0Ȓ`#c݃R7X-y.O!.![Ӷ0xf~J{8d*3Y=5˦D#X*q'?< r$ ,)])%Ƌ}ysv5r T+540\`}@Ul7~79?HY60x:S=ʆR.ەp#|A[ T`````J饤PVRt_XSRzJbb{1{,׳_''cfC%maTr?KZ R+.|J1l50000000000000Rg[b" 䐖W(EV(R[Bq).gGxO|hCgl&L#{~[ |J,B%4_6z_Ba [_ dx BSJIFƷ(fkOd9dgkp3~ؗʩOܜM}W7:0}Yzx~ D΅Sgf\S;?B| ^ɽx\0-9B uMB95kȰN1^PJz_xǧ:qOEpiܞQ&;rgE?(+!X.EnS/LCOh]Rݑ,-C 0 9!$n<krFŪ-CQRe6!FbrwE"VAݵHUQ0$~@w[?%T"Phtg^"n(VhEV勌 nGu*2ҋbgH-q&}X ' >I 7Dҙ꠺ƹD-dC 1 %ҫ;"$"UbGaFTVYS(OX/vشB**Q/*I+`6N[HVbJ}#GVeߗ?x<,V?sH1000000000000w^(Z9֩:I%4ODo)Gh`````````````B[7J2g,CwЄf Zm^H>ϕ1v`qT)eWllk|U }?JAAgARtIU(g_bu>E& @T϶ >14x,()-Z&Uur)7oLO !q :Dcŭe-gN,{C0!B >2!q/Syk|y`f%=큙G&9$z[d.o`/@>ء[PHV̩*.ZG!8Pԋr޷B}׿_BIޅHo+$:+BPr]9^=R2^!?Rq v!tb[e!zR,qdW@(T30y\k 11Ȝ}rԂ c`o@H>-[Ig0_O?/D|˄熩/n15TWJu %9|"00000000000x8 sJB.pIJS ).Zj'!t9^7 R7u [<וS*Hm W5_I߹! /"gbget,~aI^\iM`Rj&0Z ^i;7ֽ5<ާ?oo:R098qUjyE78 PnyUC5L4!S9hhL=:jUc#ԧwjdG &o֠n4:cJYl6Ӫ'%G*@Pa2,S7]cMY{LSjH]R}9P-PY&^ ELtgS/#e/9R~40000000000008!*/uuR,&T}yT-s_[чQ k9K'.Z_)9A[7rtpzOuSO$!)grP~Q|bmv {tA&->Ŵ]8>Z {\#tfޯP [AGѕD?PLg̟wKetJBTjRm\Nrj K'0ȳN[v)⥮Q[oq "%C|bL _IW:Uu*p/k&rr]Es*^x֊[Y<4ܧWZL>:L3FѮj)#/燃1o:5C-UA,3oYԞWz1}Z8e}Ωv6 9TӢϵu"riP@ęsƒ ϛٞ^%ŗK)@uz ide5+#h`````````````|9^|v 8+J] 9OTi-]0_RG\ߓ =[j+?K[x6#7uYBV$V)aScH'6>fv0m62ye> q׍0FݙS,yoVxPX7zlz5C;Ƽj %KBx%*_dpMhn뎪ʜ.nx`1t>O\"HJTyDT1Œ6bj}d'c76xI;ZޯGЖ^v-̢W>"0o@äyĩLs:IsU5,F^A km;>Y >ICgK- <*l{AAIA@IXUmOgv2WWuY;s%0O2ݺ=ئvΩ,*[ zN@:O9էaRs vW'u1UsNS=j*7^K&JqxkPbpJ,*gEVMy)q*/^K !VAT ;d%W_S:]lI 9x#KJ5Ulݯu ?hXIvђA?Y ,9ASj{RYU5􋟾ϔj!+5SPF+#'㎽ɢ;󶉩So՘*v'}⮣@"wʰ! 륜y,w0 .~M$v$eZ 'GL)Vb U<9H9c,V!fl c^o-SVu}AIc6nepbRu H$~1"GDA^IGӵS-DtpjP,J$5HtPtPg%^(zւ@ 2#̓wϐ#"f;\0Xhu<2u,XqzydEYq;㥺|Ѻ  K!ZhN2 Z9}~X"j, |mCf*&qd, CQp>6&"h}dD8a.MA'N!ɒ0-m#bWTkS1&`^}vMQP9(b^ Re-pz8!eqPyeT&yoBŴ#:UKNR;G200p/;ot+|LC'WS kv+I)\ r)г\MJܢsQ^H>ǿ!̠&o&t[i~A ~ ܳ_uo|8VJK\iFi\JtR^ndG.y'13OIqega````䠷W<:+ByvHm @:o8I/$? `krEL]vrG>yq$5P&fw>m-ᣃlE oր>b ;wFP5D RCWC ٫S>8A fG]+Sc^=xHwpIŵ)Y(\r߸Ib95nt( j>iq$Mwu #O/D*#@HAV6Y3DYV*F`lWYpAQp`mgWu7gxu8u>81|jҋtA,TAa/,ePL}6nںUPBY ӓ|CT2.ڑ7bUjb^F 0 E^/ط#J Yji I{& Npb8,Y3J]O*·NTG+ߢXm(7Y8)xq c|ٿ+BWbJ+GU+uV^O45jhN pd d%Uʠ~&n:@g^г4)C)!l A]Ty*sfQY7gZi!}k}i+r5tJTJ칾V jY)|w!r=!93ueH^^vɔDr\n\$/N_Kqrc<\==5U <We^.t=}w\ .3Rգ*V)ƵdZB \hEr(\^]*qGlOo ]n( *J.Z#?5K/'; ''uybgo*ߑU_c%>5."]{ q&jĕ2S+]{ "L9Q?fKh soc8Fꊉpe;$'0om,J 92c4yP.\eu; m{\/ VO6+&Y,mdIcJC .}89DD:ѺH7C8@OkM7m bw)0R 'T]!ڛUf-cqHh;g>R<C/d)0nձ$e|+nA,7[8/m~=p97[~oڿR;Ř꠼m\(5oTj칵9pS^MCJBАhG!sD6+Oc@g%&E֚;wԚ:aS>4DJDR+'u(|%XHQ+/Bj֕a0/.o>*οdcw<8M=6zC.݌~"5vAWSGjʶG.u& Z'렼)k*qFG̫Rg`PxeFHm/#)+knB,%)&f`(THWmy6H}cd4r /|:A) ]rd _Kߟ>^_*ϲ_YB{FEudAhH9ľ>G=ק=B-SH{Aᾳ~?3X eGt0$<Α_9(3~O>_:R >nc````t/s^T.T:xGa(^&e^2ˉsW%/zlpR n}f}#{aM-&|+wK7I|G]aI|S~YR~싞VMw_8L<~=)  ߽cyJ%RNoSou-Vњ_bXc=5?tq_k9}EAŝ[eՑ{ !R[c) MNGӟƱ>ɡ4!9";<}p΂l%#I6xbIAʲ9pPpcl]0a&關 >ӟ 9bF 9s33x$G1~8sV.AlR6S9!IPX,l4dp.2 ?!oGs_UĵprFx86l>>-҈AϬ;/N^*,ɗHDV&Kw!Qb1d%r$r,)b2ѽx,v`DJ8eYQ16*B~;S8`ꑶ)-fYFCT9F=NٝEl*eo<m+1Qd%35 =v%<5n,flWGaFcdYL 6:ʈ,81_&ʨZæ/b51#a}X1˄?)5_.l3G>p-QcaE5ÓC\x%8I@cc>H1 Y4mzF] O]CO)1(a\uCM^7.]`````````!߃dWYj?eѻBʩ´^BMO4z(SS[GVkm=@Skmu)TE(/_94.̓c1 Ex@ɻQX8|)qRxHsٍMHMǣwYXF߷U9lܺ-_;I&ey_ c8>Y8:8Kޖd&Y3&.w)s".ZfzA.CUaR4\g$3ǔQZ%d6ank d~hA3?8w3Ĝ"09,N"r.)'lx0(7ȱm!%Z)PUg1O!2,7b =7{/RCa?xblOR&9wH O7)j_T=%rtaUTW1(Ɣr9)2 n|P&]Nm: A}!8c3s"娉Ml\OR]so0#7^qZۯ{h```````````/La2 K2~4\ $@7*㵢zZ+jIIq~B[S$)U$7p<4# T#{;,g}._Tj%GGw6 4oRvj,Ό) quK sp[o!R:EQ 1(=I[oD rtg|D4Iw jtC2Wi"o1TegQeLQmi˜k"ģ@-Ś"ı́>(k b^Y;dU) H۩)`F"0 "RLJ~C u\߷:aRvN2 zgC "C0ܲ6ɊFL)\}jԳdaJ#kkZx~Pv釆Xہ@ BvqaHR m=^X[׵0ajb= AAGT}?Dh3\4gxޭ@=45+гm+Pz7fVXJїY0EEƧ(AiSC|>Q i{F[̣/20xY/XJ[zRԩjq<@uBЪ|69pušߑ2$ϫ(6%#.tA*.8<)SvO+pBWه3g,GָBѯSt]`6A]`^=Pڳrˑ:2t400000000000gOȟoMP؝XwI: J~xV8ĕqD{ӍsI}tZ\=  E~Aw?Ґl4M W>Q||򄃁1Q;jG/7G] RyT=rMEbr!j/ -x)Uo+Dܩ\Vb _J:%&:rrqrϞ%HKYݠT])Pԩ5z? Sa0tvdI?C{_z]ήv]`Q CS. \Y2'Eݑ=kmWi'E :lKJb+է>=eǖkꓮ!SR] ,]m:,ǍcԕWcơX sOC%p~e#8ewBC0w^.t,V8H!E iu8R B~#$RkuD6Z@\->㛛yLzq~?fȶlKNV1@E4!yoaNz0H_gq @~L4et炵[Ӭ== %U\Đ$sZ.8keL*VŰl%YPPeM:f &ыFJ=ۢ|FpY{&KI)β沏k SD܆Ӷe4ё!,N-?ۆKVdDyRӆ}"bJW[09<25GΘNxj{E}թ=!;o1G3?{yfKaݘޡ w>gBrL'#ּfbc3ʘ(dB-<9Y2\Y"6AB4k|s@7dCּe<_%S1-1NAGbǒectEԀ(w#kLeA=៉nLHs}M > ჿ W/N9egկP\rok{JPOQZF-%.R?OMJV7q^9sFA/T@S͙Fh~!Kze$RgmIɪuX5Sp)iYRf/@F7 8ZS_ew9@w&z.Z'6jv_)ӑwEʶD  Y(L-J{s2Say[8Ug^ %j\[ _i]9Mbt\:%{ j~ġ0\w1)}0W(djQ8mXuA-(5f(۰Y YJTG3l4HJPc-b1r0e;EYFt/nr|~Auu?'\A0UR@W1N錞ιo#W p IStWBgjdPԾ(kx/D\ !u"ښWo ~`A?^.LR1$-e(b纤=eJBהgݺ4:7{FD;!FJ{G/*`-#c7nȞ R= @4Y!'\Q3N^g{B23`e 9JQ\L'^H5h8~8E_K 1{[  D QQ&^5%Qa}\sdo -x%z!+𡎔D66֐H50000000000000000000000000K)y&~[ :D+k~u%])KBV^=;Z{J,IĽV6 7CVeEO2V?|vi'P_skpVq z#.{'CϽ˝^ PO cVrh$CW6F}IaHr6[9SrƓy (L^$GO;Q4A*@9ԯ@{#xTAQ좃D$: k )3>1ؾg\r2~Q ).C4#R]L-KI#dE$ r,I/a|x(|>7E߳_oT|j*`LeA-aH}=t"ًU. ]Z{# ]Y"TBmF[ذJgSNt2_᫘osNƤSN, c6&Iq**qH2*єűe:F[©{ol ޯhJYf¥{8$M858V$WeYIXrbG~zdqmӎ촆tgJoh@_*AT$%&(@\qyku/)p}OGiQOD2~<}o\%=>ኜAEܓ<_QdeepTools-2.5.0/deeptools/test/test_data/make_test_data.sh0000640000201600010240000000015612757050136023054 0ustar ryanbioinfobamCoverage -b testA.bam -o testA_skipNAs.bw --skipNAs bamCoverage -b testB.bam -o testB_skipNAs.bw --skipNAs deepTools-2.5.0/deeptools/test/test_data/test.bed30000640000201600010240000000005012757050136021262 0ustar ryanbioinfochr1 1 10 chr2 1 10 chr2 5 15 chr2 20 30deepTools-2.5.0/deeptools/test/test_data/test.gtf0000640000201600010240000000120212757050136021225 0ustar ryanbioinfo3R deepTools gene 1 1000 . . 0 gene_id "example"; 3R deepTools transcript 1 1000 . + 0 gene_id example; transcript_id "first"; 3R deepTools exon 1 50 . + 0 gene_id example; transcript_id "first"; 3R deepTools exon 400 510 . + 0 gene_id example; transcript_id "first"; 3R deepTools exon 980 1000 . + 0 gene_id example; transcript_id "first"; 3R deepTools transcript 100 1100 . - 0 gene_id example; transcript_id "second"; 3R deepTools exon 100 150 . - 0 gene_id example; transcript_id "second"; 3R deepTools exon 500 610 . - 0 gene_id example; transcript_id "second"; 3R deepTools exon 1080 1100 . - 0 gene_id example; transcript_id "second"; deepTools-2.5.0/deeptools/test/test_data/test1.bam0000640000201600010240000006135612757050136021305 0ustar ryanbioinfoBC^@BAM)@HD VN:1.0 SO:unsorted @SQ SN:3R LN:1500 3RY@@BCrbTb+I3DD61XKN1:101:D0EKPACXX:2:2103:15826:1665440HH((!DH$H@""%%%%%'&'''()((()()))')))))&()))'))))% '''()'$''XACMDZ49C0T0NMCJ* I3DD61XKN1:101:D0EKPACXX:2:1107:3353:1551980HA(HB"!!DD" '$&(&$&#&'''&'%#$('$%&(('&%"$%!&&!"''%%%#### XACMDZ51NMCU*I3DD61XKN1:101:D0EKPACXX:2:2205:8714:1541310"(HHB!H(D """%%%%%'''''())%($'(''''((')())))))(((())((&'))%'$XACMDZ51NMC\+ I3DD61XKN1:101:D0EKPACXX:2:2306:16413:1749170"!!DD"(HBB ##$$!'!!%'&$"%&&%"'#$&&' $$'('#%''$"&& &$%¬MDZ51NMCv+I3DD61XKN1:101:D0EKPACXX:2:1305:17377:1588870"(HBB$(AA"%#%%%''&#''()))))&$&')$&())))((''()'(&'(((()'&'(XACMDZ51NMC+I3DD61XKN1:101:D0EKPACXX:2:1308:19209:1441010"!!"B$(H!"!BB('%"(%% %# # #XACMDZ0G0G4T5T9G4T23NMC* I3DD61XKN1:101:D0EKPACXX:2:1108:9446:1274950A""($""$!@%#%%%%"!%#'$%&$'))()&(()((#($&!(&(()))!'&((((&XACMDZ51NMC)(I3DD61XKN1:101:D0EKPACXX:2:2305:7088:933450HH!"!BB((BH!"@!# !##%###(($&&'("'$ '#% #%(#$$% %'(((($(#XACMDZ8A42NMC)I3DD61XKN1:101:D0EKPACXX:2:1304:4948:393720H!"!BB((BH!"A ###  ###( $$$#$$"#% $"####( !###(##!!XACMDZ48G1T0NMC*I3DD61XKN1:101:D0EKPACXX:2:2304:6235:1125950H!"!BB((BH!"AD##%$ %'%%'(&(($'&&&''''&'))()((&()))"&&(&&())&!XACMDZ51NMC*'I3DD61XKN1:101:D0EKPACXX:2:2307:18363:549400!"!BB((BH!"ADA@%!#%%%" %$%%$&#"## ###XACMDZ51NMC)I3DD61XKN1:101:D0EKPACXX:2:1306:17117:24110""($""$!AH$#& %!!%$'!(&!#(&&" $%#$"(((&$%'%#%###XACMDZ51NMC+&I3DD61XKN1:101:D0EKPACXX:2:1305:12595:1937630"!B"((BH!"ADAA!A %% #%%%%'$%'$(((((((&'((&(!!#&&(%!'&%&((&(((XACMDZ12G38NMC(I3DD61XKN1:101:D0EKPACXX:2:1106:7245:98840"($""$!AH$ """%%%%%''&&')(('(&'(&&&&'('&$&&'((($%&&&"''()&(&$XACMDZ51NMC* I3DD61XKN1:101:D0EKPACXX:2:1102:16207:318860"($""$!AH$(##$!#' %#%## $"&&'(((((#%%#$&$$$#'((($"" XACMDZ51NMC) I3DD61XKN1:101:D0EKPACXX:2:2206:21197:45080"($""$!AH$(###!##'' %%'!% !%(($'$!%%#'!!%'& &!%''(# XACMDZ51NMC*I3DD61XKN1:101:D0EKPACXX:2:1206:11566:957210"!BB((BH!"ADAA!A" '$"%$!"&$%&(&& %((('&'"#'&($'%##'%%$#%%XACMDZ51NMC)%I3DD61XKN1:101:D0EKPACXX:2:2305:9277:800190($""$!AH$(#####'''%&&&&((((((&#%#&(&((!#''(!"%&&('(%&$XACMDZ51NMC)I3DD61XKN1:101:D0EKPACXX:2:2304:5021:302750$""$!AH$(@&& %%!%#&'#(&'&"$&&%&''$('%%'$'&'!%%#%%%$##%XACMDZ51NMC)I3DD61XKN1:101:D0EKPACXX:2:2102:10856:89920!BB((BH!"ADAA!A"("""%%%%%''&&'&(&($''('(&$&""%(%&!##%'(&(()%!"''(XACMDZ51NMC* I3DD61XKN1:101:D0EKPACXX:2:2106:11863:239180!BB((BH!"ADAA!A"("""%%%%%'''''((&()))))))()))))'()))()())))())()))(#XACMDZ51NMC*'I3DD61XKN1:101:D0EKPACXX:2:1208:19104:153340$""$!AH$(H ""%%#$%''''%'&'(&"'(''$&'&$'%'&(&&$'%'((&&('(&()&XACMDZ51NMC)I3DD61XKN1:101:D0EKPACXX:2:1103:5323:975250((BH!"ADDA!A"(" #!# %% #$%"% $"&%"!! !%%!%%"XACMDZ27A23NMC)I3DD61XKN1:101:D0EKPACXX:2:1202:2896:730430(BH!"ADAA!A"("""""%%%%%'''''))(&'))))())&)&()))()(()()(()))#'())))XACMDZ51NMC+I3DD61XKN1:101:D0EKPACXX:2:1208:12933:1839800$!AH$(H(B($###% !!%%#$!'%$$"%'('("%''(% #'()()(&XACMDZ51NMC+I3DD61XKN1:101:D0EKPACXX:2:2104:16766:1216970BH!"ADAAAA"(""A@((''#(&$##'%!#' %"$!$'%'"%")))(&&#'%#%%%#%!XACMDZ24C26NMC*I3DD61XKN1:101:D0EKPACXX:2:2202:9758:1234050!AH$(H(B($A@'"%#%'&%!#%!"#&#$($&& $#!"$'&&&'%'%%###%%XACMDZ51NMC*I3DD61XKN1:101:D0EKPACXX:2:2103:5708:1729950(H(B($ADB$D!""%%%%%&'&''(())&() &'()%&'(()()())((' &"''&'&&XACMDZ51NMC+I3DD61XKN1:101:D0EKPACXX:2:2107:14776:1525710H(B($ADB$D!D#%##%''&&#($'(&($$&())))&&#%&'% &((&(&('(&&XACMDZ51NMC*I3DD61XKN1:101:D0EKPACXX:2:1203:6539:1691350""AH$$D!AABAAHBHA@&&&&!((()((&()))&))(()))))(&(((())()''''&%%%%%""XACMDZ51NMC(I3DD61XKN1:101:D0EKPACXX:2:1101:6601:88620(B($ADB$D!D!""%%%%%'''''))()))())))))))'(''))))&(())#&'"&'$''XACMDZ51NMC+I3DD61XKN1:101:D0EKPACXX:2:1305:13851:1890100$ADB$D!D$!@%!! #%'# #(($!%" %''" # %'&&$  !$XACMDZ51NMC*'I3DD61XKN1:101:D0EKPACXX:2:2204:17651:413800(H$$D!AABAAHBHAHABB $&$(((%((((&'%#(((((((('$(((&&'!(((('#'''%%%%%"""XACMDZ0G0A49NMC*I3DD61XKN1:101:D0EKPACXX:2:2206:10244:138160(H$$D!AABAAHBHAHABB())(()(&)))))))))))())()))))(&()(())))'''''%%%%%"""XACMDZ0G0A49NMC * I3DD61XKN1:101:D0EKPACXX:2:2106:8135:1028520HAHABB$A$H$$!#####"$## %%''$$! #&)(((((&&'%(()))'''''%%%%%!"XACMDZ51NMC*I3DD61XKN1:101:D0EKPACXX:2:2201:9988:1400060$!AABH($A(($BAB!#%%% ''''&&!'((%&"% %'&&(&&&#!XACMDZ51NMC*$I3DD61XKN1:101:D0EKPACXX:2:2207:4417:1358580AABH($A(($BAB!A$ # #%### "$"&$#!!!!$"""!#!""XACMDZ51NMC +$I3DD61XKN1:101:D0EKPACXX:2:1107:10958:1143490$($A(($BAB!A$B!!!%""%$ "%!"##XACMDZ0G0C0G48NMC$)I3DD61XKN1:101:D0EKPACXX:2:2203:1197:624310($A(($BAB!A$B!!#!%%%$%%%%&#&&&!$"###XACMDZ51NMC/+ I3DD61XKN1:101:D0EKPACXX:2:2205:17888:1647870H$$!!HH$(!A!(H$B """%%%%%''''&))))))))))()&(&&')()))()))#"''$''%!##XACMDZ51NMCT* I3DD61XKN1:101:D0EKPACXX:2:1305:6255:1318130D"!AA$H$$A!$!$%&&!%#'"%#%#%# #!#XACMDZ51NMCU*I3DD61XKN1:101:D0EKPACXX:2:1105:8844:1067500A!(H$B!A!"H$BH@"# "!$'!((&&"&%((&'''%&'#'&#&&%$' %##%$##%XACMDZ51NMCU)I3DD61XKN1:101:D0EKPACXX:2:1304:6790:626020"ADB!A!"H$BH@%%%%%#!####XACMDZ0G0A1A0C0T0G0T0C42NMCy*&I3DD61XKN1:101:D0EKPACXX:2:1102:17282:950550$BHBH$D$"DA"!@ ##' #%%%!''$#%$"%!%!!XACMDZ51NMC)I3DD61XKN1:101:D0EKPACXX:2:2101:3335:343980HBH$D$"DA"!HD"%! ##%%''&&#''$'%&(((((&&((&('((((((''%%##$$$""XACMDZ51NMC*I3DD61XKN1:101:D0EKPACXX:2:2302:4837:1497310BH$D$"DA"!HD$%'&&()))))()(&)()))))))())))))))'&)))('&'''%%%%%"""XACMDZ51NMC+I3DD61XKN1:101:D0EKPACXX:2:1206:10242:1012840($BDBB!AA$"AH!H###!# %!% &% !%!  XACMDZ23T27NMC)I3DD61XKN1:101:D0EKPACXX:2:1107:9066:176870AH$D$"DA"!HD$A%%'&'()()(())())((&'&)(&()((())))))((&'%''%%%%%%""XACMDZ0A2T47NMC+I3DD61XKN1:101:D0EKPACXX:2:1302:10299:1981120H$D$"DA"!HD$A!D@#####%%' %!%%!%&''(($&$'%&"$ " #$$"""""!!!XACMDZ51NMC*I3DD61XKN1:101:D0EKPACXX:2:2108:17719:866810H$D$"DA"!HD$A!D@!!$%  #&!%#$$"'$%%% %"$%%#!%!### XACMDZ51NMC+I3DD61XKN1:101:D0EKPACXX:2:2204:15207:1839530H$D$"DA"!HD$A!D@ &('#&((('$&%%#!%"&&&&&%%%&%! #%'''#####XACMDZ51NMC)'I3DD61XKN1:101:D0EKPACXX:2:2305:1362:676320DA"!HD$A!DDH!@'&%! $#!"%$"&$ '%&%%#" #XACMDZ51NMC+I3DD61XKN1:101:D0EKPACXX:2:2208:15034:1517320A$"AH!H"DA$B"!@""%%%%%&&#%%"$'((&()&%()&(&$'!%&'())))#%'()('(( $XACMDZ51NMC)I3DD61XKN1:101:D0EKPACXX:2:2301:3775:258780AH!H"DA$B"!H!@%#!%#"% %%"$%%%%$" "##%%! !XACMDZ17G33NMC*I3DD61XKN1:101:D0EKPACXX:2:2304:19339:362560AH!H"DA$B"!H!B! #!"""!  " $%$!#"#!!!#!%%$XACMDZ51NMC*I3DD61XKN1:101:D0EKPACXX:2:1108:9454:1769880$A!DDH!B"($D@ #! $'$&&( "% #"#$!# %XACMDZ51NMC)I3DD61XKN1:101:D0EKPACXX:2:1201:5184:725350$A!DDH!B"($D$###% #'%'%!&&($#'$#! "&'&!&"&$&&(((XACMDZ48A1G0NMC*'I3DD61XKN1:101:D0EKPACXX:2:1101:21208:509440!DDH!B"($DDH(###'% ""$&$"$%&(&"'&$%''((&&& ''""$$XACMDZ51NMC+I3DD61XKN1:101:D0EKPACXX:2:1202:17726:1075720!DDH!B"($DDH(%%%%%''%"$$'((%&"%"'&'((($$&'#%&$" "''"XACMDZ51NMC*I3DD61XKN1:101:D0EKPACXX:2:2206:21259:601130$"!H!BDADDABA$% #!&%'&%%"" %"&(('#"%%## ###XACMDZ6G44NMC*I3DD61XKN1:101:D0EKPACXX:2:2202:20063:535810!B"($DDH(A!BBH@"%%%#%''''#((&&&&'((%'()!%#'&&((&%"& %'#$!XACMDZ51NMC*'I3DD61XKN1:101:D0EKPACXX:2:2105:20550:778070!H!BDADDAABA$$$D$@###! "$$%$$(!"!"XACMDZ22T21T6NMC* I3DD61XKN1:101:D0EKPACXX:2:1307:13537:698800($DDH(A!BBHBH%$"''$'(()('&(('&)'#&'$&('&$&&$&&!$('''#%#####XACMDZ51NMC* I3DD61XKN1:101:D0EKPACXX:2:2204:10042:313620H(ABBHBH!AA&$"('&"!'"!#"" %!'&"$'&(('" %###%%###XACMDZ16C34NMC*&I3DD61XKN1:101:D0EKPACXX:2:1206:8347:1377860BBDBH!AA$$!A(!  #!$#"## #$$$#"#$!" !### XACMDZ5T45NMC + I3DD61XKN1:101:D0EKPACXX:2:1103:10361:1803210A"A$$!A(!$B! "#! ### #XACMDZ0A0G1A1G1A0A0G0G0A0G38NMC *(I3DD61XKN1:101:D0EKPACXX:2:2103:18603:417730BDBA"A$"H!@%'$&())(())&&!!&())))(('((&'&&'%(&))(('&'''%%#%%""XACMDZ51NMC*I3DD61XKN1:101:D0EKPACXX:2:1301:2009:1573710BA"A$"H!DBB@!'))(('()))((')(&&&((()(()(&(()))))))(&'&''%%%%%"""XACMDZ51NMC*I3DD61XKN1:101:D0EKPACXX:2:2205:6958:1401550$!A(!$B!"D((###%%%'#!%$&%#%&$##'&&''(&(& '&$%&&"'!#XACMDZ51NMC)I3DD61XKN1:101:D0EKPACXX:2:2304:7387:671150!A(!$B!"D(( $%%!!&#&$'%%%&$% # !XACMDZ51NMC=*I3DD61XKN1:101:D0EKPACXX:2:1103:12878:370360D(($("D$%%'''$'('#)))()))))))))('")))('&))))))'''''%%%%%"""XACMDZ0C1A48NMC>+I3DD61XKN1:101:D0EKPACXX:2:1307:11922:1107900!DBBHHHBHHH!$HHBAHHA@##%$%$"##!%%((%&#%(%%%$ %% "! ###XACMDZ51NMC?)I3DD61XKN1:101:D0EKPACXX:2:2108:11686:29930D(($("D(@"" "'%%#$($ $&"&()(''%&'&&'!#! '###XACMDZ41G9NMCC*I3DD61XKN1:101:D0EKPACXX:2:1106:13858:490490(($("D$DD!@# !# ###!$$ $ ''''&"#&%'(! "$ $XACMDZ38A12NMCG)I3DD61XKN1:101:D0EKPACXX:2:1201:6831:941130($("D$D!DA@""%# #!%#'''&%'(()())(((&&&&$%&'&&&%%#" %$''$XACMDZ49C0T0NMCK* I3DD61XKN1:101:D0EKPACXX:2:1307:8654:1120750$("D$D!DB  #%"%%( !# $"#%#%%%(($$! XACMDZ15C30T0T0T0G1NMCK+$I3DD61XKN1:101:D0EKPACXX:2:2202:16204:1027460$("D$D!DB$ ###%#%%'$#&'(&&'$&"#!#%&$!&(&&&XACMDZ46T0T0T0G1NMCN*I3DD61XKN1:101:D0EKPACXX:2:1305:3741:1364560HBHHH!$HHBAHHADBD(B!@!%(())((&)))(((())))))))(()'))((&!)))('''''%%%%%"""XACMDZ51NMCY)"I3DD61XKN1:101:D0EKPACXX:2:1103:10524:66170("D$D!DB"HAB #""$(&&'%%# "%"$$' '!"' &%$'%$&'% !! !XACMDZ51NMC]) I3DD61XKN1:101:D0EKPACXX:2:1203:5457:897910("D$D!DB"HAB(#####%% " $ #$'%%&$##&&&($&"!%' &&'&$$ XACMDZ51NMC](I3DD61XKN1:101:D0EKPACXX:2:2105:3502:93630("D$D!DB"HAB("%%%##%'''&"%$&!''(&&')))))))()&%'!&&')()'()()'#XACMDZ51NMC]+I3DD61XKN1:101:D0EKPACXX:2:2306:10026:1684460("D$D!DB"HAB(#######%%"!"$'("&&'("'&((&($#% !%'$('$"%$XACMDZ51NMC^*I3DD61XKN1:101:D0EKPACXX:2:2202:1956:1799890($HHBAHHADBD(B!D" ()((()((((((()))(&))'"(()('(('&((&&('&'''''%%%%%""XACMDZ0T0C49NMC`)!I3DD61XKN1:101:D0EKPACXX:2:2308:7770:637070$HHBAHHADBD(B!D"H(  ## $$%$#(######## !#XACMDZ44T2A2G0NMC~+I3DD61XKN1:101:D0EKPACXX:2:2107:16245:1027120!D"(H"($D(H(B))))()))))(&&()(('('$())))))))))))))()'''''%%%%%"""XACMDZ51NMC+I3DD61XKN1:101:D0EKPACXX:2:2205:17360:1021240"HDB$$!$!% %%%""&%$ %%##! XACMDZ0T0A0A48NMC*I3DD61XKN1:101:D0EKPACXX:2:2207:3068:1368080"HDB$$!$! !""%%%$%'''%'()())(()()()())()())()()(((()()((()))&XACMDZ51NMC*I3DD61XKN1:101:D0EKPACXX:2:2307:12984:938290(H"($D(H(BA!H###%!!%$'(#%&%%"$'&&& %%$&&&!!'%'('"&'%XACMDZ51NMC*I3DD61XKN1:101:D0EKPACXX:2:1104:14191:127520"($D(H(BA!HA&($(&$$% '&&!'$#% $$ '%%"%!#%# ""## #XACMDZ51NMC*I3DD61XKN1:101:D0EKPACXX:2:1202:5681:1054530H(BA!HAA!H!@()()))))()))'(()&((()())&#&&''&))((((& &'''%%%%%"""XACMDZ51NMC*#I3DD61XKN1:101:D0EKPACXX:2:1105:3468:1251380A!HAA!H!BA(HH@#"'# &$'&'&&"""#&'!$$!'%%!&&$'%"!%!#' ####XACMDZ51NMC*%I3DD61XKN1:101:D0EKPACXX:2:2106:14544:829220A!HAA!H!BA(HH@'#%#!'$&('&%"$&""$%$$&%"!&'%" %!####XACMDZ51NMC*I3DD61XKN1:101:D0EKPACXX:2:1302:1975:1882490!HAA!H!BA(HHHBHB##%%#''%#'(($$'($"&()))($'"'&(()))"&%'#%#&&&&"&XACMDZ51NMC*I3DD61XKN1:101:D0EKPACXX:2:2102:7580:1939030(B$$(H!"""%#%%%%''&'((()(()(()( %'()$'&'&&((&(()%())(((()"XACMDZ51NMC)"I3DD61XKN1:101:D0EKPACXX:2:1204:10450:40670AA!H!BA(HHHBHB"! ! !"%%($" "%%XACMDZ43C3A3NMC+#I3DD61XKN1:101:D0EKPACXX:2:1303:17605:1172430AA!H!BA(HHHBHB! !!#!#%%(#%%& $  ! !XACMDZ43C2C4NMC*I3DD61XKN1:101:D0EKPACXX:2:1204:20137:364300A!H!BA(HHHBHB!!("""%%%%%'''''))()&($'())&&&&$'&)()()((&()&&())(((&XACMDZ51NMC+I3DD61XKN1:101:D0EKPACXX:2:2201:19368:1847900!BA(HHHBHB!!(HAHH@"""%%%%%'''' &'((&&((&()))))))))"'(()&(('('(%'"'%"XACMDZ51NMC* I3DD61XKN1:101:D0EKPACXX:2:2101:18098:667100!BA(HHHBHB!!(HAHHH@"""%%%%%''%%%&''((('&&()('()))))))))()())()'(&()))"XACMDZ51NMC) I3DD61XKN1:101:D0EKPACXX:2:2102:1649:915490!BA(HHHBHB!!(HAHHH@"""%%%%%''''%(((((((&&"$('((&)))))()())(())'('(&((&XACMDZ51NMC)I3DD61XKN1:101:D0EKPACXX:2:2202:5210:596650!BA(HHHBHB!!(HAHHH@"""%%%%%'''%'%'#'(()&&(((()(&'(&#%&'&())&&%&%'#&'&XACMDZ51NMC* I3DD61XKN1:101:D0EKPACXX:2:1101:8270:1156080BA(HHHBHB!!(HAHHHH@!%'&%'&%%#&&'$ &&'&$'$'$#'"!$'%!%%%%#!%XACMDZ51NMC+I3DD61XKN1:101:D0EKPACXX:2:2305:13537:1583590A(HHHBHB!(HAHHHHB@"%%"$#(%%$% !% &"!$! %!!%$(((%%%% #####XACMDZ28C22NMC+I3DD61XKN1:101:D0EKPACXX:2:2108:11187:1791590$(H!""$$#!##  $   $  ! "XACMDZ28A2A18C0NMC*(I3DD61XKN1:101:D0EKPACXX:2:2303:12707:287560"$$($"!$ ""%%#$#%''&&)&$$%''$&'()()())(()))&()()))))))))%!XACMDZ51NMC*I3DD61XKN1:101:D0EKPACXX:2:1307:10897:199090$$($"!$$! "!!%$$$$&$$'% &$%##"#&$#$%" !(%'% #%#%##XACMDZ17G33NMC* I3DD61XKN1:101:D0EKPACXX:2:2302:8329:1995770AHHHHBBHH(HA"BAH@$%%''')((&%()(())())(()('%''')(('&")((%%''&%#%%%!XACMDZ51NMC*I3DD61XKN1:101:D0EKPACXX:2:2205:6343:1709540HHHHBBHH(HA"BAHA@#$''$'&(&(((#(%(((&'(('#!%(((('&(&&$%!%!'!%#%%%""XACMDZ51NMC+I3DD61XKN1:101:D0EKPACXX:2:1101:12875:1762550HBBHH(HA"BAHAB!H@ ## #"!!#'&&!& #%'&&')$&"&&"XACMDZ51NMC+ I3DD61XKN1:101:D0EKPACXX:2:1203:17753:1885180HBBHH(HA"BAHAB!H@####%#'%%#'&&%#"%'$&&&&&&&&("'$""'((&XACMDZ51NMC7*I3DD61XKN1:101:D0EKPACXX:2:2206:13591:476200B$$BAA$("$H"""%%%%%'%'''))(&(((#%!&'()())()(('''%''%%%####""!XACMDZ51NMCH*I3DD61XKN1:101:D0EKPACXX:2:1308:18519:398350$"B(A(($D"A$ ""%%%#%%'%%'!'()()"'()))("'&"%'$"&&($(&(%(%(((#'%"XACMDZ51NMCI+I3DD61XKN1:101:D0EKPACXX:2:1207:12521:1012380AA$("$HH$B$A !####%"$%"$!%%"% "!!%$((XACMDZ36G12C0A0NMCZ* I3DD61XKN1:101:D0EKPACXX:2:1205:14859:431330(A(($D"A$!$B"B#### %%%'&$%"%' ''#&##'(!&%!" XACMDZ51NMCZ)I3DD61XKN1:101:D0EKPACXX:2:1305:3450:882950(A(($D"A$!$B"B######%$$&&$$!" $ %%%$!% $'!"" !! XACMDZ51NMC`*'I3DD61XKN1:101:D0EKPACXX:2:2204:1504:1696280A(($D"A$!$B"B "#!#%%%#!%%$! ''$$!& "$"#!!!!!XACMDZ51NMCc)$I3DD61XKN1:101:D0EKPACXX:2:1107:3972:590700ABH$B$BD!"!D!!!!!B!  $"&(' $#""" #!XACMDZ0A1G0T47NMCc*&I3DD61XKN1:101:D0EKPACXX:2:1206:17656:863110ABH$B$BD!"!D!!!!!B! "#!%!'%$#! &'$(('$!%"#"%!# #XACMDZ0A1G0T47NMCc*I3DD61XKN1:101:D0EKPACXX:2:1207:13576:400020ABH$B$BD!"!D!!!!!B! " #%## #%%(% $""!!##%#####XACMDZ0A1G0T47NMCc* I3DD61XKN1:101:D0EKPACXX:2:2106:13119:177640HBH$B$BD!"!D!!!!!B! "" "$###%$%$'&()((&'''&&&'&'$ ()(&&'#%%#!%##$#%XACMDZ51NMCc*I3DD61XKN1:101:D0EKPACXX:2:2204:20637:136910ABH$B$BD!"!D!!!!!B!   $#$!$'&'###"%%&('#!%" #%###!#XACMDZ0A1G0T47NMCc) I3DD61XKN1:101:D0EKPACXX:2:2206:5679:379560ABH$B$BD!"!D!!!!!B!  !%%&%&"%(%$#""  #!!##XACMDZ0A1G0T47NMCc)I3DD61XKN1:101:D0EKPACXX:2:2301:2777:155170A"BD$B$BD!"!D!!!!!B!  #%&$%#&'!&%"#!"%!##XACMDZ0A1G0T0T8T37NMCc+ I3DD61XKN1:101:D0EKPACXX:2:2301:14795:1146890ABH$B$BD!"!D!!!!!B! % &$& ##$&& $((&&&$! "%#####XACMDZ0A1G0T47NMCc*(I3DD61XKN1:101:D0EKPACXX:2:2303:4165:1415110ABH$B$BD!"!D!!!!!B! !%%%$&&"!&$!""" !# #XACMDZ0A1G0T47NMCh* I3DD61XKN1:101:D0EKPACXX:2:1106:3911:1777170(($D"A$!$B"B" !##%%&& %'((&!&'&"' " '$$# "!XACMDZ45C1T0T1G0NMCj* I3DD61XKN1:101:D0EKPACXX:2:1105:5355:1742190($D"A$!$B"B"B###"#$ #%% $$%!""$$#! ! XACMDZ51NMCk*I3DD61XKN1:101:D0EKPACXX:2:2105:7761:1302180BH$B$BD!"!D!!!!!B!!!@"%%#%###%'%%&()))(' %'(&'(&''%'!%$# !#"####$"XACMDZ51NMCk*I3DD61XKN1:101:D0EKPACXX:2:2106:20083:916230BH$B$BD!"!D!!!!!B!!!@##%#'''((&&'((%'(( '%&$#%#!##!"   XACMDZ1A49NMCk+'I3DD61XKN1:101:D0EKPACXX:2:2106:11915:1864620BH$B$BD!"!D!!!!!B!!$@!!!"#%%(((%$!$(%# !!"((%%'%%$"#$!!%$%%" XACMDZ47G1A1NMCm) I3DD61XKN1:101:D0EKPACXX:2:2305:7910:291580BH$B$BD!"!D!!!!!B!!!A"%#!&((&(&&'&'#&%#!&$'"&'%&%$"&$((&'%%%''%%%%%"""XACMDZ51NMCo)I3DD61XKN1:101:D0EKPACXX:2:2106:9016:647540H$B$BD!"!D!!!!!B!!!A%%%#'#' %&()&&((&(&(((('&'())&&%'%%%%%%$#$$$ #"XACMDZ51NMCs)I3DD61XKN1:101:D0EKPACXX:2:1304:4663:457840B$BD!"!D!!!!!B!!!A"!  &'#&$$$#&!'$&&%((&$$"'%"('' ''#%%##XACMDZ51NMCt* I3DD61XKN1:101:D0EKPACXX:2:2307:5310:1881360"A$!$B"B"B! !&('&&%#"!!$""&"$% $%$#%# ## #XACMDZ37T13NMCz)#I3DD61XKN1:101:D0EKPACXX:2:1204:6882:984180!$B"B"B!(@%!##'%#'!&(%% '''&((($###"%%! ##"""XACMDZ49T0A0NMCz*I3DD61XKN1:101:D0EKPACXX:2:2306:8141:1356500!$B"B"B!(%% %%)(&'&#%$!&&" #&&'$'$)(()((#%$&('%"# # ##XACMDZ51NMC*I3DD61XKN1:101:D0EKPACXX:2:2102:13845:293020!D!!!!!B!!!A"!$A #####!#$" !$$!$ $# #$$"!### XACMDZ35C15NMC+&I3DD61XKN1:101:D0EKPACXX:2:2104:13028:1564540D!!!!!B!!!A"!$A@ #'& #!!&(%)&(%(&)))()((&'%&%'%##"' %&&'#%#%#"XACMDZ51NMC+ I3DD61XKN1:101:D0EKPACXX:2:2102:11807:1414130B!!!A"!$AHD"!! ")))'())))((&('&%&&&#"!&'&#%&&&('!!'&%##''&$ %##XACMDZ51NMC+ I3DD61XKN1:101:D0EKPACXX:2:2207:11383:1402040"BD!(A$$B!B%%%%%''#&&$'((&'$'&!$$&'&(%%& ''(&%'&(&('XACMDZ10A40NMC)I3DD61XKN1:101:D0EKPACXX:2:1103:2005:942730B!(A$$B!BB@&))()((&(('$%((((&'(('(()(((((()'&'))(''%#%##%%%XACMDZ51NMC*I3DD61XKN1:101:D0EKPACXX:2:1104:3068:1109260!A"!$AHD"!!!$ ##%!"&%''"%'"#&!"&'XACMDZ51NMC*"I3DD61XKN1:101:D0EKPACXX:2:1208:1245:1101870"!$AAHD"!!!$$A #!#%%!$ %% #%%%&# # % XACMDZ14A36NMC+%I3DD61XKN1:101:D0EKPACXX:2:2302:15040:1146520$A"A"(((H"$$###$$$''$' "#((&'%($#%!#$&&'&&'''''$##%%"""XACMDZ51NMC6[TbBCdeepTools-2.5.0/deeptools/test/test_data/test1.bam.bai0000640000201600010240000000014012757050136022017 0ustar ryanbioinfoBAII_bJ_b_deepTools-2.5.0/deeptools/test/test_data/test1.bg0000640000201600010240000000122312757050136021121 0ustar ryanbioinfo3R 0 25 0.76 3R 25 50 1.00 3R 50 75 0.32 3R 75 100 1.92 3R 100 125 3.28 3R 125 150 2.92 3R 150 175 7.88 3R 175 200 18.96 3R 200 225 15.84 3R 225 250 8.40 3R 250 275 6.84 3R 275 300 4.80 3R 300 325 5.68 3R 325 350 3.96 3R 350 375 3.16 3R 375 400 4.56 3R 400 425 8.64 3R 425 450 10.92 3R 450 475 9.48 3R 475 500 7.48 3R 500 525 4.12 3R 525 550 4.68 3R 550 575 5.32 3R 575 600 7.96 3R 600 625 12.76 3R 625 650 8.76 3R 650 675 5.48 3R 675 700 6.56 3R 700 725 8.12 3R 725 750 12.84 3R 750 775 10.56 3R 775 800 6.44 3R 800 825 4.08 3R 825 850 1.76 3R 850 875 7.80 3R 875 900 22.24 3R 900 925 21.96 3R 925 950 9.32 3R 950 975 4.20 3R 975 1000 1.20 3R 1000 1025 0.80 deepTools-2.5.0/deeptools/test/test_data/test1.bw.bw0000640000201600010240000006225512757050136021564 0ustar ryanbioinfo&X0 3 4 GLmL~?E@`@('*Ax3Rx=1(Eq- 2H& /7LdAJ&+&Eo$dx/30( 2Hy/t3m)eTJq]˩p򒰜zmMXɲ゠PH<;ǩV=ZYȱz ?;? ك9I˯VWB~ wCvk+V?c;{"rc.gxĜN3;<.Gq<ZS_ onEb=;B3g[3/¨[9ERkʼn?sh$~~4xc`P0kOG S0 ẓf:1Ĝv(`ȧsLK{fIh$ 43:xc` , u@|3N Ll=\rh$mLKL"&deepTools-2.5.0/deeptools/test/test_data/test1.sam0000640000201600010240000006605512757050136021327 0ustar ryanbioinfo@HD VN:1.0 SO:unsorted @SQ SN:3R LN:1500 DD61XKN1:101:D0EKPACXX:2:2103:15826:166544 0 3R 7 5 51M * 0 0 TCTCTTGTTGTAGTCTCTTGACAAAATGCAATGGTCAGGTAGCGTTGTTAG @CCFFFFFHGHHHIJIIIJIJJJHJJJJJGIJJJHJJJJF*?HHHIJHEHH XA:i:0 MD:Z:49C0T0 NM:i:2 DD61XKN1:101:D0EKPACXX:2:1107:3353:155198 16 3R 75 9 51M * 0 0 GTGAATAGTCCTGTAAGCCCTATAAACATATGTACATAGGTAGGCCAGTAC HEGIGEGD@GHHHGHFDEIHEFGIIHGF?CEF?BGGBCHHFFFDDDDA@@@ XA:i:0 MD:Z:51 NM:i:0 DD61XKN1:101:D0EKPACXX:2:2205:8714:154131 0 3R 86 5 51M * 0 0 TGTAAGCCCTATAAACATATGTACATAGGTAGGCCAGTACTTAGTACTGGC CCCFFFFFHHHHHIJJFIEHIHHHHIIHJIJJJJJJIIIIJJIIGHJJFHE XA:i:0 MD:Z:51 NM:i:0 DD61XKN1:101:D0EKPACXX:2:2306:16413:174917 0 3R 93 32 51M * 0 0 CCTATAAACATATGTACATAGGTAGGCCAGTACTTAGTACTGGCACATGCC @@@DDEEBHBBFHGECFGG>FCHDEGGHA?FGD XA:i:0 MD:Z:51 NM:i:0 DD61XKN1:101:D0EKPACXX:2:1305:17377:158887 0 3R 119 19 51M * 0 0 CCAGTACTTAGTACTGGCACATGCCGCTGATCTGTTAGTAGATTATCCATT @@@FDFFFHHGDHHIJJJJJGEGHJEGIJJJJIIHHIJHIGHIIIIJHGHI XA:i:0 MD:Z:51 NM:i:0 DD61XKN1:101:D0EKPACXX:2:1308:19209:144101 16 3R 134 26 51M * 0 0 CCCACAAGCCGCCGATCTGTTAATAGAATATCCATTTCCCTTCAGCGCCTA ###############################@HFC;=IFFA6FDADAD@@@ XA:i:1 MD:Z:0G0G4T5T9G4T23 NM:i:6 DD61XKN1:101:D0EKPACXX:2:1108:9446:127495 0 3R 149 10 51M * 0 0 TCTGTTAGTAGATTATCCATTTCCCTTCAGCGCCTACCTGCGTCACCAATG @@@FDFFFF:CBFDHEFGEHJJIJGIIJIIDIEGBIGIIJJJBHGIIII@G XA:i:0 MD:Z:51 NM:i:0 DD61XKN1:101:D0EKPACXX:2:2305:7088:93345 0 3R 152 40 51M * 0 0 GTTAGTAGTTTATCCATTTCCCTTCAGCGCCTACCTGCGTCACCAATGATG @@;BDABDDFDDDII9EGGHICHE+AAHDFADFIDEE@>@FAFHIIIIEID XA:i:1 MD:Z:8A42 NM:i:1 DD61XKN1:101:D0EKPACXX:2:1304:4948:39372 0 3R 156 25 51M * 0 0 GTAGATTATCCATTTCCCTTCAGCGCCTACCTGCGTCACCAATGATGAAGA ?8?ADDDA4ADDDIAEEED>EE:C@DFAB XA:i:0 MD:Z:51 NM:i:0 DD61XKN1:101:D0EKPACXX:2:2307:18363:54940 16 3R 160 39 51M * 0 0 ATTATCCATTTCCCTTCAGCGCCTACCTGCGTCACCAATGATGAGGTCGAG #####@@@==8'FB8DF8???F??1F@C1A+9FEFFEGD?CG@;AFB(BFEHBIGBDIGGC?A::EFDEC:IIIGEFHFD6FD?DD@<@ XA:i:0 MD:Z:51 NM:i:0 DD61XKN1:101:D0EKPACXX:2:1305:12595:193763 0 3R 168 38 51M * 0 0 TTTCCCTTCAGCCCCTACCTGCGTCACCAATGATGAGGTCGAGACAGAATC @@@FFADFFFFH:EFHEIIIIIIIG@HIIGIBBDGGIFB@@HGFGIIGIII XA:i:1 MD:Z:12G38 NM:i:1 DD61XKN1:101:D0EKPACXX:2:1106:7245:9884 0 3R 169 6 51M * 0 0 TTCCCTTCAGCGCCTACCTGCGTCACCAATGATGAGGTCGAGACAGAATCC CCCFFFFFHHGGHJIIHIGHIGGGGHIHGEGGHIIIEFGG@GCHHIJGIGE XA:i:0 MD:Z:51 NM:i:0 DD61XKN1:101:D0EKPACXX:2:1102:16207:31886 0 3R 171 12 51M * 0 0 CCCTTCAGCGCCTACCTGCGTCACCAATGATGAGGTCGAGACAGAATCCTA @@>B>:FABFIIEHEBFFDHBBFHGAG0B@FHHI@DA XA:i:0 MD:Z:51 NM:i:0 DD61XKN1:101:D0EKPACXX:2:1206:11566:95721 16 3R 172 19 51M * 0 0 CCTTCAGCGCCTACCTGCGTCACCAATGATGAGGTCGAGACAGAATCCTAC HECFEB@@CG?00EFGIGGAF@IIIH@GHCD@HG>IEHFDDHFFEDFF@@@ XA:i:0 MD:Z:51 NM:i:0 DD61XKN1:101:D0EKPACXX:2:2305:9277:80019 0 3R 173 37 51M * 0 0 CTTCAGCGCCTACCTGCGTCACCAATGATGAGGTCGAGACAGAATCCTACT @@@DDDDDHHH:FGGGGIIIIIIG;DFDGIGIIBDHHI8;BCFGGIHIFGE XA:i:0 MD:Z:51 NM:i:0 DD61XKN1:101:D0EKPACXX:2:2304:5021:30275 16 3R 175 23 51M * 0 0 TCAGCGCCTACCTGCGTCACCAATGATGAGGTCGAGACAGAATCCTACTAG GGAFFBFD@?GHDIGHGCHHEGHGEHFHGIGGEHFHIIGGIHIGIJG XA:i:0 MD:Z:51 NM:i:0 DD61XKN1:101:D0EKPACXX:2:1103:5323:97525 0 3R 182 1 51M * 0 0 CTACCTGCGTCACCAATGATGAGGTCGGGACAGAATCCTACTAGTACCTGC ;==DBD?AFFA:DEF:CF:AECG2 XA:i:1 MD:Z:27A23 NM:i:1 DD61XKN1:101:D0EKPACXX:2:1202:2896:73043 0 3R 184 17 51M * 0 0 ACCTGCGTCACCAATGATGAGGTCGAGACAGAATCCTACTAGTACCTGCCT CCCFFFFFHHHHHJJIGHJJJJIJJGJGIJJJIJIIJIJIIJJJDHIJJJJ XA:i:0 MD:Z:51 NM:i:0 DD61XKN1:101:D0EKPACXX:2:1208:12933:183980 0 3R 187 23 51M * 0 0 TGCGTCACCAATGATGAGGTCGAGACAGAATCCTACTAGTACCTGCCTCGA @@@?DD:DFABBF?DAFHGGE...().8@3;8BE XA:i:0 MD:Z:51 NM:i:0 DD61XKN1:101:D0EKPACXX:2:2204:17651:41380 16 3R 236 39 51M * 0 0 CTGTCGATCGGGCAGAGAGCGAGAAATGGTAAGCAGGTGAGTGAGCGCAGA A;EGEIIIFIIIIGHFDIIIIIIIIHEIIIGGHBIIIIHDHHHFFFFFCCC XA:i:0 MD:Z:0G0A49 NM:i:2 DD61XKN1:101:D0EKPACXX:2:2206:10244:13816 16 3R 236 24 51M * 0 0 CTGTCGATCGGGCAGAGAGCGAGAAATGGTAAGCAGGTGAGTGAGCGCAGA IJJIIJIGJJJJJJJJJJJIJJIJJJJJIGIJIIJJJJHHHHHFFFFFCCC XA:i:0 MD:Z:0G0A49 NM:i:2 DD61XKN1:101:D0EKPACXX:2:2106:8135:102852 16 3R 270 9 51M * 0 0 AGGTGAGTGAGCGCAGAGAGCGTCTTTCGACGACTCTTTCGTCGCGAGCAA DDDDDCEDDAFFHHE?6'EBADGJIIIIIGGHFIIJJJHHHHHFFFFFB;@6?@### XA:i:0 MD:Z:51 NM:i:0 DD61XKN1:101:D0EKPACXX:2:2207:4417:135858 0 3R 285 36 51M * 0 0 GAGAGCGTCTTTCGACGACTCTTTCGTCGCGAGCAAACAACAAGTAGACGT 8:=;AAD@ADFDDD:ACE@?0CGEDBBB6677@;BEC=CC?B?D;BCC>?# XA:i:0 MD:Z:51 NM:i:0 DD61XKN1:101:D0EKPACXX:2:1107:10958:114349 16 3R 289 36 51M * 0 0 CGATCTTTCGACGACTCTTTCGTCGCGAGCAAACAACAAGTAGACGTCGCT ###########################BBBFCCFEA?:C4FBC8?:DD??; XA:i:0 MD:Z:0G0C0G48 NM:i:3 DD61XKN1:101:D0EKPACXX:2:2203:1197:62431 16 3R 293 17 51M * 0 0 CTTTCGACGACTCTTTCGTCGCGAGCAAACAACAAGTAGACGTCGCTCAGA #BB;=?=8@?DBFFFE;@@GGBEC<08D@3D;D?=: XA:i:0 MD:Z:51 NM:i:0 DD61XKN1:101:D0EKPACXX:2:2205:17888:164787 0 3R 304 12 51M * 0 0 TCTTTCGTCGCGAGCAAACAACAAGTAGACGTCGCTCAGACACTGTCGGCC CCCFFFFFHHHHGJJJJJJJJJJIJGIGGHJIJJJIJJJ9DCHHEHHFBDD XA:i:0 MD:Z:51 NM:i:0 DD61XKN1:101:D0EKPACXX:2:1305:6255:131813 16 3R 341 9 51M * 0 0 AGACACTGTCGGCCAGATTCATTTTCCAGAAAGACGTCGTCGCGTTGACAA #######EB@=);@9EFGGB4@F??F@FBHHFB?F67';8'4));@9>9>BB?## XA:i:0 MD:Z:51 NM:i:0 DD61XKN1:101:D0EKPACXX:2:2101:3335:34398 0 3R 384 15 51M * 0 0 GTTGACAAGCTTAAATTCGTAGCGGGCGCCAGTAGGACGACCCAGTGGATA @@CFBADDFFHHGGDHHEHFGIIIIIGGIIGIHIIIIIIHHFFDDEEECC@ XA:i:0 MD:Z:51 NM:i:0 DD61XKN1:101:D0EKPACXX:2:2302:4837:149731 16 3R 390 22 51M * 0 0 AAGCTTAAATTCGTAGCGGGCGCCAGTAGGACGACCCAGTGGATATCGTCA FHGGIJJJJJIJIGJIJJJJJJJIJJJJJJJJHGJJJIHGHHHFFFFFCCC XA:i:0 MD:Z:51 NM:i:0 DD61XKN1:101:D0EKPACXX:2:1206:10242:101284 0 3R 393 19 51M * 0 0 CTTAAATTCGTAGCGGGCGCCAGAAGGACGACCCAGTGGATATCGTCAGTT ?@@DDDBD?;AFB7@FAGF>ABF(/?(=B<@'@/(6.;3;7;@;A;?;?;> XA:i:1 MD:Z:23T27 NM:i:1 DD61XKN1:101:D0EKPACXX:2:1107:9066:17687 16 3R 396 28 51M * 0 0 GAACTCGTAGCGGGCGCCAGTAGGACGACCCAGTGGATATCGTCAGTTGAA FFHGHIJIJIIJJIJJIIGHGJIGIJIIIJJJJJJIIGHFHHFFFFFFCC@ XA:i:0 MD:Z:0A2T47 NM:i:2 DD61XKN1:101:D0EKPACXX:2:1302:10299:198112 0 3R 402 23 51M * 0 0 GTAGCGGGCGCCAGTAGGACGACCCAGTGGATATCGTCAGTTGAACCAGGG @@CEACA?DEE@CCCCCBBB XA:i:0 MD:Z:51 NM:i:0 DD61XKN1:101:D0EKPACXX:2:2108:17719:86681 16 3R 402 29 51M * 0 0 GTAGCGGGCGCCAGTAGGACGACCCAGTGGATATCGTCAGTTGAACCAGGG BBA>C,A33?EBDCD;;0B<;??)B3?BDB?=FFE XA:i:0 MD:Z:51 NM:i:0 DD61XKN1:101:D0EKPACXX:2:1108:9454:176988 0 3R 436 3 51M * 0 0 CGTCAGTTGAACCAGGGGAAACGTAGCAGCCCAGTTACATTGCTCGGGAGG =18AD:B;<4?*99?C@EEHIIFGCFCHGHIIIEEGHD8@FGE';CAAACHHC XA:i:0 MD:Z:51 NM:i:0 DD61XKN1:101:D0EKPACXX:2:2206:21259:60113 16 3R 455 18 51M * 0 0 AACGTATCAGCCCAGTTACATTGCTCGGGAGGGGTAAAGAGCTTGACGACA #########F?9**DB0?GFHGF::FCC@:+F@CGIIHDCFFDDADDD@@@ XA:i:0 MD:Z:6G44 NM:i:1 DD61XKN1:101:D0EKPACXX:2:2202:20063:53581 0 3R 462 29 51M * 0 0 CAGCCCAGTTACATTGCTCGGGAGGGGTAAAGAGCTTGACGACAGCGCGTG C@@FFFDFHHHHDIIGGGGHII@FHIJ0BFDHGGIIGFCGA;FH@D=EB## XA:i:0 MD:Z:51 NM:i:0 DD61XKN1:101:D0EKPACXX:2:2105:20550:77807 0 3R 467 39 51M * 0 0 CAGTTACATTGCTCGGGAGGGGGAAAGAGCTTGACGACAGCGCGGGCGTAG ?1?D=DDB,2=C4?EE?8FEEI)?@8B800?@CBC8@############## XA:i:1 MD:Z:22T21T6 NM:i:2 DD61XKN1:101:D0EKPACXX:2:1307:13537:69880 16 3R 472 9 51M * 0 0 ACATTGCTCGGGAGGGGTAAAGAGCTTGACGACAGCGCGTGCGTAGAGTGA 3FECHHEHIIJIHGIIH@GJHDGHEGIHGEGGEGGBEIHHHDFDDDDD@@@ XA:i:0 MD:Z:51 NM:i:0 DD61XKN1:101:D0EKPACXX:2:2204:10042:31362 16 3R 488 10 51M * 0 0 GTAAAGAGCTTGACGATAGCGCGTGCGTAGAGTGAAAGTATGCAAGGAGAT GECIHGC;;;BHCB?0)D?8CC<+@FBHGCEHGIIHCA?FDDDFFDDD@@@ XA:i:0 MD:Z:16C34 NM:i:1 DD61XKN1:101:D0EKPACXX:2:1206:8347:137786 16 3R 506 38 51M * 0 0 GCGCGGGCGTAGAGTGAAAGTATGCAAGGAGATTCGCGATCAGAACCTCAC A@A;''6?DB4ED@CDDDDA48:1 XA:i:0 MD:Z:5T45 NM:i:1 DD61XKN1:101:D0EKPACXX:2:1103:10361:180321 16 3R 524 12 51M * 0 0 GATCTTCCGATCTATTCGCGATCAGAACCTCACGACGCCATATTTGTTTTC ####################CDB?*1;;83:)@)@6@DD??48?DA7D??? XA:i:0 MD:Z:0A0G1A1G1A0A0G0G0A0G38 NM:i:10 DD61XKN1:101:D0EKPACXX:2:2103:18603:41773 16 3R 527 40 51M * 0 0 ATGCAAGGAGATTCGCGATCAGAACCTCACGACGCCATATTTGTTTTCCAG FHEGIJJIIJJGGBBGIJJJJIIHIIGHGGHFIGJJIIHGHHHFFDFFCC@ XA:i:0 MD:Z:51 NM:i:0 DD61XKN1:101:D0EKPACXX:2:1301:2009:157371 16 3R 537 18 51M * 0 0 ATTCGCGATCAGAACCTCACGACGCCATATTTGTTTTCCAGGGCTTGCTTG BHJJIIHIJJJIIHJIGGGIIIJIIJIGIIJJJJJJJIGHGHHFFFFFCCC XA:i:0 MD:Z:51 NM:i:0 DD61XKN1:101:D0EKPACXX:2:2205:6958:140155 0 3R 542 23 51M * 0 0 CGATCAGAACCTCACGACGCCATATTTGTTTTCCAGGGCTTGCTTGTGTGT @@@DDDFFFHDBFEG@FD@FGED9DHGGHHIGIGAHGE@FGGCHB@=@@D= XA:i:0 MD:Z:51 NM:i:0 DD61XKN1:101:D0EKPACXX:2:2304:7387:67115 16 3R 544 26 51M * 0 0 ATCAGAACCTCACGACGCCATATTTGTTTTCCAGGGCTTGCTTGTGTGTGC A>@;=EFFB8@7:??@8BG?9?DGE:?HFF?F?@GE?@F??AD==A?B:?: XA:i:0 MD:Z:51 NM:i:0 DD61XKN1:101:D0EKPACXX:2:1103:12878:37036 16 3R 574 2 51M * 0 0 TCTGGGCTTGCTTGTGTGTGCGTGTGTTTCAACTCCGGTGTGCGAGTGTGA FFHHHEHIHDJJJIJJJJJJJJJIHCJJJIHGJJJJJJHHHHHFFFFFCCC XA:i:0 MD:Z:0C1A48 NM:i:2 DD61XKN1:101:D0EKPACXX:2:1307:11922:110790 16 3R 575 24 51M * 0 0 CAGGGCTTGCTTGTGTGTGCGTGTGTTTCAACTCCGGTGTGCGAGTGTGAG DDFEFECD9D;@@B8F?@:FIIFG?4D9FIFF@FEA<)FFACB?ADDD@@@ XA:i:0 MD:Z:51 NM:i:0 DD61XKN1:101:D0EKPACXX:2:2108:11686:2993 16 3R 576 1 51M * 0 0 AGGGCTTGCTTGTGTGTGCGTGTGTTTCAACTCCGGTGTGCTAGTGTGAGG CCA@7C=@H@FFDEIEAEG@3CGIJIH@HF6>GHGGHBDBA:HDD?=D@@@ XA:i:1 MD:Z:41G9 NM:i:1 DD61XKN1:101:D0EKPACXX:2:1106:13858:49049 0 3R 580 23 51M * 0 0 CTTGCTTGTGTGTGCGTGTGTTTCAACTCCGGTGTGCGGGTGTGAGGGCAG @;?DABD?+:;E=AE< XA:i:0 MD:Z:38A12 NM:i:1 DD61XKN1:101:D0EKPACXX:2:1201:6831:94113 0 3R 584 3 51M * 0 0 CTTGTGTGTGCGTGTGTTTCAACTCCGGTGTGCGAGTGTGAGGGCAGGGAG @CCFDADBFDHHHGFHIIJIJJIIIGGGGEFGHG@GG9?FFDCAA1FEHHE XA:i:0 MD:Z:49C0T0 NM:i:2 DD61XKN1:101:D0EKPACXX:2:1307:8654:112075 0 3R 588 12 51M * 0 0 TGTGTGCGTGTGTTTAAACTCCGGTGTGCGAGTGTGAGGGCAGGGCAGATC ?71?=?4ADF1CFFI,A@BDA@E?C@)?DF<:08DF>FFII?EEB1;A### XA:i:1 MD:Z:15C30T0T0T0G1 NM:i:5 DD61XKN1:101:D0EKPACXX:2:2202:16204:102746 0 3R 588 36 51M * 0 0 TGTGTGCGTGTGTTTCAACTCCGGTGTGCGAGTGTGAGGGCAGGGCCGATC ?@?DDDFDF?@FHEDGHIGGHEG>::C)?D?6)??BDFGEBGIGGG##### XA:i:0 MD:Z:46T0T0T0G1 NM:i:4 DD61XKN1:101:D0EKPACXX:2:1305:3741:136456 16 3R 591 3 51M * 0 0 GTGCGTGTGTTTCAACTCCGGTGTGCGAGTGTGAGGGCAGGGCTTTGCCAG BFIIJJIIGJJJIIIIJJJJJJJJIIJHJJIIGBJJJIHHHHHFFFFFCCC XA:i:0 MD:Z:51 NM:i:0 DD61XKN1:101:D0EKPACXX:2:1103:10524:6617 16 3R 602 34 51M * 0 0 TCAACTCCGGTGTGCGAGTGTGAGGGCAGGGCTTTGCCAGGTGATAATGCC DCCEIGGHFFDA@6CF@C3=EEHAHBCHAGF@EHFE@G8?HFABBAB1?@@ XA:i:0 MD:Z:51 NM:i:0 DD61XKN1:101:D0EKPACXX:2:1203:5457:89791 0 3R 606 9 51M * 0 0 CTCCGGTGTGCGAGTGTGAGGGCAGGGCTTTGCCAGGTGATAATGCCTTAA @@@DDD@DDFFA)<GHGEEA XA:i:0 MD:Z:51 NM:i:0 DD61XKN1:101:D0EKPACXX:2:2105:3502:9363 0 3R 606 31 51M * 0 0 CTCCGGTGTGCGAGTGTGAGGGCAGGGCTTTGCCAGGTGATAATGCCTTAA @@CFFFDDFHHH?GCFEGBHHIGGHJJJJJJJIJGFHBGGHJIJHIJIJHD XA:i:0 MD:Z:51 NM:i:0 DD61XKN1:101:D0EKPACXX:2:2306:10026:168446 0 3R 606 2 51M * 0 0 CTCCGGTGTGCGAGTGTGAGGGCAGGGCTTTGCCAGGTGATAATGCCTTAA @@@DDDDDD;DF?FCBEHIDDDAD@?; XA:i:0 MD:Z:51 NM:i:0 DD61XKN1:101:D0EKPACXX:2:1202:5681:105453 16 3R 677 18 51M * 0 0 TCGTCTTCGCAAATTCGAACAACAGTATTCTTGATTGATGCAGTTTTACAG IJIJJJJJIJJJHIIJGIIIJIJJGDGGHHGJJIIIIGAGHHHFFFFFCCC XA:i:0 MD:Z:51 NM:i:0 DD61XKN1:101:D0EKPACXX:2:1105:3468:125138 16 3R 689 35 51M * 0 0 ATTCGAACAACAGTATTCTTGATTGATGCAGTTTTACAGCGACTTTGTGTG DCHDAGEHGHGGCCCD>G@HBEEBHFF9BGGEHFC1B@:FBDHADDDD@@@ XA:i:0 MD:Z:51 NM:i:0 DD61XKN1:101:D0EKPACXX:2:2106:14544:82922 16 3R 689 37 51M * 0 0 ATTCGAACAACAGTATTCTTGATTGATGCAGTTTTACAGCGACTTTGTGTG HDFDB;HEGIHGF@CEGC>C@E>FEEGFC@BGHFC@:??AAAFBDDDD?8: XA:i:0 MD:Z:51 NM:i:0 DD61XKN1:101:D0EKPACXX:2:1302:1975:188249 0 3R 699 2 51M * 0 0 CAGTATTCTTGATTGATGCAGTTTTACAGCGACTTTGTGTGTGCGTATGCT @@@DDFFDHHFDHIIEEHIECGIJJJIEHCHGIIJJJCGFHDFDGGGGCG> XA:i:0 MD:Z:51 NM:i:0 DD61XKN1:101:D0EKPACXX:2:2102:7580:193903 0 3R 706 24 51M * 0 0 CTTGATTGATGCAGTTTTACAGCGACTTTGTGTGTGCGTATGCTGTCACCA @CCFDFFFFHHGHIIIJIIJIIJIAFHIJEHGHGGIIGIIJFIJJIIIIJC XA:i:0 MD:Z:51 NM:i:0 DD61XKN1:101:D0EKPACXX:2:1204:10450:4067 0 3R 709 34 51M * 0 0 GATTGATGCAGTTTTACAGCGACTTTGTGTGTGCGTATGCTGTAACCCCAC ::?B?:=AB=CFFIE?C:31::89?::??############ XA:i:0 MD:Z:43C3A3 NM:i:2 DD61XKN1:101:D0EKPACXX:2:1303:17605:117243 0 3R 709 35 51M * 0 0 GATTGATGCAGTTTTACAGCGACTTTGTGTGTGCGTATGCTGTAACAACAC +8?BB::DB?DFFI>DF@HGF;=HGFFDGGHEAGG=HGEHEHEDH>CB<>@@EHFBFFFFDBF@@@ XA:i:0 MD:Z:51 NM:i:0 DD61XKN1:101:D0EKPACXX:2:2305:13537:158359 16 3R 729 7 51M * 0 0 GACTTTGTGTGTGCGTATGCTGTCACCATACTATGTTCGAGTGTGTGTGCG 7CFFCEDIFF:EFAB9F?8@AGCBEB?2+FBBF@EIIIFFFFADDDDD@@@ XA:i:1 MD:Z:28C22 NM:i:1 DD61XKN1:101:D0EKPACXX:2:2108:11187:179159 0 3R 730 14 51M * 0 0 ACTTTGTGTGTGCGTATGCTGTCACCACCCTTTGTTCGAGTGTGTGTGCGA ???DBDD22=+2,?E72+A4:+GEEHFA<(GEFDDC;DGED@EFCABIFHFAD8F>DFDD@?< XA:i:0 MD:Z:17G33 NM:i:1 DD61XKN1:101:D0EKPACXX:2:2302:8329:199577 16 3R 767 12 51M * 0 0 GAGTGTGTGTGCGCTCGTGTTTCTGTGAACCCAATCGCGAACACTGTTGTG EFFHHHJIIGFIJIIJJIJJIIJIHFHHHJIIHGCJIIFFHHGFDFFF@@B XA:i:0 MD:Z:51 NM:i:0 DD61XKN1:101:D0EKPACXX:2:2205:6343:170954 16 3R 769 16 51M * 0 0 GTGTGTGTGCGCTCGTGTTTCTGTGAACCCAATCGCGAACACTGTTGTGAG DEHHEHGIGIIIDIFIIIGHIIHDBF@IIIIHGIGGEFBFBHBFDFFFCC@ XA:i:0 MD:Z:51 NM:i:0 DD61XKN1:101:D0EKPACXX:2:1101:12875:176255 0 3R 775 16 51M * 0 0 GTGCGCTCGTGTTTCTGTGAACCCAATCGCGAACACTGTTGTGAGCCAGTG @@@ADDADH?EGGGG?GGGGI'=CHEC<)5=CHIIG=7 XA:i:0 MD:Z:51 NM:i:0 DD61XKN1:101:D0EKPACXX:2:2206:13591:47620 0 3R 824 17 51M * 0 0 TGGCTCTGTCTGCGCGGCGAGAAATATCCGCTTACCTAAACGAAAAGTTCT CCCFFFFFHFHHHJJIGIIIDFBGHIJIJJIJIIHHHFHHFFFDDDDCC>B XA:i:0 MD:Z:51 NM:i:0 DD61XKN1:101:D0EKPACXX:2:1308:18519:39835 0 3R 841 31 51M * 0 0 CGAGAAATATCCGCTTACCTAAACGAAAAGTTCTCTAGCGTCGGCCGACGC @CCFFFDFFHFFHBHIJIJCHIJJJICHGCFHECGGIEIGIFIFIIIDHFC XA:i:0 MD:Z:51 NM:i:0 DD61XKN1:101:D0EKPACXX:2:1207:12521:101238 0 3R 842 3 51M * 0 0 GAGAAATATCCGCTTACCTAAACGAAAAGTTCTCTATCGTCGGCCGACGAC @<@BDDDD?F==69D6D?DDFEEGGEEB3@CAEA>FF:FEBFAEHB6>CC?BBB59< XA:i:0 MD:Z:51 NM:i:0 DD61XKN1:101:D0EKPACXX:2:1107:3972:59070 16 3R 868 36 51M * 0 0 GATCTCTCTAGCGTCGGCCGACGCACGGCACCCAGGCACACACACAGCCAC #############@4;76A@:81)::EC@3GIHA@EDC8C/=D=:/BFBHF?@;ED?1BAGHEIIHEBF??3CDCFBD>AD@@@ XA:i:0 MD:Z:0A1G0T47 NM:i:3 DD61XKN1:101:D0EKPACXX:2:1207:13576:40002 16 3R 868 2 51M * 0 0 GATCTCTCTAGCGTCGGCCGACGCACGGCACCCAGGCACACACACAGCCAC ##?=3C>A?<<:;/@@D6FDDA@?8AECCBBDDFDDDDD@@@ XA:i:0 MD:Z:0A1G0T47 NM:i:3 DD61XKN1:101:D0EKPACXX:2:2106:13119:17764 16 3R 868 32 51M * 0 0 AAGTTCTCTAGCGTCGGCCGACGCACGGCACCCAGGCACACACACAGCCAC CCACEDDDFEFEHGIJIIGHHHGGGHGHEAIJIGGH@DFFDBFDDEDF@?? XA:i:0 MD:Z:51 NM:i:0 DD61XKN1:101:D0EKPACXX:2:2204:20637:13691 16 3R 868 18 51M * 0 0 GATCTCTCTAGCGTCGGCCGACGCACGGCACCCAGGCACACACACAGCCAC #A=53AA>ED=EB@EHGHDDD@??:CFF<3GIHDBFCAA;/?<8:@;>BFF?<<=;'FAGEGAD6DE?6GG@AEIIGGG@EBA?CFDDDDD@?@ XA:i:0 MD:Z:0A1G0T47 NM:i:3 DD61XKN1:101:D0EKPACXX:2:2303:4165:141511 16 3R 868 40 51M * 0 0 GATCTCTCTAGCGTCGGCCGACGCACGGCACCCAGGCACACACACAGCCAC #@;;(>38B=<:BAAA XA:i:0 MD:Z:51 NM:i:0 DD61XKN1:101:D0EKPACXX:2:2105:7761:130218 0 3R 876 1 51M * 0 0 TAGCGTCGGCCGACGCACGGCACCCAGGCACACACACAGCCACATTTGCAG @@CFFDFDDDFHFFGIJJJIHAFHIGHIGHHFHBFEDA@?B@D@CDDDDEC XA:i:0 MD:Z:51 NM:i:0 DD61XKN1:101:D0EKPACXX:2:2106:20083:91623 0 3R 876 3 51M * 0 0 TCGCGTCGGCCGACGCACGGCACCCAGGCACACACACAGCCACATTTGCAG 11144@DDA>A@ XA:i:1 MD:Z:1A49 NM:i:1 DD61XKN1:101:D0EKPACXX:2:2106:11915:186462 16 3R 876 39 51M * 0 0 TAGCGTCGGCCGACGCACGGCACCCAGGCACACACACAGCCACATTTTCGG BBBCDFFIIIFEBEIFDABBC9IIFFHFF@ECDEBBFEFFC<<4)04++11 XA:i:2 MD:Z:47G1A1 NM:i:2 DD61XKN1:101:D0EKPACXX:2:2305:7910:29158 16 3R 878 32 51M * 0 0 GCGTCGGCCGACGCACGGCACCCAGGCACACACACAGCCACATTTGCAGAA CFDBGIIGIGGHGHDGFD@BGEHCGHF;GFECGEIIGHFFFHHFFFFFCCC XA:i:0 MD:Z:51 NM:i:0 DD61XKN1:101:D0EKPACXX:2:2106:9016:64754 0 3R 880 2 51M * 0 0 GTCGGCCGACGCACGGCACCCAGGCACACACACAGCCACATTTGCAGAAAT @@@FFF>DHDHAFGIJGGIIGIGIIIIHGHIJJGGFHFFFFFFEDEEEADC XA:i:0 MD:Z:51 NM:i:0 DD61XKN1:101:D0EKPACXX:2:1304:4663:45784 16 3R 884 26 51M * 0 0 GCCGACGCACGGCACCCAGGCACACACACAGCCACATTTGCAGAAATACCA BGB;HEGGFIIGEECHFCIHHAHHDFFDD@@@ XA:i:0 MD:Z:51 NM:i:0 DD61XKN1:101:D0EKPACXX:2:2307:5310:188136 16 3R 885 12 51M * 0 0 CCGACGCACGGCACCCAGGCACACACACAGCCACATTCGCAGAAATACCAC #@5;@@@6@@B0:GIHGGFD?;CBBECCGCEFAEF@E8DDDDBDE;C+238BEEAAED>*0?DEEC3BDDFHGIGIH XA:i:1 MD:Z:10A40 NM:i:1 DD61XKN1:101:D0EKPACXX:2:1103:2005:94273 16 3R 919 26 51M * 0 0 ATTTGCAGAAATACCACTACATACGAAACGAACGTGGCCAGCACACAAGCG GJJIJIIGIIHEFIIIIGHIIHIIJIIIIIIJHGHJJIHHFDFDDFFF@@@ XA:i:0 MD:Z:51 NM:i:0 DD61XKN1:101:D0EKPACXX:2:1104:3068:110926 0 3R 924 14 51M * 0 0 CAGAAATACCACTACATACGAAACGAACGTGGCCAGCACACAAGCGAAACC @@@=D>?DFB3<;CG@IEDFBDEGGHGGHHHHHEDDFFCCC XA:i:0 MD:Z:51 NM:i:0 deepTools-2.5.0/deeptools/test/test_data/test2.bam0000640000201600010240000010220512757050136021273 0ustar ryanbioinfoBC^@BAM)@HD VN:1.0 SO:unsorted @SQ SN:3R LN:1500 3RY@@BC |*I3DD61XKN1:101:D0EKPACXX:1:1307:6042:1203990HH((!DH$@# " %#$ %!$%%$!$#$%'!%&($#$ !#&(XACMDZ51NMC*%I3DD61XKN1:101:D0EKPACXX:1:2201:2981:1589950HH((DH!H# ""#"$ $  ""  $ XACMDZ19G8C14G7NMCN*I3DD61XKN1:101:D0EKPACXX:1:1108:19948:917540(HB"!!DD"(@'''%#())'$))))))))()'''())((&&)(&('%&%%!''%%%%%"""XACMDZ51NMCW*I3DD61XKN1:101:D0EKPACXX:1:2102:10665:575930"(HHB!H(D! """%%%%%#''%%'&$%&'"""%'&$&&$!'&" "%"&&'# #'()&&XACMDZ43A7NMCZ*I3DD61XKN1:101:D0EKPACXX:1:2102:11401:945390B"!!DD"(HB@'((&'"((('"%%%'%$'$&&$&&'&' ##(&('%!%% %#$##XACMDZ51NMC^*I3DD61XKN1:101:D0EKPACXX:1:1306:7851:1907160!!DD"(HBB$ ##! %'' ""%%'#'(%&"!''&''"'&"(!%#'#!" 'XACMDZ51NMCk) I3DD61XKN1:101:D0EKPACXX:1:1308:7611:235340HB!H(D!!"B(HH(%!## #&)('&%%#&'&''%")&'$"((&((&(&'&'&%%###"""XACMDZ51NMCk) I3DD61XKN1:101:D0EKPACXX:1:2305:1314:971440(HB!H(D!!"B(HH(&%&'"'$$"($'&%())((&&##('('$%"' &'!#%!#$##%%XACMDZ0A0C49NMC~)I3DD61XKN1:101:D0EKPACXX:1:2107:3608:703790HBB$(AA""("""#%%%%''''')'())))(())))&(()'()())())))))))))()((XACMDZ51NMC*I3DD61XKN1:101:D0EKPACXX:1:1308:12105:616090(D!!"B(HH!"!BB #####!!#$#&&("''%$%"$%'(&(%%'((($#%'!'%XACMDZ51NMC*$I3DD61XKN1:101:D0EKPACXX:1:1204:8617:1700170BB$(AA""($"####%!%%#$'#!'''%%&"&% &#&&%!&(&&(((%#XACMDZ51NMC*!I3DD61XKN1:101:D0EKPACXX:1:1301:14071:879490D!!"B(HH!"!BB( #!$ %' '#&&"!'&!!'#$'$(&$$'&'&'&&'%"&'(&&XACMDZ50A0NMC+I3DD61XKN1:101:D0EKPACXX:1:1207:15012:1982240!"B(HH!"!BB((@(& !%'%$$&"(&&(&&%$$&(#%'&&%'''##!XACMDZ51NMC*I3DD61XKN1:101:D0EKPACXX:1:1108:20053:528350$(AA""($""$&"!&%#! &%!'&% '#! &((&%#" %# XACMDZ21T29NMC*$I3DD61XKN1:101:D0EKPACXX:1:2205:3896:1017410(AA"""$""$&%&'&'#(&$#((((((&(((('%##!#&&&# '#'%#%%%XACMDZ0C30T19NMC+I3DD61XKN1:101:D0EKPACXX:1:1304:17350:1412660(HH!"!BB((BH!""#%%%#'%'''&'(((')())&)&'&(((()())(&'(%%&$'()))(XACMDZ51NMC+ I3DD61XKN1:101:D0EKPACXX:1:2308:16926:1463360(HH!"!BB((BH!"!%%!#!%#!!%')(&&)(()(&"'()$('())((()#&(&')))))&XACMDZ51NMC*I3DD61XKN1:101:D0EKPACXX:1:1206:19765:241060H!"!BB((BH!"A@((((&'%(&$'"''%!&%&&$ $&"$" &%"$"'&'##$#!"XACMDZ51NMC* I3DD61XKN1:101:D0EKPACXX:1:1103:7490:2001700A""($""$!A@#'(&&&!"%#'$"&('#&#&&%!"'$&#(('& #%'%!%###"XACMDZ51NMC)I3DD61XKN1:101:D0EKPACXX:1:2107:9512:138650!"!BB((BH!"ADA@(''& '&&!!&#&&#(&'&'% " ! '&&& #&''%%%%#"XACMDZ51NMC*"I3DD61XKN1:101:D0EKPACXX:1:1203:10217:202040"($""$!AH$ "#((# # # "%$  " "" ###XACMDZ51NMC*I3DD61XKN1:101:D0EKPACXX:1:1306:19026:426920"($""$!AH$ !((&&%% % '&#%!%#!(&'#"$&%'&'& &&%'#'%## %#XACMDZ51NMC*I3DD61XKN1:101:D0EKPACXX:1:1303:1729:1247910"($""$!AH$("%%%#$'''''))&''&(&' '())(($(&&()#&!'%'(())()))XACMDZ51NMC) I3DD61XKN1:101:D0EKPACXX:1:2108:3585:273500"($""$!AH$(%!%%#!&##''$ ''))('$#$&''$%%%''&%%###XACMDZ51NMC*I3DD61XKN1:101:D0EKPACXX:1:1108:19068:664810"!BB((BH!"ADAA!A"@%%%%#'%%%%(&(&((%#&%'"&(#$&('$#&%&'&$& &XACMDZ50C0NMC+#I3DD61XKN1:101:D0EKPACXX:1:2307:20427:1312050"!BB((BH!"ADAAAD!A#  !%"%#"%  !%#XACMDZ40C1G0A0A0T1C0T1C0NMC*I3DD61XKN1:101:D0EKPACXX:1:1101:8129:1110820"!BB((BH!"ADAA!A" '(&!(('#('%!!%$&"$('%()((((&$'%&%(&'!##'&#%!%#XACMDZ51NMC)$I3DD61XKN1:101:D0EKPACXX:1:2308:9605:815730$"$!AH$$@#### $$ "$$"#"# !"XACMDZ6C37C0T1C0T0A1NMC+(I3DD61XKN1:101:D0EKPACXX:1:1106:21127:1836920B((BH!"ADAA!A"("#%%%%&'%% '())(&#'&'$&%''((''(&(&$'"$"#&"!&"XACMDZ51NMC($I3DD61XKN1:101:D0EKPACXX:1:1307:6197:28410""$!AH$((@#!#%#$%%!$  ""%%%#&#! !!%XACMDZ44G6NMC* I3DD61XKN1:101:D0EKPACXX:1:1304:15855:767400""$!AH$(H(@ #"#"#&'%'%#& &('&&$$$! ('!&% ## XACMDZ51NMC)I3DD61XKN1:101:D0EKPACXX:1:1205:8830:103220((BH!"ADAA!A"("  ##"##$$#   !!###! ##!!!XACMDZ24T26NMC*I3DD61XKN1:101:D0EKPACXX:1:1107:3548:1775280(BH!"ADAA!A"(""######"##$$$$$%  ""###$ !#!##$# XACMDZ51NMC*!I3DD61XKN1:101:D0EKPACXX:1:2307:16591:878470$!AH$(H(B($#####%%%%  " #%!$%&# $&$( %&&%%((%XACMDZ51NMC*I3DD61XKN1:101:D0EKPACXX:1:1303:13801:605060!"ADAA!A"(""AH$####%!%! " &%&'!"#!"&##!%"!&&$##XACMDZ51NMC*"I3DD61XKN1:101:D0EKPACXX:1:1104:5795:1273540"ADAA!A"(""AH$ ##$ !%#% #!'!&%$#"'&(($&(#'&'((((((&(##'&'"XACMDZ51NMC*I3DD61XKN1:101:D0EKPACXX:1:1301:4704:1436910"ADAA!A"(""AH$ !#%#% #''!&$$'& '(&((((((%(!"&'&&$&(&(%!' "#XACMDZ51NMC)I3DD61XKN1:101:D0EKPACXX:1:1305:7404:948180AH$(H(B($BAD@ ""#!!##### ##"!#XACMDZ42T8NMC(I3DD61XKN1:101:D0EKPACXX:1:1307:3116:64300AH$(H(B($AD@" ! %# #&"%%$%!"#"" % # ### #XACMDZ51NMC+I3DD61XKN1:101:D0EKPACXX:1:1107:16927:1539760H$(H(B($ADB#!  %% $ %"'$&"!$""%%'%## &&%$!!&XACMDZ51NMC*I3DD61XKN1:101:D0EKPACXX:1:2107:4832:1095720$(H(B($ADB$!### ## &!&#$ $%'"%'&#"%!%%!& $!XACMDZ51NMC*I3DD61XKN1:101:D0EKPACXX:1:2204:6880:1275110$(H(B($ADB$#####%%%%%(%%(( "%'$%%((%&%"&$(((((%%$"%"$XACMDZ51NMC+I3DD61XKN1:101:D0EKPACXX:1:2101:10755:1149280AA!A"(""AH$$D!AABA@#####%#'#'$%$'$'&&#'&(((%&''&&(('(&&(!" '&('$XACMDZ51NMC*I3DD61XKN1:101:D0EKPACXX:1:1203:9513:1503530!A"(""AH$$D!AABAA##### #!"! $ $#%$ $## ""XACMDZ51NMC)$I3DD61XKN1:101:D0EKPACXX:1:1205:4068:124960"A(A($ADB$D#%!%$((''"'& $$'%"!%##XACMDZ1C1T0A0C1A0G6C35NMC)I3DD61XKN1:101:D0EKPACXX:1:2202:4350:758620"AH$$D/AABAAHBHAHA@"""%%%%%''''&))))))%"'()&($'())('()())))%"'#'(&XACMDZ19A31NMC+I3DD61XKN1:101:D0EKPACXX:1:2308:11549:1284480"AH$$D!ABAAHBHAHA@##### %##&((!'$'"#'%'(&'$&((%!'#&&'&% XACMDZ20G30NMC)%I3DD61XKN1:101:D0EKPACXX:1:2106:6241:534980"!H$$D!AABAAHBHAHAB@"%!!$#%#'%'($&&&&'&'$&%' %'$#'&('(&%#%#"'XACMDZ4G46NMC+I3DD61XKN1:101:D0EKPACXX:1:1302:13211:1694140($ADB$D!D$ %!#!#%%'''(((&(&(%%# &!&&('%$&'((""&%'&$!XACMDZ51NMC*"I3DD61XKN1:101:D0EKPACXX:1:2108:3748:1389790($ADB$D!DD %#%#'#'%%('&&&($(#&(!%'()(%%("''()$'(#"""$XACMDZ46A1C0G1NMC+I3DD61XKN1:101:D0EKPACXX:1:1207:13423:1025250D$!AABH($A(($BAB!""""""$!"%%"&! !&&('"#&#%#!%&%''%#####XACMDZ51NMC*I3DD61XKN1:101:D0EKPACXX:1:2102:11015:975950ABB$A$H$$!!@#! #%%#%''&(&(((((&'!#$&#(('#&&$)('&'&'%%%%%""XACMDZ51NMC* I3DD61XKN1:101:D0EKPACXX:1:2306:9355:1413230ABB$A$H$$!!@!'&&&"'%"%& &$'&#&%"%#%%%!!### XACMDZ51NMC*&I3DD61XKN1:101:D0EKPACXX:1:2202:9047:1014840$!AABH($A(($BAB!@(((&&&!  '&%!(((('&%"%%('% #'($'(&'''#%%%%%"""XACMDZ31C19NMC+I3DD61XKN1:101:D0EKPACXX:1:2105:11395:1665240(AABH($A(($BAB!A !    "&$'&%#"% &!&&%!%'%! ##XACMDZ1A49NMC!) I3DD61XKN1:101:D0EKPACXX:1:2208:17627:87900$A$H$$!!HH$( "!!! !!! % (&&&&%"&&&&'#%%'# #%%XACMDZ31A19NMC#+I3DD61XKN1:101:D0EKPACXX:1:2204:12638:1397800A$H$$!(HH$(!@"#####%#%'$'&'))(()))))()('$&" &(('))''%'%#%%%%"""XACMDZ31A19NMC()'I3DD61XKN1:101:D0EKPACXX:1:2305:9127:458480$A(($BAB!A$B#%%%%%%'#%%"%'&($ &$&(!&())("&('&(&##" "XACMDZ51NMC)+%I3DD61XKN1:101:D0EKPACXX:1:1301:13576:1992900A$H$$!!HH$(!A!A## #!!"%#&&$%#!!"%!!#XACMDZ48C0T0G0NMC++I3DD61XKN1:101:D0EKPACXX:1:1305:10305:1393670$H$$!!HH$(!A!(H!##### ## !#"!      # #XACMDZ50C0NMC1)I3DD61XKN1:101:D0EKPACXX:1:2204:8124:349460H$$!!HH!(!A!(H$B!@$!'& & !%##)'((((&&))(&'%%'$('&'%''''#%%%%"XACMDZ31G19NMC1+I3DD61XKN1:101:D0EKPACXX:1:2301:13637:1982070H$$!!HH$(!A!(H$B!@! $$$"((((((((%((((&('% &$&&&$$&$(%%'' %%%%XACMDZ51NMC=)I3DD61XKN1:101:D0EKPACXX:1:2303:3102:376810!!HH$(!A!(H$B!A!A#####  " "#"## # !""XACMDZ9A37T0C0C0A0NMCO+I3DD61XKN1:101:D0EKPACXX:1:1202:15301:1181220$(A!(H$B!A!"H$BH'!!# &&&!%!&&% XACMDZ2C2A45NMCO*I3DD61XKN1:101:D0EKPACXX:1:1307:2511:1007280"A!(H$B!A""H$BH! ! ##!" XACMDZ1G0C0T0C0A0G18A25NMCR*I3DD61XKN1:101:D0EKPACXX:1:2208:19469:212860D"!AA$H$$A ####%%#%%(#%"% $&%((%&#&"(%%(#% $!"#XACMDZ19T31NMCh* I3DD61XKN1:101:D0EKPACXX:1:1304:18506:916720!AA$H$$A!($BDB"##!#%'&#%&'("$%""%#%!&%'!%#%""!%""$((XACMDZ50G0NMCm* I3DD61XKN1:101:D0EKPACXX:1:2106:3217:1159290"H$BH"BH$D(""%#### %%$&&%'&((#&((((((%((((("'$$&$XACMDZ22A22G4T0NMCw*I3DD61XKN1:101:D0EKPACXX:1:1202:8838:1834780H$BHBH$D$"DA"  "#&&(%%&$!$%!# "##! XACMDZ23T27NMC})I3DD61XKN1:101:D0EKPACXX:1:2208:6719:449690BHBH$D$/DA"!HD$!#((&&$))))))))((()))))))('% ((&('(%%%&%%%%#XACMDZ31C19NMC+ I3DD61XKN1:101:D0EKPACXX:1:2107:10458:1796970HBH$D$"DA"!HD#####  %'&%""%%'#'&&'&%"'($&'%'$$"""""""XACMDZ51NMC*I3DD61XKN1:101:D0EKPACXX:1:2305:19231:720180HBH$D$"DA"!DD####'%'&    "% %XACMDZ45T5NMC)I3DD61XKN1:101:D0EKPACXX:1:2107:15978:53970!($BDBB!HA$"AH %%!##''&''(#%$&&()%&!()"#"&(&!&!$#%""%#"#"$##!XACMDZ51NMC*%I3DD61XKN1:101:D0EKPACXX:1:2108:5650:1775800$BDBB!HA$"AH!H"#!#!#%##'%%&% &##%$'##&$"$!"XACMDZ51NMC*I3DD61XKN1:101:D0EKPACXX:1:1303:9692:1248690$($D$"DA"!HD$A!@ !!#"%%!""!('$'"%$%%##!XACMDZ0T0C0G1A0G45NMC*I3DD61XKN1:101:D0EKPACXX:1:2206:8706:1392170$BDBB!HA$"OH!H"@ "#%"#!%$"$%%!$ &$% #####XACMDZ31A19NMC)$I3DD61XKN1:101:D0EKPACXX:1:1102:5315:355380D$"DA"!HD$A!DAA@# #%#%'#%$%'"%&%%% !% !!!"&"XACMDZ45G0A1A2NMC*I3DD61XKN1:101:D0EKPACXX:1:1205:3993:1775640D$"DA"!HD$A!DD@%%#!!%#'#%%$%%"$!'&!%%" "!"'$ '%''##%%#XACMDZ51NMC+I3DD61XKN1:101:D0EKPACXX:1:1201:17678:1432040!HA$"AH!H"DA$B#####"% % #%!$#$!&&"%&"%''("$&(!'!"XACMDZ51NMC)I3DD61XKN1:101:D0EKPACXX:1:1204:6403:231000!HA!"AH!H"DA$B#!""  $! !## XACMDZ9G41NMC* I3DD61XKN1:101:D0EKPACXX:1:2301:11427:643150!HA$"AH!H"DA$B)'%()(&('&)))())()''&((('%))))))')))('''''%%%%%"""XACMDZ51NMC*$I3DD61XKN1:101:D0EKPACXX:1:1203:4885:1756950DA"!HD$A!DDH!B #!%#%% "&!'&&$% %'$( ##&!"' " XACMDZ51NMC*I3DD61XKN1:101:D0EKPACXX:1:1301:1384:1212980DA"!HD$A!DDH!B """%#$%%'''''&((()(&'()()())%"'))))()('()()())((()(XACMDZ51NMC*I3DD61XKN1:101:D0EKPACXX:1:1207:10462:363210DA"!HD$A!DDH!B"#### !#%%& !$#!&"&&!!%&()#'$ #!"$%'XACMDZ51NMC) I3DD61XKN1:101:D0EKPACXX:1:1307:4428:770900DA"!HD$A!DDH!B"(''$#&&(&%((&(&('$)(&($&'%&'&&&&$%& #! '%%%#%""XACMDZ51NMC*I3DD61XKN1:101:D0EKPACXX:1:2103:13338:577210H"!HD$A!DDH!B" '&!& ((&'#%!))('(&))(())(&&%&'##'&'%%#%%""XACMDZ1A49NMC)I3DD61XKN1:101:D0EKPACXX:1:2203:5030:495370!!HD$A!DDH!B"'&%(&'%#%&!##'(&(&((((&&'%  &"'''''#####XACMDZ1C29A19NMC+I3DD61XKN1:101:D0EKPACXX:1:2202:11507:1471900$A!DDH!B"($D@ ### ##$$$$ ###!#!#!#! !# ## XACMDZ19A31NMC*I3DD61XKN1:101:D0EKPACXX:1:2307:17903:304160$A!DDH!B"($D@####%%!' $$'%&& !$$% &'&&(( !!%$$'$'(&'  XACMDZ51NMC+I3DD61XKN1:101:D0EKPACXX:1:1302:14199:1558860"DA$B"!H!BDADD@((' (&)(((&(')('$('!))))()(&&$'%%"%$('''''%%%%%""XACMDZ51NMC)I3DD61XKN1:101:D0EKPACXX:1:1105:8679:979170H!B"($DDH(A!B@!###%#%%  ""!$&(("#%(%"!#%%!" $"XACMDZ51NMC+I3DD61XKN1:101:D0EKPACXX:1:1108:13946:1457210B"($DDH(A!BBHB@#"""""" #####!$!#  $$####XACMDZ51NMC(I3DD61XKN1:101:D0EKPACXX:1:2307:2862:41710"($DDH(A!BBHBH%%% # %' %%$$'#$'#"%'&%$' &"'XACMDZ51NMC)I3DD61XKN1:101:D0EKPACXX:1:2208:7118:890610($DDH/A!BBHBH#%%#$ ''('#&&)('%(((('"&'%!((''$'#%&''%%%%%"""XACMDZ0C30T19NMC*#I3DD61XKN1:101:D0EKPACXX:1:1301:3974:1857780!H!BDADDABA$$$$@###"%#%&(($% %"#%!!%%#%$$!"XACMDZ51NMC*%I3DD61XKN1:101:D0EKPACXX:1:1307:10125:501370!BDADDABA$$$$AA ##"% $"!&&%$  XACMDZ49T0G0NMC)$I3DD61XKN1:101:D0EKPACXX:1:1203:5003:273140($DDH(B!BBHBH#%%! # $"$%#%#!##XACMDZ1T27A21NMC+&I3DD61XKN1:101:D0EKPACXX:1:1202:20532:1653950($DDH(A!BBHBH!!# %'% $"&&#'&&#&#'&#&'&'!$"!$" "XACMDZ51NMC+I3DD61XKN1:101:D0EKPACXX:1:2303:15856:1340020($DDH(A!BBHBH%%%#%'%'#% &'&((&'$#%'&!#$$& !'$!#$" $$""XACMDZ51NMC*&I3DD61XKN1:101:D0EKPACXX:1:2104:6954:1712550ADDABA$$$$AHAHAA## #%#"   "$ XACMDZ47C0A1G0NMC*$I3DD61XKN1:101:D0EKPACXX:1:2307:7881:1968300BA"$$$AHAHBDB@ %$$#"'%'&&'&&#&$"&%''&((&(((&!#%######XACMDZ0G8G41NMC+ I3DD61XKN1:101:D0EKPACXX:1:1202:12689:1413850(A!BBHBH!AA$$ ####%'$#%'&#'!#!%"%'&$ %$ &&'#'' XACMDZ51NMC+I3DD61XKN1:101:D0EKPACXX:1:2207:10715:1094200(A!BBHBO!AA$$ #%%%%'%'%!$"#!#%'$$$%"&&((&&"& $$$!" XACMDZ19T31NMC+I3DD61XKN1:101:D0EKPACXX:1:2204:18234:1794240(BA"A$"H!DB@   # $$$%  $($$!$#"### !XACMDZ0G0G49NMC+(I3DD61XKN1:101:D0EKPACXX:1:2304:8751:26320$B!"D(($ """%%%%%'&''')&((()((()!'()()))%! #"&'&&"%$&&&())("XACMDZ51NMC=*I3DD61XKN1:101:D0EKPACXX:1:2203:1524:1842510"D(($("D$#####'''''(&"%' "$&%''((("#&'&((#%#$&(%#XACMDZ51NMC?)(I3DD61XKN1:101:D0EKPACXX:1:2102:8875:724430D(($("D$@$# '%)((('%$"()('&(''"'&#'"('$%&(&($('##''%%#%%XACMDZ51NMC@*I3DD61XKN1:101:D0EKPACXX:1:2106:7946:1344610ABHHHBHHH!$HHAHHAD@""#"&(((&$&'%'$%!((('&&((' &$&&'$ !!%&%#%#%"XACMDZ1G0G35G12NMCC*I3DD61XKN1:101:D0EKPACXX:1:2101:3407:1410940(($("D$D!@##$%%''#%"&$'(&%%'()'&%'(((((#$'&$&!%&&XACMDZ51NMCC* I3DD61XKN1:101:D0EKPACXX:1:2303:12087:401070(($("D$D!#####%  #%&$&"&'''&!%%'(((%''&&(&#%%'(&&((&XACMDZ50G0NMCC+%I3DD61XKN1:101:D0EKPACXX:1:2106:16683:1769960(($("D$D!@%'''$&'$"(((&&'&(((('&$(&((&& '&'#&%'#'&%%%%%XACMDZ51NMCD*'I3DD61XKN1:101:D0EKPACXX:1:2105:6289:1408920"AHHBHH!$HHBAHHADB@  !#($#!###$% !#" !##XACMDZ0T0T1C1T0G9G34NMCJ*I3DD61XKN1:101:D0EKPACXX:1:1103:12128:780550HHBHHH!$HHBAHHADBD(@! %!!#!&####$"""(&(&'# #%'%#####XACMDZ0G0T49NMCJ*I3DD61XKN1:101:D0EKPACXX:1:1107:5965:1625080HHHBHHH!$HHBAHHADBD(@   ###%%(&%$" $'&!$##!###!XACMDZ51NMCK)I3DD61XKN1:101:D0EKPACXX:1:2301:1260:241740$("D$D!DB "$$########"%$$"!#""#!#XACMDZ51NMCM)I3DD61XKN1:101:D0EKPACXX:1:1104:5082:177410$("D$D!DB" &&(&((%()))()((()))))))))'(((()()))))'''''%%%%%""XACMDZ51NMCQ*I3DD61XKN1:101:D0EKPACXX:1:1302:13170:747860$("D$D!DB"H@ (&&((&$'&& &'%'#('((((()(($$((&&'!(%%%%%#!#XACMDZ51NMCR+ I3DD61XKN1:101:D0EKPACXX:1:2307:14759:1214170HHH!$HHBAHHADBD(B!D !###%$%$"%"!"#%(%%%%$%%($%%((("$XACMDZ51NMCW*I3DD61XKN1:101:D0EKPACXX:1:2105:19416:611960("D$D!DB"HA@$$"#'&' ('&(&!&('%""'%&% &&'& &(((''##%###XACMDZ51NMCW+!I3DD61XKN1:101:D0EKPACXX:1:2301:20635:1281030("D$D!DB"HA@(''$&(&(&#&%#$"#"&$&'%%'&'('$''##'####XACMDZ51NMC]*I3DD61XKN1:101:D0EKPACXX:1:1305:6666:1598190("D$D!DB"HAB("%%##''''')%$#%'(&&($')))())))))(!%$$')(((())))XACMDZ51NMC^+I3DD61XKN1:101:D0EKPACXX:1:2201:16418:1399230$HHBAHHABBD(B!D" ###%%% $" %%(#$$&%!!!%%($"$%%%%((!XACMDZ19G31NMC^+$I3DD61XKN1:101:D0EKPACXX:1:2202:21067:1482110$HHBAHHAOBD(B!D" %%##%'''%' %%("&$#&&%'!!#'%$&(&&'!&(((&"XACMDZ19G31NMC^*%I3DD61XKN1:101:D0EKPACXX:1:1103:15967:151860$HHBAHHADBD(B!D" $$'%"''##&'!!'&#")(&((('%((('#'!((''#!%''%#$#!XACMDZ51NMCc*I3DD61XKN1:101:D0EKPACXX:1:2305:6803:1166980$D!DB"HAB( ##!!&%#!$'&"& ('$"(%'&&#%##$&##'!###!! XACMDZ51NMCg("I3DD61XKN1:101:D0EKPACXX:1:2206:1076:39670$D!DB"HAB("@!!"%"%##!#%!%" $" $"# %##XACMDZ31A19NMCg*I3DD61XKN1:101:D0EKPACXX:1:2207:2606:1584810$D!DB"HAB("@)((()(&('&))))())&)))(('%'%% '&%('!'#''%##%%%"XACMDZ31A19NMCq* I3DD61XKN1:101:D0EKPACXX:1:1304:7344:1782320D!DB"HAB("HDA@#%%##%'&%''&&$!! %!''&(&(&$&$#&(&&%"!&#%&(%XACMDZ49C0T0NMCs* I3DD61XKN1:101:D0EKPACXX:1:2108:6658:1226480!DB"HAB("HDB@### #"%$$#$'! ''&%'$"&"#&' #$##!'"&XACMDZ49T0C0NMCs*I3DD61XKN1:101:D0EKPACXX:1:2206:14847:131550!DB"HAB("HDB "%%%%%'&'%%&&%&&" %''&&()))&'"&&(&$$&)))(%(&(#XACMDZ19A31NMCt*#I3DD61XKN1:101:D0EKPACXX:1:1301:9974:1528680D(B!D"(H"($D(@ '&%(''&('"&(("(#!"(&'%&&&&&&'&)('''%!""%%##%XACMDZ51NMC{*I3DD61XKN1:101:D0EKPACXX:1:2307:18343:748340"HAB(HDB$$ !""%%%%#%'''&)))))))()))((())))'()))((())))(&(()()%XACMDZ26C24NMC})I3DD61XKN1:101:D0EKPACXX:1:1105:16709:81510"HAB("HDB$$## ##% $%&'%'%%%$%'("!'((($&"%&!##%#%$((XACMDZ48C0A1NMC*I3DD61XKN1:101:D0EKPACXX:1:1304:21148:235900"(H"($D(H(B@&$'&(&('&&'&(((((&&&%%$&$('&!#%'(#%''#####XACMDZ51NMC*I3DD61XKN1:101:D0EKPACXX:1:1304:11733:717520B("HDB$$!$ ######''%%%$'(&$ $"''&&(($$##&'#$''#&("$"%XACMDZ51NMC+%I3DD61XKN1:101:D0EKPACXX:1:1106:13439:1572920"HDB$$!$!"##!! #!##!###""%$#"$#### ##!#XACMDZ51NMC*I3DD61XKN1:101:D0EKPACXX:1:1204:5265:1783580"HDB$$!$!(######''%(&$  %$$%#%!%'&((!!#'!%!XACMDZ51NMC*I3DD61XKN1:101:D0EKPACXX:1:1305:16468:516860B$$!$!(B####%%((&'&$'&&'&$('( " %&'"'!#'( !#!XACMDZ51NMC*%I3DD61XKN1:101:D0EKPACXX:1:2205:16349:302240B$$!$!(B))((('%)(()())('$))))()(())%$ (())))'''''%%%%%"""XACMDZ31T19NMC+I3DD61XKN1:101:D0EKPACXX:1:1207:19691:1301860(H(BA!HAA!H "!###%'% #!%!%& $&!$$''%&''(#&%&&("'%"'(&'XACMDZ51NMC)#I3DD61XKN1:101:D0EKPACXX:1:1202:5626:370740H(BA!HAA!H!@&''$!#(&$'&&& ((%(&(&((('%%"%&"(&&$'%#'' #%%%XACMDZ51NMC*I3DD61XKN1:101:D0EKPACXX:1:1302:19769:709930!HAA!H!BA(HHHBHB###%%'''''))(&(($($'()''&&'((()))('()('')(&((((&XACMDZ51NMC*I3DD61XKN1:101:D0EKPACXX:1:2106:7819:1748230AA!H!BA(HHHBHB ('"'$&$(('%'"&&#(& &!&&%$'&'&%&#$%!"# # ! #XACMDZ51NMC* I3DD61XKN1:101:D0EKPACXX:1:2106:3249:1249950(B$$$(H!"# !# % "$$ "$&$&%$"%#&&$%%((&%"%$  "%$XACMDZ12A38NMC)I3DD61XKN1:101:D0EKPACXX:1:2308:5372:747270(B$$(H!"&'%&'&(&%((((((('&&$&&%((((&&&%&$#'''#%#!XACMDZ51NMC) I3DD61XKN1:101:D0EKPACXX:1:1202:3174:693740B$$(H!"'"&$)($(&(((((('$('('&%&$)(&$)&)(%)))(''%&'$####"XACMDZ1G49NMC* I3DD61XKN1:101:D0EKPACXX:1:2102:17237:111750H!BA(HHHBH"!!(HA@""%! (' !""!%"!"!$'" "## %%$%#XACMDZ28G22NMC(I3DD61XKN1:101:D0EKPACXX:1:2201:5891:66920$$(H!"$""%%%%%%'''')))()) "&''()))))&()()())%'(((((&'&'XACMDZ48T1T0NMC*I3DD61XKN1:101:D0EKPACXX:1:1304:20633:468080!BA(HHHBHB!!(HAHH@''()(&'%$(&&'$(((&)()((('!'&% ('&'%)(&'''%%%%%%XACMDZ51NMC*I3DD61XKN1:101:D0EKPACXX:1:1308:4585:1424420!BA(HHHBHB!!(HAHHH@## ##"" $!$!&"%!%&!#&  %$##%'! XACMDZ51NMC*I3DD61XKN1:101:D0EKPACXX:1:2307:20474:889540!BA(HHHBHB!!(HAHHH@####%' ' %" $% %"%$&$!#'$&!!%'#'($'!XACMDZ51NMC*I3DD61XKN1:101:D0EKPACXX:1:1108:14466:366160!BA(HHHBHB!!(HAHHH@%!!%(%$%##!%##!%#"" "$  %$"%!####!XACMDZ51NMC*I3DD61XKN1:101:D0EKPACXX:1:2102:19912:173880!BA(HHHBHBB!(HAHHH@&)'$$'%)))))(&)))))))))))('%&" %'&))'''''%%%%%"""XACMDZ28A3C18NMC*I3DD61XKN1:101:D0EKPACXX:1:2202:10607:845790(HHHBHB!!(HAHHHHBB""%%###'''''()&()) "'')(&()((())))%&"#!&#"&(($((XACMDZ19G31NMC* I3DD61XKN1:101:D0EKPACXX:1:2206:11281:581200(HHHBHB!!(HAHHHHBB"% #$&'''&(((($' &())())&(&(()(%!%!%&&'()))%XACMDZ19G31NMC+I3DD61XKN1:101:D0EKPACXX:1:2205:21060:1993050$(A!!$(#! "!#""$  #$ #$###XACMDZ19T3C22C3C0NMC* I3DD61XKN1:101:D0EKPACXX:1:2102:18838:452990!!(HAHHHHBBHH(AA"#%%% #%%'%'&))((&& $''%' '&'()))'&&'&&( #''&&XACMDZ43T7NMC+I3DD61XKN1:101:D0EKPACXX:1:2102:17448:1309690(!"$$($"!'&!&$'%$!((((''#((((&('!(&!!$&!$'&###" ####XACMDZ0G50NMC+ I3DD61XKN1:101:D0EKPACXX:1:1104:16651:1196040!"$$($"! ##### !!#$%$$&%'  ""%!%!##$#%%"!%%%%%XACMDZ33G17NMC)I3DD61XKN1:101:D0EKPACXX:1:1205:2404:289400!!(HAHHHHBBHH(HA"@#" !##$$ $"!# ###XACMDZ51NMC+ I3DD61XKN1:101:D0EKPACXX:1:2302:17950:1878850!(HAHHHHBBHH(HA"BA#$$$'$(&$%"(&%$'#&&&$$($)())(((''%&&%# %%%"XACMDZ51NMC)%I3DD61XKN1:101:D0EKPACXX:1:1207:4005:626500HAHHHHBBHH(HA"BA #""!$$!&&& !! "##%#'&"&"&&XACMDZ51NMC*I3DD61XKN1:101:D0EKPACXX:1:1304:19026:394680HAHHHHBBHH(HA"BA#!" #% "$$%'&##$!'(((!'&"%'( $$'XACMDZ51NMC)I3DD61XKN1:101:D0EKPACXX:1:2306:9443:652800DHBAHHA"BADH@!  !"(((((%%$&" !####XACMDZ0G0A0G0T0G2T5C1C0G5C21T6NMC +I3DD61XKN1:101:D0EKPACXX:1:1307:13797:1826140HHHHBBHH(HA"BAHA@!!!$ '$'''%$#(&))())('#&&'(((&('))(&('!%'&%%#%%"!!XACMDZ51NMC*!I3DD61XKN1:101:D0EKPACXX:1:2305:6498:1257650$($"!$$!(H %%$'$$$&('%&'#)(&&%&"((&#&()(($((#)(&%#'&'%%%%%"""XACMDZ51NMC*!I3DD61XKN1:101:D0EKPACXX:1:1206:9986:1594040HHBBHH(HA"BAHAB!@! !#!#$%#$$$$" # ##! XACMDZ51NMC+I3DD61XKN1:101:D0EKPACXX:1:2303:20942:1228800$($"!$$!(H"##%%%&'!%%'&%%&(!%%'&&('!%'$'&%'(((&$&&&''"XACMDZ51NMC9*I3DD61XKN1:101:D0EKPACXX:1:2203:9722:1642740B$$BAD$("$H#!!!!"% "$ &$"'!""! "XACMDZ19A31NMC:*'I3DD61XKN1:101:D0EKPACXX:1:2107:19883:882060((H(BBD$"B(A(("%%%%%'''''&&$'!&&(("(%'(()!&$'(&'%'&$#%#$ $#%## XACMDZ51NMC<*I3DD61XKN1:101:D0EKPACXX:1:1204:2063:1767940(H(BBD$"B(A(( """%%%%%%''%%&&&&&&#%&&&())()&(&&''''%%"#"$ " " ""XACMDZ51NMC@*&I3DD61XKN1:101:D0EKPACXX:1:1105:19061:442910(BBD$"B(A(($@#!#%%''%###%($'&(((((((%  ""$$"!!#XACMDZ35A15NMCH+I3DD61XKN1:101:D0EKPACXX:1:1207:10060:1093720$"B(A(($D"A$ ""%%%%%##%'!$''!&&())&$&&&#"#&&&&$% &'(((&((!'XACMDZ51NMCI+I3DD61XKN1:101:D0EKPACXX:1:2206:11225:1325300AA$"$HBH$B$B#%%#!%'%# $$'&& %!&&(&&(&$ %&'!$%'!&$&('$XACMDZ12C6A31NMCL)I3DD61XKN1:101:D0EKPACXX:1:2102:6645:611020"B(A(($D"A$!$@%###"%#'$$' '$ $''!&))(''&&#&&%(&((&)''&''%%%##XACMDZ51NMCS*$I3DD61XKN1:101:D0EKPACXX:1:1204:16871:432920$("$HBH$B$"D!"!@## $$#""" !""  ## #XACMDZ5A32G12NMCY)I3DD61XKN1:101:D0EKPACXX:1:1201:12030:74620"$HBH$B$BD!"!D!! #" %%##$"""$$& &!((%'%$&$$#%%"#&'##$!#XACMDZ51NMCZ+I3DD61XKN1:101:D0EKPACXX:1:2202:17734:1117810(A(($D"A$!$B"B"%%!##%%'##'!!"$! &'&&&!&'&&$'%%%"##!! !XACMDZ19G31NMC]+I3DD61XKN1:101:D0EKPACXX:1:2206:13193:1922970$HDH$B$BD!"!D!!!! ##"%$"  $%&%%!&$ &"((%%! ###XACMDZ17C13C19NMCh*I3DD61XKN1:101:D0EKPACXX:1:1106:1847:1780790(($D"A$!$B"B"@"!!"$'& '!&%#'$%#&$&"&''#"""!%"!## !#XACMDZ51NMCh+I3DD61XKN1:101:D0EKPACXX:1:2103:18338:1592840(($D"A$!$B"B"@!%% #&!##%!%"%%'%%%##%%####!XACMDZ51NMCi)I3DD61XKN1:101:D0EKPACXX:1:2204:7449:596720BH$B$BD!"!D!!!!!B!! """%%%%%'&'''))))(&!"'(((((($''&&%%%#$##!####%$#XACMDZ19C31NMCj* I3DD61XKN1:101:D0EKPACXX:1:2101:18475:889630($D"A$!$B"B"B"""##%%%'&'''))($'&(()(()))()''''%#%##"####" ####XACMDZ51NMC+I3DD61XKN1:101:D0EKPACXX:1:2302:18497:1004560!"!D!!!!!B!!!A"!$%% #%%'%%&'$'!'(#" %'()&(()'(&&()$'&&$(((&(())XACMDZ51NMC*"I3DD61XKN1:101:D0EKPACXX:1:2206:6582:1594060DB"B!(A$ ####%%!#&'(!"$&'"!%'&&! !# "'&((((&$$XACMDZ0A18T31NMC+I3DD61XKN1:101:D0EKPACXX:1:1105:19632:1494420"B!(A$$@!!%$&&'#'$#%(&("('''# %" $#$&%!'&&'''###%#"XACMDZ51NMC)I3DD61XKN1:101:D0EKPACXX:1:1306:2059:453150"B!(A$$B #&!%'! !'%#&&"&"'&%""   $!#&!('%"!####XACMDZ51NMC*I3DD61XKN1:101:D0EKPACXX:1:2205:7552:1139120B!(A$$B!BBA )))($(&&!&$((&'('&')''(((&$&")((' '!%#'#%%%%%""XACMDZ51NMC)$I3DD61XKN1:101:D0EKPACXX:1:2106:3808:444430HD"!!!$$A"A"( (&'#&%##&"(#&' &&&&$(&''& $$ %%$('#%  !XACMDZ51NMC* I3DD61XKN1:101:D0EKPACXX:1:1303:14193:515300BA"D!!(B"BH( !#!% $"%$" (((%%%# XACMDZ51NMC)I3DD61XKN1:101:D0EKPACXX:1:1302:9341:739550(B"BH((!!BA &'%"!('%!%!####XACMDZ51NMC+I3DD61XKN1:101:D0EKPACXX:1:1307:16416:1215260$("BH((!!BA(@(& #$&$"'''" " # #XACMDZ0A0C0C1G0C45NMC)I3DD61XKN1:101:D0EKPACXX:1:1101:4449:444110(((H"$$(($(($A!$%$%%%&)))((&'$()))(&&$'$)('$'$& )('!'&'%#%%%"""XACMDZ51NMC.BCdeepTools-2.5.0/deeptools/test/test_data/test2.bam.bai0000640000201600010240000000014012757050136022020 0ustar ryanbioinfoBAII_J__deepTools-2.5.0/deeptools/test/test_data/test2.bg0000640000201600010240000000126012757050136021123 0ustar ryanbioinfo3R 0 25 1.68 3R 25 50 2.00 3R 50 75 0.40 3R 75 100 2.04 3R 100 125 5.44 3R 125 150 8.48 3R 150 175 13.48 3R 175 200 21.68 3R 200 225 22.76 3R 225 250 15.64 3R 250 275 7.28 3R 275 300 6.80 3R 300 325 11.76 3R 325 350 9.56 3R 350 375 5.20 3R 375 400 7.16 3R 400 425 13.76 3R 425 450 17.08 3R 450 475 12.44 3R 475 500 11.88 3R 500 525 10.64 3R 525 550 3.68 3R 550 575 1.88 3R 575 600 10.28 3R 600 625 19.64 3R 625 650 18.96 3R 650 675 12.48 3R 675 700 9.00 3R 700 725 9.44 3R 725 750 14.52 3R 750 775 17.32 3R 775 800 12.72 3R 800 825 5.64 3R 825 850 4.56 3R 850 875 10.28 3R 875 900 10.92 3R 900 925 8.76 3R 925 950 4.84 3R 950 975 2.76 3R 975 1000 2.68 3R 1000 1025 3.76 3R 1025 1050 2.44 deepTools-2.5.0/deeptools/test/test_data/test2.sam0000640000201600010240000011041212757050136021313 0ustar ryanbioinfo@HD VN:1.0 SO:unsorted @SQ SN:3R LN:1500 DD61XKN1:101:D0EKPACXX:1:1307:6042:120399 0 3R 3 26 51M * 0 0 ATTCTCTCTTGTTGTAGTCTCTTGACAAAATGCAATGGTCAGGTAGCGTTG ?@@=D4=AC2AFDE3:AFDE*:B?DGI# XA:i:0 MD:Z:51 NM:i:0 DD61XKN1:101:D0EKPACXX:1:2201:2981:158995 0 3R 7 37 51M * 0 0 TCTCTTGTTGTAGTCTCTTTACAAAATGTAATGGTCAGGTAGCATTGTTCT ??GFFBHHFFFFFCCC XA:i:0 MD:Z:51 NM:i:0 DD61XKN1:101:D0EKPACXX:1:2102:10665:57593 0 3R 88 28 51M * 0 0 TAAGCCCTATAAACATATGTACATAGGTAGGCCAGTACTTAGTGCTGGCAC CCCFFFFFDHHFFHGF;G3CBHHGHHCHGCI=BFDHDBCAH XA:i:0 MD:Z:51 NM:i:0 DD61XKN1:101:D0EKPACXX:1:1308:7611:23534 16 3R 108 11 51M * 0 0 ACATAGGTAGGCCAGTACTTAGTACTGGCACATGCCGCTGATCTGTTAGTA =IFBDDADGJIHGFFGHGHHFCJGHECIIGIIG>IGHGHGFFDDDCCC XA:i:0 MD:Z:51 NM:i:0 DD61XKN1:101:D0EKPACXX:1:2305:1314:97144 16 3R 108 12 51M * 0 0 CTATAGGTAGGCCAGTACTTAGTACTGGCACATGCCGCTGATCTGTTAGTA =@IGFGHCHEECIEHGFIJJIIGGDDIHIHEFC>HAGHBDFBDEDDFF@@@ XA:i:0 MD:Z:0A0C49 NM:i:2 DD61XKN1:101:D0EKPACXX:1:2107:3608:70379 0 3R 127 30 51M * 0 0 TAGTACTGGCACATGCCGCTGATCTGTTAGTAGATTATCCATTTCCCTTCA CCCDFFFFHHHHHJHIJJJJIIJJJJGIIJHIJIJJIJJJJJJJJJJIJII XA:i:0 MD:Z:51 NM:i:0 DD61XKN1:101:D0EKPACXX:1:1308:12105:61609 0 3R 132 28 51M * 0 0 CTGGCACATGCCGCTGATCTGTTAGTAGATTATCCATTTCCCTTCAGCGCC @@@DD?DDDBBD1EDGGICHHFEFCEFHIGI9?FBFFDEHD>?BHHH9FGGFBGIGGIII@@FD< XA:i:0 MD:Z:51 NM:i:0 DD61XKN1:101:D0EKPACXX:1:1301:14071:87949 0 3R 134 33 51M * 0 0 GGCACATGCCGCTGATCTGTTAGTAGATTATCCATTTCCCTTCAGCGCCTC @@@?DBEAFHAAAHDGGCBHG?B?BHDEHEIGEEHGHGHGGH@FCGHIGG# XA:i:0 MD:Z:50A0 NM:i:1 DD61XKN1:101:D0EKPACXX:1:1207:15012:198224 16 3R 138 30 51M * 0 0 CATGCCGCTGATCTGTTAGTAGATTATCCATTTCCCTTCAGCGCCTACCTG @@@IGABFFEEGIDFHGGFHHHDDB:1?@?@ XA:i:0 MD:Z:51 NM:i:0 DD61XKN1:101:D0EKPACXX:1:1108:20053:52835 16 3R 143 28 51M * 0 0 CGCTGATCTGTTAGTAGATTAGCCATTTCCCTTCAGCGCCTACCTGCGTCA @==3GC;B???4GFDBAGFB:)HGF=AHD;BAGIIGF@DC2+F@6DA?@@? XA:i:0 MD:Z:21T29 NM:i:1 DD61XKN1:101:D0EKPACXX:1:2205:3896:101741 16 3R 143 36 51M * 0 0 TGCTGATCTGTTAGTAGATTATCCATTTCCCCTCAGCGCCTACCTGCGTCA @GF;G@HGHDIGEDIIIIIIGIIIIHFDD?1)BDGGGDAAHDHFDFFF@@? XA:i:1 MD:Z:0C30T19 NM:i:2 DD61XKN1:101:D0EKPACXX:1:1304:17350:141266 0 3R 150 25 51M * 0 0 CTGTTAGTAGATTATCCATTTCCCTTCAGCGCCTACCTGCGTCACCAATGA @@CDFFFDHFHHHGHIIIHJIJJGJGHGIIIIJIJJIGHIFFGEHIJJJI< XA:i:0 MD:Z:51 NM:i:0 DD61XKN1:101:D0EKPACXX:1:2308:16926:146336 0 3R 150 13 51M * 0 0 CTGTTAGTAGATTATCCATTTCCCTTCAGCGCCTACCTGCGTCACCAATGA B@@FFBDBFDBBFHJIGGJIIJIGCHIJEIHIJJIIIJDGI@GHJJJJJG@ XA:i:0 MD:Z:51 NM:i:0 DD61XKN1:101:D0EKPACXX:1:1206:19765:24106 16 3R 154 4 51M * 0 0 TAGTAGATTATCCATTTCCCTTCAGCGCCTACCTGCGTCACCAATGATGAG IIIIGHFIGEHCHHFB8@GF?GGEAEGCEC8@AGFC:ECDHECGIHDGD6GGFBC92HEGDIIHGADFHFBFDDDC@@ XA:i:0 MD:Z:51 NM:i:0 DD61XKN1:101:D0EKPACXX:1:2107:9512:13865 16 3R 160 8 51M * 0 0 ATTATCCATTTCCCTTCAGCGCCTACCTGCGTCACCAATGATGAGGTCGAG IHHGAHGGBB8D?9:??8:)1+22CFEA,:4A<+AEEA?CEE?@)1?9?C?DC3?D:A/(8B)==@C###### XA:i:1 MD:Z:6C37C0T1C0T0A1 NM:i:6 DD61XKN1:101:D0EKPACXX:1:1106:21127:183692 0 3R 180 40 51M * 0 0 GCCTACCTGCGTCACCAATGATGAGGTCGAGACAGAATCCTACTAGTACCT @@@DFFFFGHFFAHIJJIGDHGHEG>FHHIIHHIGIGEHC>ECDGC@BG>C XA:i:0 MD:Z:51 NM:i:0 DD61XKN1:101:D0EKPACXX:1:1307:6197:2841 0 3R 181 36 51M * 0 0 CCTACCTGCGTCACCAATGATGAGGTCGAGACAGAATCCTACTAATACCTG @@FFBE4<2+A;*CC@F?)9?@FF@DGDAIHBGFA?>?DD?A??;@ XA:i:0 MD:Z:51 NM:i:0 DD61XKN1:101:D0EKPACXX:1:1205:8830:10322 0 3R 182 25 51M * 0 0 CTACCTGCGTCACCAATGATGAGGACGAGACAGAATCCTACTAGTACCTGC ?7?AA?DD<8CDDEED@+<:BB8)8B# XA:i:1 MD:Z:24T26 NM:i:1 DD61XKN1:101:D0EKPACXX:1:1107:3548:177528 0 3R 184 20 51M * 0 0 ACCTGCGTCACCAATGATGAGGTCGAGACAGAATCCTACTAGTACCTGCCT ??FG>DAE>GEI@*?FGDDDD9D?*:DD??):@C@<@2<@)BD??? XA:i:1 MD:Z:42T8 NM:i:1 DD61XKN1:101:D0EKPACXX:1:1307:3116:6430 16 3R 197 27 51M * 0 0 ATGATGAGGTCGAGACAGAATCCTACTAGTACCTGCCTCGAGTCGATCGGG @4C=)75A7=@B@A@F?9D?*DGCFFEFBC:DC8<@C+FADADDDA?D@@@ XA:i:0 MD:Z:51 NM:i:0 DD61XKN1:101:D0EKPACXX:1:1107:16927:153976 0 3R 201 25 51M * 0 0 TGAGGTCGAGACAGAATCCTACTAGTACCTGCCTCGAGTCGATCGGGCAGA ?@?DB2=AA@AAFFAEACFHGDCFBFF1BG>6?@@AEB;@### XA:i:0 MD:Z:51 NM:i:0 DD61XKN1:101:D0EKPACXX:1:2204:6880:127511 0 3R 207 16 51M * 0 0 CGAGACAGAATCCTACTAGTACCTGCCTCGAGTCGATCGGGCAGAGAGCGA @@@DDDDDFFFFE=CFCE< XA:i:0 MD:Z:51 NM:i:0 DD61XKN1:101:D0EKPACXX:1:2101:10755:114928 0 3R 208 1 51M * 0 0 GAGACAGAATCCTACTAGTACCTGCCTCGAGTCGATCGGGCAGAGAGCGAG @@@DDDDDFDHDH@EFEH?EHGGDHGIIIFGHHGGIIHIGGIB;CAHGIHE XA:i:0 MD:Z:51 NM:i:0 DD61XKN1:101:D0EKPACXX:1:1203:9513:150353 0 3R 212 30 51M * 0 0 CAGAATCCTACTAGTACCTGCCTCGAGTCGATCGGGCAGAGAGCGAGAAAT ???DDDDDADB?CBAE:4?+A??EDFEGGGGHGHEG@FHAFHE>DHGIHIGFD>F7@@DCH XA:i:1 MD:Z:4G46 NM:i:1 DD61XKN1:101:D0EKPACXX:1:1302:13211:169414 0 3R 233 29 51M * 0 0 CTCGAGTCGATCGGGCAGAGAGCGAGAAATGGTAAGCAGGTGAGTGAGCGC @@@FBDBDFFHHHIIIGIGIF@@F>DAGBGGIH XA:i:0 MD:Z:51 NM:i:0 DD61XKN1:101:D0EKPACXX:1:2108:3748:138979 0 3R 233 34 51M * 0 0 CTCGAGTCGATCGGGCAGAGAGCGAGAAATGGTAAGCAGGTGAGTGGGATC @@@FDF?DHDHFFI>HGGGIEIDGIBFHIJIF@FICHHIJ@EHIDC(6CCE XA:i:0 MD:Z:46A1C0G1 NM:i:3 DD61XKN1:101:D0EKPACXX:1:1207:13423:102525 16 3R 271 7 51M * 0 0 GGTGAGTGAGCGCAGAGAGCGTCTTTCGACGACTCTTTCGTCGCGAGCAAA BCCC@CADFFDFHHGIGIIIIIGHBDEGDIIHDGGE6JIHGHGHFFFFF@CC XA:i:0 MD:Z:51 NM:i:0 DD61XKN1:101:D0EKPACXX:1:2306:9355:141323 16 3R 278 10 51M * 0 0 GAGCGCAGAGAGCGTCTTTCGACGACTCTTTCGTCGCGAGCAAACAACAAG B;?>>>>>;/8GGFBFHFB?ADD=:@ XA:i:0 MD:Z:1A49 NM:i:1 DD61XKN1:101:D0EKPACXX:1:2208:17627:8790 16 3R 290 11 51M * 0 0 CGTCTTTCGACGACTCTTTCGTCGCGAGCAANCAACAAGTAGACGTCGCTC #C>B?BBABB>?=;>B;ADD@C(;AC XA:i:0 MD:Z:51 NM:i:0 DD61XKN1:101:D0EKPACXX:1:1301:13576:199290 0 3R 298 37 51M * 0 0 GACGACTCTTTCGTCGCGAGCAAACAACAAGTAGACGTCGCTCAGACAGAT ?<@DDAA8?DBB;:2BDDDDDA:??<@:?DDA3B;@DCB?*9*0?6-;''-6-7).?DAD;; XA:i:0 MD:Z:50C0 NM:i:1 DD61XKN1:101:D0EKPACXX:1:2204:8124:34946 16 3R 306 2 51M * 0 0 TTTCGTCGCGAGCAAACAACAAGTAGACGTCACTCAGACACTGTCGGCCAG :EBHGAGABFD?9DJHIIIIGGJJIGHFF<22HEIHGHFHHHHDFFFFC@@ XA:i:1 MD:Z:31G19 NM:i:1 DD61XKN1:101:D0EKPACXX:1:2301:13637:198207 16 3R 306 29 51M * 0 0 TTTCGTCGCGAGCAAACAACAAGTAGACGTCGCTCAGACACTGTCGGCCAG B?;A>EEECIIIIIIIIFIIIIGIHFAGE:GGGEEGEIFFHHAAFFFF@@@ XA:i:0 MD:Z:51 NM:i:0 DD61XKN1:101:D0EKPACXX:1:2303:3102:37681 0 3R 318 28 51M * 0 0 CAAACAACAGGTAGACGTCGCTCAGACACTGTCGGCCAGATTCATTTAGAT ???7DDDDD2:+:AC+<<)@?CD1CDD)1?9:*?D@AGGGBFB?GGF:?8:8<8@8AA=:= XA:i:0 MD:Z:2C2A45 NM:i:2 DD61XKN1:101:D0EKPACXX:1:1307:2511:100728 16 3R 336 23 51M * 0 0 CCGATCTACACTGTCGGCCAGATTCCTTTTCCAGAAAGACGTCGTCGCGTT #######################B0*0B99*D??>DB8?C1@8<8A:41;= XA:i:1 MD:Z:1G0C0T0C0A0G18A25 NM:i:7 DD61XKN1:101:D0EKPACXX:1:2208:19469:21286 0 3R 339 3 51M * 0 0 TCAGACACTGTCGGCCAGANTCATTTTCCAGAAAGACGTCGTCGCGTTGAC @@@DDD8DFFDFFIDF1CF#2AEGFIIF@EB=CD XA:i:1 MD:Z:19T31 NM:i:1 DD61XKN1:101:D0EKPACXX:1:1304:18506:91672 0 3R 361 11 51M * 0 0 ATTTTCCAGAAAGACGTCGTCGCGTTGACAAGCTTAAATTCGTAGCGGGCA @@CD?DBDFHGDFGHICEFC?CFDFBG=@FH@9BFGFCCFFHDHG>:@GHG XA:i:0 MD:Z:51 NM:i:0 DD61XKN1:101:D0EKPACXX:1:2305:19231:72018 0 3R 384 23 51M * 0 0 GTTGACAAGCTTAAATTCGTAGCGGGCGCCAGTAGGACGACCCAGGGGATA @@@D?DD>?DHFHG+A==@'59=(6(39;?? XA:i:0 MD:Z:45T5 NM:i:1 DD61XKN1:101:D0EKPACXX:1:2107:15978:5397 0 3R 389 29 51M * 0 0 CAAGCTTAAATTCGTAGCGGGCGCCAGTAGGACGACCCAGTGGATATCGTC @@@FFBDDHHGHHIDFEGGIJF:F*?GDD:@@FEHDDGE7=??=;CE2=>BC6;@=; XA:i:0 MD:Z:51 NM:i:0 DD61XKN1:101:D0EKPACXX:1:1303:9692:124869 16 3R 400 6 51M * 0 0 CGATCTCGGGCGCCAGTAGGACGACCCAGTGGATATCGTCAGTTGAACCAG ########A?(BBDCFFB??C:CFADD@FDFHDFE@FH6?C9?FGFFFA1)88?BF*BBB(8=CG(;8)7C XA:i:0 MD:Z:45G0A1A2 NM:i:3 DD61XKN1:101:D0EKPACXX:1:1205:3993:177564 16 3R 408 5 51M * 0 0 GGCGCCAGTAGGACGACCCAGTGGATATCGTCAGTTGAACCAGGGGAAACG FF@=D3BB@FD@HDFFEFFCEBHGBF@FCA3CB@CHEAHFH?HDDFFD@@@ XA:i:0 MD:Z:51 NM:i:0 DD61XKN1:101:D0EKPACXX:1:1201:17678:143204 0 3R 413 3 51M * 0 0 CAGTAGGACGACCCAGTGGATATCGTCAGTTGAACCAGGGGAAACGTAGCA @@@DDDD>DCFAFADFBE?D@EBGG?C;@FGCFHHICEGIBHB=@C##### XA:i:0 MD:Z:51 NM:i:0 DD61XKN1:101:D0EKPACXX:1:1204:6403:23100 16 3R 413 4 51M * 0 0 CAGTAGGACAACCCAGTGGATATCGTCAGTTGAACCAGGGGAAACGTAGCA ############DB?????@@?88CC9A:3+4@E;BA+A:BD>DA:=:7?1 XA:i:0 MD:Z:9G41 NM:i:1 DD61XKN1:101:D0EKPACXX:1:2301:11427:64315 16 3R 413 10 51M * 0 0 CAGTAGGACGACCCAGTGGATATCGTCAGTTGAACCAGGGGAAACGTAGCA JHF=IJIGIHGJJJIJJIJHHGIIIHFJJJJJJHJJJIHHHHHFFFFFCCC XA:i:0 MD:Z:51 NM:i:0 DD61XKN1:101:D0EKPACXX:1:1203:4885:175695 0 3R 416 36 51M * 0 0 TAGGACGACCCAGTGGATATCGTCAGTTGAACCAGGGGAAACGTAGCAGCC =?;D?B@@FDF?F+ACGBHGGE??FA?FHEIADDG@<<(6BCH(.=@@;CA XA:i:0 MD:Z:51 NM:i:0 DD61XKN1:101:D0EKPACXX:1:1301:1384:121298 0 3R 416 5 51M * 0 0 TAGGACGACCCAGTGGATATCGTCAGTTGAACCAGGGGAAACGTAGCAGCC CCCFDEFFHHHHHGIIIJIGHIJIJIJJFCHJJJJIJIHIJIJIJJIIIJI XA:i:0 MD:Z:51 NM:i:0 DD61XKN1:101:D0EKPACXX:1:1207:10462:36321 0 3R 418 31 51M * 0 0 GGACGACCCAGTGGATATCGTCAGTTGAACCAGGGGAAACGTAGCAGCCCA @@@DD@DDABDFFGABEDBGCGGBB>FGIJ=8DHE@.@D>B(=CE>FH;;@ XA:i:0 MD:Z:51 NM:i:0 DD61XKN1:101:D0EKPACXX:1:1307:4428:77090 16 3R 418 13 51M * 0 0 GGACGACCCAGTGGATATCGTCAGTTGAACCAGGGGAAACGTAGCAGCCCA =IHHEDGGIGF?BGA?IIGHDFBJJIHIGJJIIJJIGGF@GHDDHGHFFDFF@CC XA:i:0 MD:Z:1A49 NM:i:1 DD61XKN1:101:D0EKPACXX:1:2203:5030:49537 16 3R 424 21 51M * 0 0 CACAGTGGATATCGTCAGTTGAACCAGGGGATACGTAGCAGCCCAGTTACA ##HGFIGHFD;FGBDDHIGIGIIIIGGHFA3+GC<4@?HHHHHDDDDD@@@ XA:i:1 MD:Z:1C29A19 NM:i:2 DD61XKN1:101:D0EKPACXX:1:2202:11507:147190 0 3R 436 24 51M * 0 0 CGTCAGTTGAACCAGGGGANACGTAGCAGCCCAGTTACATTGCTCGGGAGG ??;=A8DDDA?DD>EEE@E#2CC=C=3;A;;0DDD7DDFFEEH)@:@:1?DEH4DCFHGFEH;AA@ XA:i:0 MD:Z:49T0G0 NM:i:2 DD61XKN1:101:D0EKPACXX:1:1203:5003:27314 16 3R 474 36 51M * 0 0 AGTGCTCGGGAGGGGTAAAGAGCTTGACGCCAGCGCGTGCGTAGAGTGAAA ################DF=8G?DHGDGHGHB@AC##### XA:i:0 MD:Z:51 NM:i:0 DD61XKN1:101:D0EKPACXX:1:2303:15856:134002 0 3R 478 2 51M * 0 0 CTCGGGAGGGGTAAAGAGCTTGACGACAGCGCGTGCGTAGAGTGAAAGTAT @@@FFFDFHFH>AEE>CC XA:i:0 MD:Z:51 NM:i:0 DD61XKN1:101:D0EKPACXX:1:2104:6954:171255 0 3R 483 38 51M * 0 0 GAGGGGTAAAGAGCTTGACGACAGCGCGTGCGTAGAGTGAAAGTATGAGAT ==?DDA8DF?D?;:CA?:3<>777A#### XA:i:0 MD:Z:47C0A1G0 NM:i:3 DD61XKN1:101:D0EKPACXX:1:2307:7881:196830 16 3R 493 36 51M * 0 0 TAGCTTGACCACAGCGCGTGCGTAGAGTGAAAGTATGCAAGGAGATTCGCG AFEE>DC;HF;HGGHGGDG@ECG@F?H?HGIIGIIIGBDF>D>DDDDD@?< XA:i:0 MD:Z:0G8G41 NM:i:2 DD61XKN1:101:D0EKPACXX:1:1202:12689:141385 0 3R 496 13 51M * 0 0 CTTGACGACAGCGCGTGCGTAGAGTGAAAGTATGCAAGGAGATTCGCGATC @@@D=D:DD6:?FHE?DFH??GDH9??B?D9BFCFHGEAFEAGGHDHH6=A XA:i:0 MD:Z:51 NM:i:0 DD61XKN1:101:D0EKPACXX:1:2207:10715:109420 0 3R 496 25 51M * 0 0 CTTGACGACAGCGCGTGCGNAGAGTGAAAGTATGCAAGGAGATTCGCGATC @@@DFFFFH?FHFBE1CDB#08?D?FHEEE?FCGGIIGGCGAAA@EEEBCA XA:i:1 MD:Z:19T31 NM:i:1 DD61XKN1:101:D0EKPACXX:1:2204:18234:179424 16 3R 533 5 51M * 0 0 CTAGATTCGCGATCAGAACCTCACGACGCCATATTTGTTTTCCAGGGCTTG #?=-48@6(?*/DDDAB44<;? XA:i:0 MD:Z:0G0G49 NM:i:2 DD61XKN1:101:D0EKPACXX:1:2304:8751:2632 0 3R 556 5 51M * 0 0 CGACGCCATATTTGTTTTCCAGGGCTTGCTTGTGTGTGCGTGTGTTTCAAC CCCFFFFFHGHHHJGIIIJIIIJBHIJIJJJFBADCGHGGCFEGGGIJJIC XA:i:0 MD:Z:51 NM:i:0 DD61XKN1:101:D0EKPACXX:1:2203:1524:184251 0 3R 574 29 51M * 0 0 CCAGGGCTTGCTTGTGTGTGCGTGTGTTTCAACTCCGGTGTGCGAGTGTGA @@@DDDDDHHHHHIG9CFH+3@CEGFHHIIICDGHGIIDFDEGI6F'=;D@ XA:i:0 MD:Z:51 NM:i:0 DD61XKN1:101:D0EKPACXX:1:2102:8875:72443 16 3R 576 40 51M * 0 0 AGGGCTTGCTTGTGTGTGCGTGTGTTTCAACTCCGGTGTGCGAGTGTGAGG EDA@DCGIIIGEGHFHEFB?IIIHG@GIIHAGEGGHEA+BBFGFDFDF@C@ XA:i:1 MD:Z:1G0G35G12 NM:i:3 DD61XKN1:101:D0EKPACXX:1:2101:3407:141094 0 3R 580 17 51M * 0 0 CTTGCTTGTGTGTGCGTGTGTTTCAACTCCGGTGTGCGAGTGTGAGGGCAG 11=DDEFFHHDFCGEHIGFFHIJHGFHIIIIIDEHGEG:(08==BFGG### XA:i:0 MD:Z:51 NM:i:0 DD61XKN1:101:D0EKPACXX:1:2303:12087:40107 0 3R 580 12 51M * 0 0 CTTGCTTGTGTGTGCGTGTGTTTCAACTCCGGTGTGCGAGTGTGAGGGCAA ?@@DDDDDF+IIGGAHGHDGFHDHGFFFFF@@@ XA:i:0 MD:Z:51 NM:i:0 DD61XKN1:101:D0EKPACXX:1:2105:6289:140892 16 3R 581 39 51M * 0 0 CCGATCTTGTGTGCGTTTGTTTCAACTCCGGTGTGCGAGTGTGAGGGCAGG #####@@A8'-7;7?9)BDIEDBDD@?DE?F@@1<+AABDCA??BDD:??? XA:i:0 MD:Z:0T0T1C1T0G9G34 NM:i:6 DD61XKN1:101:D0EKPACXX:1:1103:12128:78055 16 3R 587 7 51M * 0 0 TCGTGTGCGTGTGTTTCAACTCCGGTGTGCGAGTGTGAGGGCAGGGCTTTG #####BEECD?;1 XA:i:0 MD:Z:51 NM:i:0 DD61XKN1:101:D0EKPACXX:1:1104:5082:17741 16 3R 590 8 51M * 0 0 TGTGCGTGTGTTTCAACTCCGGTGTGCGAGTGTGAGGGCAGGGCTTTGCCA AGGIGIIFIJJJIJIIIJJJJJJJJJHIIIIJIJJJJJHHHHHFFFFFCC@ XA:i:0 MD:Z:51 NM:i:0 DD61XKN1:101:D0EKPACXX:1:1302:13170:74786 16 3R 594 18 51M * 0 0 CGTGTGTTTCAACTCCGGTGTGCGAGTGTGAGGGCAGGGCTTTGCCAGGTG 8A?IGGIIGEHGGAGHFHDIHIIIIIJIIEEIIGGHBIF>FFF?FDBD@@? XA:i:0 MD:Z:51 NM:i:0 DD61XKN1:101:D0EKPACXX:1:2307:14759:121417 0 3R 595 10 51M * 0 0 GTGTGTTTCAACTCCGGTGTGCGAGTGTGAGGGCAGGGCTTTGCCAGGTGA =+:BD?DDHIHEHHDDHDDD?D@?@ XA:i:0 MD:Z:51 NM:i:0 DD61XKN1:101:D0EKPACXX:1:1305:6666:159819 0 3R 606 24 51M * 0 0 CTCCGGTGTGCGAGTGTGAGGGCAGGGCTTTGCCAGGTGATAATGCCTTAA @@CFFD@DHHHHHJFED@FHIGGIEHJJJIJJJJJJIBFEEHJIIIIJJJJ XA:i:0 MD:Z:51 NM:i:0 DD61XKN1:101:D0EKPACXX:1:2201:16418:139923 0 3R 607 5 51M * 0 0 TCCGGTGTGCGAGTGTGAGCGCAGGGCTTTGCCAGGTGATAATGCCTTAAC @@@DD?D:FFF??1AFBF@?:)C:*?@ECA+3#E:?<>C?DAF;D???D@@@ XA:i:1 MD:Z:31A19 NM:i:1 DD61XKN1:101:D0EKPACXX:1:2207:2606:158481 16 3R 616 7 51M * 0 0 CGAGTGTGAGGGCAGGGCTTTGCCAGGTGATNATGCCTTAACTGTCCCTTG JIIIJIGIHGJJJJIJJGJJJIIHF9HFFA3#HGFIHBHDHHFDDFFFC@@ XA:i:1 MD:Z:31A19 NM:i:1 DD61XKN1:101:D0EKPACXX:1:1304:7344:178232 0 3R 626 13 51M * 0 0 GGCAGGGCTTTGCCAGGTGATAATGCCTTAACTGTCCCTTGTATTCGGGAG @<@DFFDDFHGFHHGGEBB>AFBH@HGIGIGEGEDGIGGFCB?GDFGIF@6 XA:i:0 MD:Z:49C0T0 NM:i:2 DD61XKN1:101:D0EKPACXX:1:2108:6658:122648 0 3R 628 12 51M * 0 0 CAGGGCTTTGCCAGGTGATAATGCCTTAACTGTCCCTTGTATTCGGGCTAG @@@DEHBAHHGFHE?CGCDGH*?DED>D@BHCG XA:i:0 MD:Z:49T0C0 NM:i:2 DD61XKN1:101:D0EKPACXX:1:2206:14847:13155 0 3R 628 6 51M * 0 0 CAGGGCTTTGCCAGGTGATNATGCCTTAACTGTCCCTTGTATTCGGGCTTC @@CFFFFFHGHFFGGFGGC#3:AFHHGGIJJJGHCGGIGEEGJJJIFIGID XA:i:1 MD:Z:19A31 NM:i:1 DD61XKN1:101:D0EKPACXX:1:1301:9974:152868 16 3R 629 35 51M * 0 0 AGGGCTTTGCCAGGTGATAATGCCTTAACTGTCCCTTGTATTCGGGCTTCG >AHGFIHHGIHCGIICIDB3CIGHFGGGGGGHGJIHHHFBCC?FFDDF@@? XA:i:0 MD:Z:51 NM:i:0 DD61XKN1:101:D0EKPACXX:1:2307:18343:74834 0 3R 636 31 51M * 0 0 TGCCAGGTGATAATGCCTTAACTGTCACTTGTATTCGGGCTTCGTCTTCGC BCCFFFFDFHHHGJJJJJJJIJJJIIIJJJJHIJJJIIIJJJJIGIIJIJF XA:i:1 MD:Z:26C24 NM:i:1 DD61XKN1:101:D0EKPACXX:1:1105:16709:8151 0 3R 638 24 51M * 0 0 CCAGGTGATAATGCCTTAACTGTCCCTTGTATTCGGGCTTCGTCTTCGAGA ??GHFHFFFE9FHI<4CBHIIIEGCFGBDDFDFEII XA:i:0 MD:Z:48C0A1 NM:i:2 DD61XKN1:101:D0EKPACXX:1:1304:21148:23590 16 3R 643 16 51M * 0 0 TGATAATGCCTTAACTGTCCCTTGTATTCGGGCTTCGTCTTCGCAAATTCG >GE@>HGIGIHGGH?GIIIIIGGGFFEGEIHGBDF?HIDFHHDDDDD=@@@ XA:i:0 MD:Z:51 NM:i:0 DD61XKN1:101:D0EKPACXX:1:1304:11733:71752 0 3R 646 4 51M * 0 0 TAATGCCTTAACTGTCCCTTGTATTCGGGCTTCGTCTTCGCAAATTCGAAC @@@DDDDDDHH?F@F?FEHIGEAECECF XA:i:0 MD:Z:51 NM:i:0 DD61XKN1:101:D0EKPACXX:1:1106:13439:157292 16 3R 654 37 51M * 0 0 TAACTGTCCCTTGTATTCGGGCTTCGTCTTCGCAAATTCGAACAACAGTAT C?7(5@==DDBBADBDD0BDD??D?C111C19FEDC3EDD=DDADDBD?:= XA:i:0 MD:Z:51 NM:i:0 DD61XKN1:101:D0EKPACXX:1:1204:5265:178358 0 3R 662 23 51M * 0 0 CCTTGTATTCGGGCTTCGTCTTCGCAAATTCGAACAACAGTATTCTTGATT @@@DD;DDDDHHFIGE@@A1AFEE6?F8DF>BFHGIIB=;B?DH)=BF=B# XA:i:0 MD:Z:51 NM:i:0 DD61XKN1:101:D0EKPACXX:1:1305:16468:51686 0 3R 674 16 51M * 0 0 GCTTCGTCTTCGCAAATTCGAACAACAGTATTCTTGATTGATGCAGTTTTA @@@D?DD;?D?FFIIGHGEHGGHGEIHI*:CAFG@HCH9FADBDHHADFFF@@@ XA:i:0 MD:Z:51 NM:i:0 DD61XKN1:101:D0EKPACXX:1:1302:19769:70993 0 3R 699 16 51M * 0 0 CAGTATTCTTGATTGATGCAGTTTTACAGCGACTTTGTGTGTGCGTATGCT @@@DDDFFHHHHHJJIGIIEIEHIJHHGGHIIIJJJIHIJIHHJIGIIIIG XA:i:0 MD:Z:51 NM:i:0 DD61XKN1:101:D0EKPACXX:1:2106:7819:174823 16 3R 705 26 51M * 0 0 TCTTGATTGATGCAGTTTTACAGCGACTTTGTGTGTGCGTATGCTGTCACC IHCHEGEIIHF>HCGGDIGAGBGGFEHGHGF;GDE?FBCDA>D?AB+D?;= XA:i:0 MD:Z:51 NM:i:0 DD61XKN1:101:D0EKPACXX:1:2106:3249:124995 0 3R 706 11 51M * 0 0 CTTGATTGATGCCGTTTTACAGCGACTTTGTGTGTGCGTATGCTGTCACCA 8=?D+?BDA<>F+FBB<=FIFEFDD?@6:BFDDBFDCC+7CEA3<,>FEC;FBDD:DDB?=;? XA:i:0 MD:Z:51 NM:i:0 DD61XKN1:101:D0EKPACXX:1:2102:19912:17388 16 3R 725 30 51M * 0 0 CAGCGACTTTGTGTGTGCGTATGCTGTCGCCATACTATGTTCGAGTGTGTG GJHEEHFJJJJJIGJJJJJJJJJJJIHF9GCA3FHGJJHHHHHFFFFFCCC XA:i:2 MD:Z:28A3C18 NM:i:2 DD61XKN1:101:D0EKPACXX:1:2202:10607:84579 0 3R 731 15 51M * 0 0 CTTTGTGTGTGCGTATGCTNTCACCACACTATGTTCGAGTGTGTGTGCGCT @CCFFDDDHHHHHIJGIJJ#3ACHHJIGIJIIIJJJJFGCDBGDCGIIEII XA:i:1 MD:Z:19G31 NM:i:1 DD61XKN1:101:D0EKPACXX:1:2206:11281:58120 0 3R 731 12 51M * 0 0 CTTTGTGTGTGCGTATGCTNTCACCACACTATGTTCGAGTGTGTGTGCGCT @@CF1ADEGHHHGIIIIEH#3AAGIJJIJJGIGIIJI?FBFBFGGHIJJJF XA:i:1 MD:Z:19G31 NM:i:1 DD61XKN1:101:D0EKPACXX:1:2205:21060:199305 0 3R 732 1 51M * 0 0 TTTGTGTGTGCGTATGCTGACACAACACTATGTTCGAGTGTGTGTGAGCTT ;??D:B;+CBDEDFFC?BFF@=FFF XA:i:0 MD:Z:33G17 NM:i:1 DD61XKN1:101:D0EKPACXX:1:1205:2404:28940 16 3R 753 23 51M * 0 0 ACCACACTATGTTCGAGTGTGTGTGCGCTCGTGTTTCTGTGAACCCAATCG DC@7=7;=756.(B8/?;?D80:60?:):1D@E:EAAEC4:BD=ADDD8;8 XA:i:0 MD:Z:51 NM:i:0 DD61XKN1:101:D0EKPACXX:1:2302:17950:187885 16 3R 757 9 51M * 0 0 CACTATGTTCGAGTGTGTGTGCGCTCGTGTTTCTGTGAACCCAATCGCGAA ?;D@EEEHEIGEFCIGF::EHDGGGEE9IEJIJJIIIHHFGGFDAFFF@@C XA:i:0 MD:Z:51 NM:i:0 DD61XKN1:101:D0EKPACXX:1:1207:4005:62650 0 3R 763 37 51M * 0 0 GTTCGAGTGTGTGTGCGCTCGTGTTTCTGTGAACCCAATCGCGAACACTGT ;?@A;?D3CCB??<:EEBGGG@ABBAC@DD9FD@?DEBHIIIBHGC?FHI@=AEEH XA:i:0 MD:Z:51 NM:i:0 DD61XKN1:101:D0EKPACXX:1:2306:9443:65280 16 3R 767 17 51M * 0 0 TTTGTTGGGTGCGATGTTGTTTTTGTGAACCCAATCGCGAACACGGTTGTG ###################B?0*0**8BCIIIIIFFEGC+BD??;DDD@@@ XA:i:1 MD:Z:0G0A0G0T0G2T5C1C0G5C21T6 NM:i:11 DD61XKN1:101:D0EKPACXX:1:1307:13797:182614 16 3R 769 16 51M * 0 0 GTGTGTGTGCGCTCGTGTTTCTGTGAACCCAATCGCGAACACTGTTGTGAG BBBEA=HEHHHFEDIGJJIJJIHDGGHIIIGIHJJIGIHBFHGFFDFFCBB XA:i:0 MD:Z:51 NM:i:0 DD61XKN1:101:D0EKPACXX:1:2305:6498:125765 16 3R 770 33 51M * 0 0 TGTGTGTGCGCTCGTGTTTCTGTGAACCCAATCGCGAACACTGTTGTGAGC FFEHEEEGIHFGHD;JIGGFGCIIGDGIJIIEIIDJIGFDHGHFFFFFCCC XA:i:0 MD:Z:51 NM:i:0 DD61XKN1:101:D0EKPACXX:1:1206:9986:159404 16 3R 773 33 51M * 0 0 GTGTGCGCTCGTGTTTCTGTGAACCCAATCGCGAACACTGTTGTGAGCCAG ###########?9B?*BD?9B1D@?1E?)F@DEEEEC+3DADDB=2+;??; XA:i:0 MD:Z:51 NM:i:0 DD61XKN1:101:D0EKPACXX:1:2303:20942:122880 0 3R 774 4 51M * 0 0 TGTGCGCTCGTGTTTCTGTGAACCCAATCGCGAACACTGTTGTGAGCCAGT @@@DDFFFGHFFGIBFFHGGIHB;FHEHGFHIIIG;EGGGHHC= XA:i:0 MD:Z:51 NM:i:0 DD61XKN1:101:D0EKPACXX:1:2203:9722:164274 0 3R 826 6 51M * 0 0 GCTCTGTCTGCGCGGCGAGGAATATCCGCTTACCTAAACGAAAAGTTCTCT ?<@D?BBBB:C?@F)1:67(.8)88=@;CEAGE?;CH@@?BCCB>AC@@;> XA:i:1 MD:Z:19A31 NM:i:1 DD61XKN1:101:D0EKPACXX:1:2107:19883:88206 0 3R 827 39 51M * 0 0 CTCTGTCTGCGCGGCGAGAAATATCCGCTTACCTAAACGAAAAGTTCTCTA C@@FFFFFHHHHHGGEHBGGIICIFHIIJBGEHIGHFHGEDFDEAEDFDDA XA:i:0 MD:Z:51 NM:i:0 DD61XKN1:101:D0EKPACXX:1:1204:2063:176794 0 3R 829 4 51M * 0 0 CTGTCTGCGCGGCGAGAAATATCCGCTTACCTAAACGAAAAGTTCTCTAGC CCCFFFFFFHHFFGGGGGG@DFGGGIJJIJGIGGHHHHFFCDCEACACACC XA:i:0 MD:Z:51 NM:i:0 DD61XKN1:101:D0EKPACXX:1:1105:19061:44291 0 3R 833 38 51M * 0 0 CTGCGCGGCGAGAAATATCCGCTTACCTAAACGAACAGTTCTCTAGCGTCG @@@DBDFFHHFDD6;DFIEHGIIIIIIIF))7;-?',;;@CCEE(>CB@BD XA:i:0 MD:Z:35A15 NM:i:1 DD61XKN1:101:D0EKPACXX:1:1207:10060:109372 0 3R 841 6 51M * 0 0 CGAGAAATATCCGCTTACCTAAACGAAAAGTTCTCTAGCGTCGGCCGACGC @CCFFFFFDDFHBEHHBGGIJJ@GEGGGDCDGGGGEF@AGHIIIGIIBH## XA:i:0 MD:Z:51 NM:i:0 DD61XKN1:101:D0EKPACXX:1:2206:11225:132530 0 3R 842 8 51M * 0 0 GAGAAATATCCGATTACCTNAACGAAAAGTTCTCTAGCGTCGGCCGACGCA ;??DFFDBFHFD+AEEHGG#3AFBGGIGGIGEAFGHBE>?FHBGEGIHE>9 XA:i:2 MD:Z:12C6A31 NM:i:2 DD61XKN1:101:D0EKPACXX:1:2102:6645:61102 16 3R 845 15 51M * 0 0 AAATATCCGCTTACCTAAACGAAAAGTTCTCTAGCGTCGGCCGACGCACGG #FDDDCFDHEEHAHEAEHHBGJJIHHGGDGGFIGIIGJHHGHHFFFDD@@@ XA:i:0 MD:Z:51 NM:i:0 DD61XKN1:101:D0EKPACXX:1:1204:16871:43292 16 3R 852 36 51M * 0 0 CGCTTCCCTAAACGAAAAGTTCTCTAGCGTCGGCCGACCCACGGCACCCAG ######DD?;7.A?EED@C9CC=AB07?80?)CC8A11)?ADDAA=?D??? XA:i:1 MD:Z:5A32G12 NM:i:2 DD61XKN1:101:D0EKPACXX:1:1201:12030:7462 16 3R 858 16 51M * 0 0 CCTAAACGAAAAGTTCTCTAGCGTCGGCCGACGCACGGCACCCAGGCACAC >;;DCAA>FFDDECCC?8EEGA>GBIIFHFEGEE@DFFC?;CFE@7CA@73@-'EFGFFBGE?;A<3#@GC;IIFFBA==:DDD;?? XA:i:1 MD:Z:17C13C19 NM:i:2 DD61XKN1:101:D0EKPACXX:1:1106:1847:178079 16 3R 873 22 51M * 0 0 CTCTAGCGTCGGCCGACGCACGGCACCCAGGCACACACACAGCCACATTTG >C?BBCEHGA>HBGFDHEFDGEG@CGHH>DC@CCGHCBBDACHGIIIIGEE XA:i:2 MD:Z:0A18T31 NM:i:2 DD61XKN1:101:D0EKPACXX:1:1105:19632:149442 16 3R 905 21 51M * 0 0 ACACACACAGCCACATTTGCAGAAATACCACTACATACGAAACGAACGTGG 9;BB9F;EGGHDBDDDD@@? XA:i:0 MD:Z:51 NM:i:0 DD61XKN1:101:D0EKPACXX:1:2205:7552:113912 16 3R 923 24 51M * 0 0 GCAGAAATACCACTACATACGAAACGAACGTGGCCAGCACACAAGCGAAAC JJJIEIGGBGEIIGHIHGHJHHIIIGEGC<33JIIHAHBFDHDFFFFFCC@ XA:i:0 MD:Z:51 NM:i:0 DD61XKN1:101:D0EKPACXX:1:2106:3808:44443 16 3R 952 36 51M * 0 0 GTGGCCAGCACACAAGCGAAACCGGAAAATCCACATTTTTTAGACCTGCTC ;IGHDGF9D;D?GCIDGHAGGGGEIGHHGAEEAFF:EIHDFA3A:B1=?=; XA:i:0 MD:Z:51 NM:i:0 DD61XKN1:101:D0EKPACXX:1:1303:14193:51530 16 3R 967 13 51M * 0 0 GCGAAACCGGAAAATCCACATTTTTTAGACCTGCTCTCTGTCCCGCGTCTC ###BDB:FAECFEC7;=.==6IIIFF?092?0869?9??:):FD?AAA=:1 XA:i:0 MD:Z:51 NM:i:0 DD61XKN1:101:D0EKPACXX:1:1302:9341:73955 16 3R 993 3 51M * 0 0 AGACCTGCTCTCTGTCCCGCGTCTCTCATCTCTTTTCATTACGCTCTCGAC ##########?;1;'GHF?8??:C?:3?<91B@IHF?1;B?FBD?DDD??? XA:i:0 MD:Z:51 NM:i:0 DD61XKN1:101:D0EKPACXX:1:1307:16416:121526 16 3R 995 8 51M * 0 0 CGATCTTCTCTGTCCCGCGTCTCTCATCTCTTTTCATTACGCTCTCGACTG #############IG@@?31?*D<@EGE=CHHHC9+1:@>@x 3Rchr_cigarxc` S|f5؃}P}p} 4xcd  |-f5؋ >h$@4& xc`P  A<4bh$@d&deepTools-2.5.0/deeptools/test/test_data/testA_offset20_-4.bw0000640000201600010240000000134313061773504023174 0ustar ryanbioinfo&X0l?P@P@x 3Rchr_cigarxc`  ˡ|=j3 z+T|+'xcd  e|-f5؃h 8և#:h$@4))xc`P  N ̈Szh$@p&deepTools-2.5.0/deeptools/test/test_data/testA_skipNAs.bw0000640000201600010240000004537112757050136022625 0ustar ryanbioinfo&X0KP,22?@i@r@x 3Rchr_cigarxc```H {.xcd#`B$1h$d2d2xc```H@ < !r'XE#32@H'z=X @h$dKPdK6xc```HPO80#x ygh$dK2dK2)&deepTools-2.5.0/deeptools/test/test_data/testB.bam0000640000201600010240000000150612757050136021315 0ustar ryanbioinfoBC]?BAM(@HD VN:1.0 SO:unsorted @SQ SN:3R LN:200 3R0f?BCR2* I2DD61XKN1:101:D0EKPACXX:1:1108:19948:91754 (HB"!!DD"('''%#())'$))))))))()'''())((&&)(&('%&%%!''%%%%%""XACMDZ50NMCd*I2DD61XKN1:101:D0EKPACXX:1:2102:10665:57593 "(HHB!H(D!"""%%%%%#''%%'&$%&'"""%'&$&&$!'&" "%"&&'# #'()&XACMDZ43A7NMC)I2DD61XKN1:101:D0EKPACXX:1:2107:3608:70379 HBB$(AA""("""#%%%%''''')'())))(())))&(()'()())())))))))))()(XACMDZ50NMC*(I2DD61XKN1:101:D0EKPACXX:1:1204:8617:170017 BB$(AA""($"####%!%%#$'#!'''%%&"&% &#&&%!&(&&(((%#XACMDZ50NMCut6BCdeepTools-2.5.0/deeptools/test/test_data/testB.bam.bai0000640000201600010240000000014012757050136022040 0ustar ryanbioinfoBAII^FJ^F^deepTools-2.5.0/deeptools/test/test_data/testB.bw0000640000201600010240000003111112757050136021161 0ustar ryanbioinfo&X0 ?@r@@x3Rxc` ipyCh$xc`P`0͙A6h$ &deepTools-2.5.0/deeptools/test/test_data/testB.sam0000640000201600010240000000143112757050136021333 0ustar ryanbioinfo@HD VN:1.0 SO:unsorted @SQ SN:3R LN:200 DD61XKN1:101:D0EKPACXX:1:1108:19948:91754 16 3R 51 10 50M * 0 0 ATAGTCCTGTAAGCCCTATAAACATATGTACATAGGTAGGCCAGTACTTA HHHFDIJJHEJJJJJJJJIJHHHIJJIIGGJIGIHF>GFFBHHFFFFFCC XA:i:0 MD:Z:50 NM:i:0 DD61XKN1:101:D0EKPACXX:1:2102:10665:57593 0 3R 101 20 50M * 0 0 TAAGCCCTATAAACATATGTACATAGGTAGGCCAGTACTTAGTGCTGGCA CCCFFFFFDHHFFHGFBFFDEHD>?BHHH9FGGFBGIGGIII@@FD XA:i:0 MD:Z:50 NM:i:0 deepTools-2.5.0/deeptools/test/test_data/testB_skipNAs.bw0000640000201600010240000003111612757050136022616 0ustar ryanbioinfo&X0,?@i@r@x3Rxc```0 5OC;P{#h$22 xc```0@<쁄3P4h$22 &deepTools-2.5.0/deeptools/test/test_data/test_filtering.bam0000640000201600010240000002765112757050136023267 0ustar ryanbioinfoBCWsred``pp 23 *+/*IMr 2Jp13qVY@@BC4/}M+v9>y}mWcWEDqy‘xR2a@1@ 1@!Ƒ yL"!eD D ( 1Unws}yyztSׯ^IijRYWZ+Ҕ:Iup"x$~jon 6I,7,'*|\N's|A,#LYyLFΉrl#&} `}qgs[5"b 8,bV$؟֦4R' >}-W˞i.%!'G(P T EVJBim Op<*q4 PMCQJQȂKxGZ?*x>Jid/1i,i^)s `omaoE$h/~ψZDa+A 'i<W`:Wk]-_,҂Jɹ)5*7OIRCO9aڂM٬,87`uR9/U(G( m@Ɓ(@TKﰩ Ke` fE^fd 6BX0!HL@@8@* B /1߮U(mlAq ,:fGZƵjRPA# ?F ]8(#ܩmtx&IVDQ ;%XZ[p9!*В3؝.D` 4d@H 6?$$xUK@l&(<+WZoN K >w~{>̿RBWBSK}~tLÏh}xBo=6mox:ƨ(䋅 - e5xBC=2 G5X$:mqXNO*:lၭn^v_0JE>9S4}W0o˨"Q{QE1l% Vs PMB Ppk#8r }O<Æ L2,)jyJX+0t" *KFwԕ׿`G6I9{z^~Q{ao2<%%^%.BM#62!et zQviRiS%(sW.e%_5\]ba20H֡|S U!:k$tݞ$M5?`$/ 򳆅"^Y9|RLӶwW,r5I ۃ:9 2Iƨ**fvyjG$DCe>`aFd"fP 6-B_&Zο mO:pI&iVVpŚ?`& L!UPv-GhlxG  :Cuf*tbk#cQ1"pG?AۚUy)yZuCof`nGhTZ5*Kk-EZƞe9 7?TI!'I갌ʚG}/=' `8~ Fj-PhlqO ^O%&)2n/l\Y}Ԁտz#@&Wې* L]c93&xn^2E _d ,&`ps1%{!٦f#ؠ}u*,dEuΞi7Q>)~恛ܔЈ(ԌY0]HeTմ4YCqt:kK5xvlܿ܏](WMy0`I`H7W _-Z)p"/+~L (hr`-U:b GwGefEu^6fX.]UV+k6nMxߴ 1Z2MєyQ~Q߉G\Vu/` ;Gbv{ F*VCIG(߰9lR^>B$o~|M%vw&ߜs@~grCTw1e ߚHj5ش~?T% ˬԗ>~ J|xbsⲑɆJAM_lϝ?~ mP }qO죜ov5HhB߹p.%Bf`9'BHO=E?:-_i02S(T ܭ=ϟE!WTr~,k쐡3tȘM}2L,'OzB*%$q^ŭ 7>9@I>$G1szCh(PbTq\c0~ia0૓bZ,k~k>EΫ#{BwLىU7*PrMuK1AO4>H>VZ-K+Q>Fړ8|QEO<=~?#mø RN6r"10:=.a2PeMv&$y}!uAi{9Efy\ \%k.XOu ]oxEt:]p%.3I!T̵Mq9˲rZwX+Ѫﮰ`4{erc3$:Ig>Ѿhʇ;vT+yA$?fY#BH)H7S=ʿmeLx':~Z`"0\qv~>ہ]Yk}&&{rЖTaʺry` pbKckD{n+yaR$.%%?xE4dm{y>!|鋞G=ir&s0ҁB)uB#.!rz5o"ط}\:mᔬO8}ez[)t90"q " kM!3:uF{5eL9vDeR!?6C꾽9KNVX y@FI1m5o>9#F6I,L|6YJ6«]a!s~6Ep7bwޏ<Ağ~vZi_ZeEr깦Z0Kp ލ !;~z/+ރy{y>hISxa>s`Ń@`'x4Mq'4fixb+ `4P9U.gv;7Wc-g^OGCi% !d pU`+wU ؟y}|B:ˊ|(m<_0*/8V @ d`~]s)u_9-Q`'NbqXlS LCw`+ d M§~0؟}µ7S:|+{pNM<;w?}KO4[%,u8VLxU"THtރ UiÑm'iwIO09F0Tق*MMR]>M2MjPmېXkZ(2.]Qb4Z;>)ki2 &OP}3&o `=;B\ LP{ { dW5o=,TZyIqVO1Ԅ/DCfa8(fSg؎BS`CvؗJIKR@'EhxP.Upז+Y-4Oo^0c٢˚5a 5;&Qu~FX#.P웭yCXi+Y靖LpbH_ q% %99*wI8|:X8EiCuc^Օ$ak ԡNH^I@%!|vO޾>%q1+43c{X+UŘ +M06`것 `<k ¿EжzM,7{j(Q!1.jƴ* z." aS_zd^"9vsTqusV.deSZ^thpR`ѫ#?@]Jze w$ޛ hL,At-qIZ V$=8lz聑2-[_*=0]\e_S؃z6'_N =if8JCChJ\FLi!]]Bru ]K6.:_t!$7cog7nnnn`~z]lww!O,n(E{b0׋;^7.2"tjyP S#9iz:>aR*%Ӣ4EaV=Ӿu`TF@MMYbXkgmn٤{e~ZS&@d"`Q4AMTE5?zkkmo5Xl:jH'// ) gw"gWWK543@@xYODue{W Mln! v* /^jΤK GiVʹf J8K& x:lv F zaQ3Enw 5]뷾+?`oSڵ ,Oj:up$B}k25J`&!zOe(pkn̥D#Դ]W:YVz.`-j\ϗ0]|35p b `w}1p]k}N){o,e&DP[}w/nFC _]}p//<I~o>qplSc@n j68YC뷟tC<yݲ>.\i1pB!P~f8oƝ}#Wj(vib<ڸGuwbPUQ~|e$Gg+EP.c610}ƻ!޺$C(ĸ;נ~p1oqɉ*1-q/OA)>dk8M)&q]< ñO>q\dIКAvsICd~4I&1.+pP}oI:}DtI 5F R8#`Xsކjm\$Xi֣*z,0y<#ͪ|~<(휐2|<˳9:X ,0t Ƙ 6h8g@?uHZe'8"oT.æ_8kQVá'<ւc @Zd":'ԃ2A8nFWu@%1L&',1Ywff5?>^CSW28}Y)A^kr A@#B8ǂ'C}1wNd3=Sx`#C .8a⎷ZI3c5udIGvQD;3Ylre>N_FlZ21OQqv v evQDqI րHٻ96q@h Wxp`lᙏ r[OږT\6MKP5`(mFU]ɐskڅ"RV*+Y+>q\VB2=POdh9{q'1l4OҲqLhxfQ%NW8*.r )!y53 hfqUa.WjaXr̃h3/mڟC7Q(:^b;a>Z`biR3-'izKbS^ϟ`!e:ž$ G.{xB)S#8Í>8sr$)njn|)f0SdfiNMeQT a#':6Dh8-Ĝ˿iX<+M}bӢI4<1_RDV=D3:E$%Fxi\bk:'1TtH3\V{W4[xn2~"-ݵO5 vzd{ǐf Mq{} 5h=fg +!Ehy7Aan)ΪT|v ߬u,o2)l4gqsNP&YGOt5<eIeI&9U>tQLy~Ǩ-m!6Jn1bP\,Ie8[ܜ مKU_({=m>N"?,ڟ`l& yNC@6[[,RzX&z(yȰs#{~vǫٴMi؋vtCX2%&L4qOnvz_`[6u~#*{[/GYH+fY!{֐WN=UX9-+OQKwgVVl/+g"v\% 8,GDWc|pd-E{ڙa1&@q9?.pܨޱa#c@T]-#j&wkNTl1-g]ʠۋfϵWli@V^mݥu?4 C :<|0 bF(GH`@f6[` &_HدwNG{Z:SjښDj- }"/ O(~/`|;q:󁰩%؛@m۰I'K'pV_4A\O3oidg^g',%M˴>a#P|w@/pE]kl.]zAh(0JUr|\tdW ¯T(<&Pb@qjx${SSoͤc;-}!Uk8 w^R1ۋ>yRt wtC\gަx on j.w C nJ?CP̘Y|ys Yeta]VfWpGܡDMT@nƵ/B n\W9+LE`$iW0ګ*1*rb Z:ol Vw:{^i=_Gx];@jF`x]s^`RV&,qu ځ nCLUcCփv 1|N:$(N3.պz<(Iͧ].(`лk[@3p۱hA<0E*ύm1)xqM3 / ]A[3ۦ_m)Pr cԋ^s3sk ]^pua9~`n׹t nS7 '}Z%b>adŒgjLrV5avq_T0 t,\L]D=(i83 HpgFܑlכM_#U#'cLanwjd)=zKf*U KƹT;=tH. \8Sy;,ji>XꜲrӨ1L^|@ ƿq3>@<Z(6lʲt6$ͬf\7va܍/?]A./χyGqaݽq1|{6OfG"0ɴ@?,lx;w,L 4X/ qƔ0cf?2MIu!0+2=^[>0W Yf<-ʤ!@-n/lVS[^ʲ0lH\vs!#=E2RN=lоz6ml1:UQA1{= F42w*0.v†oNQ2Op!K(~ެ7J-ZE+~^Z4;P97gЧ_! LuGGkT7M^%pzx-Bb5Qս-pܲa{M&R \̩~GB?攲DRfi,=uk]DVw?ߚ[ &ϑޜ02Qp 'n/ZvT BAh׮xC`E۽q?&o?r]A: NyT<^:z笭փ̆tQ\A h-|Y$`j y` |=!c"%zc>f7Z,BYF)JB!pXµjD>j0['m N30} <`ebF&)8}?QT愧83Ÿdq}_s',Wqmo,lda7^۫Bvu\>[j޷Q\l"FfJʖ$2owP@< fsx'w5WoҶpH: ~ `Xb AX,#l2;)IKO.6 &#$ ooN1eų<-ͧ"^o|k+Yp{[tq,=NQ[{.'~\\ ۻ uiCqOi h?McGΥG0,/z'ad&q>}϶wP'P *3͕Cl^(ڮ+em=J¹]uDc}8a=|oMڂ"&9FBCdeepTools-2.5.0/deeptools/test/test_data/test_filtering.bam.bai0000640000201600010240000000014012757050136024001 0ustar ryanbioinfoBAIIX/JX/XdeepTools-2.5.0/deeptools/test/test_data/test_filtering.blacklist.bed0000640000201600010240000000001312757050136025210 0ustar ryanbioinfo3R 800 900 deepTools-2.5.0/deeptools/test/test_data/test_filtering2.bam0000640000201600010240000001455512757050136023350 0ustar ryanbioinfoBCWsred``pp 23 *+/*IMr 2Jp13qVY@@BC\M#Y$y?cW**qU.1# H#6,` +`lɰ"$ EB !;ĆM @BbElXݪv5{#W|?Z)ѣꢟ׳>,q\-^|g|9OeGn;lMNg/5 pFiύ/1ZhM&u0Ti_0ƭ>4yϾx &2Y,&"ɧlwo:+vvv-x{EQhQu#W8 GqGf#R{ldiVF̍_9uT$8$D&БC( ++mRU|i g `gӬ ➯9Z\xݴJqF12rFo!Ø^OR[c-,e[M/gy*+=W݊nnD׈n>~ =a4zÐ8>N=@7ĊC5YgIL8-HZ|RCJGj5 ehxHA_%oFw lXv1OӒo{a'bC.:> C|+.ށRfЇhY6@2/f|UIQʽ޵xaJiۋ3k `hBNfet>)R1A6{2xUQPPPk-<20Θ |v&a 4x\5c6*ՓJi;b9gA$-gd=bup!W]~5D\Ş A+ #:ߥ</ypݮnC}eq(0Pt)I DƵ]\gҋ9%΢:_o^XBbPQ@E,/A“<hy*V@5H_J- r nAJ.  7xA5x2؅EFgng[٨B;Ѻ+:\ 8_@z a IL(sU`M&c҆lϳٴ*&Au:UΚ\]޻^0xON t/ {V 8fʒL6rF@\9LpEBɃPo*ԟ'y))xWn[v-V]u?}.\blDv{嘈A_&"-]M/5F3RΧ$tɬ2Aa'N(Btm砷 NX 3)Xj#ā9/p te*>"YI3$/Cmúw:CtZv8y U{8~Hwk0hk`ե UοM'S*EُmN\g>7i.X(t5TBzTjH~ 13]DDi2ʮvu{(q]2Ξ "1ٗp>H^okèyu0'}nY팛)LQ+OGbg%vɤL^ T7w~U&ӗ")RBj &O7S>)P֭[T}GvE4iWxH2ژ."@A`Eb+'Z6 $ͩMQdLK؁UhxmO(䃒tQ>g+.$jB )1<! ^??._%wJL2Ǖyl4MbUF)Ф^ԁaBHµaln{t46P=8?az(τ$heOd,El*2lB~.*o٪SRp!'IiX=kuRCqצu-9W52{8y`B|/|Qn\o:nw 6rǴ=}9?\*?`#]8 ׈sOȸqz,]Njڬ6R/ymttctq?Q|gj=:E v+o#6[qXzt^o{(]dRv _vV܇{FK2aCUD6PǓo'~[f/)}jZf BEP5vdm64,6b9e#|1pc!9ݖm)DiRUvZ5o?"6Y{ɷW}ݏ z@jsxL%ҭ/=%CżQpI>^|^Hews̮Q4Td,hKÌ\n9['Ծew1)[H{Ԛ6 ۹C,$P#l_l0fCd.,̓P?toY T|aHV4;3MK$ _4)=Z+޻EIjTP,aڜ^1[E"Rvs]wk6}y2%jޥ鬚 Rj80kZ)MSVpZIe<ɧg<VtJC"x\8qCFsrN9 XGQx(4U˭z&tv|M]n޵N+ ަ⒙aꈁ'u _%}XjMKjry0{8Gԝ1SfMRҳ111,1e+cĻUNG ʇPרP'VrW[zxF]kwy7GѲjzoUć Hw9W!D!n`].BLHJ3. W:ߡ^4f4zS2ai^꾣u֙oF){(&!&+fǕ߽IM$O6ҎߎDDͮnWOؕ\>I&.t$}.YboFQiz)|`+ _|Wh7kzlRFj%00Tga3mNml>_T392۾Bk>͝ q (՛:. T(FTۚ.vgAǘw</mf*-y &iVnXw;o嶣;ng+ݿz^<̓2 1(&ፊwj{|JV؎&^ִ;N{tƪ"U)A\ymlL f=N[BBKYXhZ='G߀W,yk35秤l2X5y-U,ݮ6zRCS8R)a=$>h \'}%eޓSkd.Ҵ KAhp$hZVtﴂPzn K D㥶O>hIlH9{sW\]鸇7"FP(4/wc|?2>;׶O.:_y|I>%;+볇ӵf5+Wpn@MNw~ꯩoMiVGĎ#;fcH8"hu|&0]i+A鎋d^nf(m~gƱ^-z? e(/"Zs?Zx9l:CQLqafTP-'zηY.VWw]t\}rs/&Wy2FxYy > wx_lOy"$<[TvHrv88xfלl>ґC;w"=BQ%X,.SR?nssq/08R6Sk PSD>eph~o%hBBCdeepTools-2.5.0/deeptools/test/test_data/test_filtering2.bam.bai0000640000201600010240000000014012757050136024063 0ustar ryanbioinfoBAIIXmJXmaXdeepTools-2.5.0/deeptools/test/test_data/test_paired.bam0000640000201600010240000000446212757050136022543 0ustar ryanbioinfoBC\srec``pp 23 *+/*IMr J(22504.FV 30ܣ%GBCVǽ[RaDž#;< 1؞10ޮVkVR ("ٺ,^*P 6Pl)BG?4yx;h47}9sZsս^e}Ǻh{{~x˲o|_~$<[YlGM-|۲duKO>r^dQ1P8kF]cL0N$̺ïguyYh+ lCr#yOnn$, BȒ4^(~]DV*v};|'vGx(P(oQ,.y,ѴE)JΑ7^帵WBPQf;{wlJΣ<"n_Wy+ȇԽ8JߌU1[ʥx5k VdY&dYyqjHn)喖Yad ,ϓ4(iajH["+IM uΕsL<߱,{( :LfQϒ0dt)`bMK*F4alVf\AQJG6+#6w&w 2j97BEQ(\9beL(9z;0HD9˽࠘p%8lQl4+dz][ʪBp{|44 ݍ H|d T˶헕[ץkGܗ])+3+cU\cU(R&:k #e1Ӷl+?W1~2%QAfE6GO$x?rv#\"v9oAroO$]Ӵ SeB) wj0\nveLY9 AB)e66.gsϯKqŋ(xF׍cN X^OEB/tJ9Ftzt(ᶖDupMҲy](ˋwֻc%'PMA]Cϥ䄗#=a5gfx%iY,\tw !PIET5R{W3* WA`IIR5!"`M a4`f_π*߶s,[f,EN<,Pʨta>ꡠgC 0@uga4jg.T3\P,gi됹6b4jeE5AL þan1ɵ(ih;rE/TcG=l( av b $_ͮ^i={ݻE,~G&=j:u'K=FHq/jY>6dZܾ7F1.i'*DZB~")a,j)a-}!IsZУ%S /-'~[?5t,S08λZRٲ7+i)7mD,aMOEpR6]ep-BB¸}VcqpX{lӼy| QgC1G5Iؖ 8\ae_LSO3+,HpXt^4z.%M*J _I?7@-m]mRR6QҨ!{8`a5§neeG޻>i<6gfxn]]@uJҫs&W < ^@[˧w^f0_vյ]QnjA5pn:pI&LXNdo]lBCdeepTools-2.5.0/deeptools/test/test_data/test_paired.bam.bai0000640000201600010240000000475012757050136023275 0ustar ryanbioinfoBAIz]2 J]2 12]deepTools-2.5.0/deeptools/test/test_data/test_paired.sam0000640000201600010240000001777012757050136022572 0ustar ryanbioinfo@HD VN:1.0 SO:unsorted @SQ SN:chr2 LN:5010000 HWUSI-EAS616:7:89:1518:3543#0 99 chr2 5000027 255 36M = 5000355 364 TGTAACAATTTACTTGATTGTTCTCAAGGATGTGAT S\dbdcfaaccbbcccc^dcdc^c^YaaabaaWdaa XA:i:0 MD:Z:36 NM:i:0 HWUSI-EAS616:7:23:12543:6958#0 83 chr2 5000081 255 36M = 4999776 -341 CTTTGTTGTTCTCCTGTCCATTTCTCACAAAGCTGG hhhhhhhghfhhfhhhhhhfhhhhhhhhhhhhhhhh XA:i:0 MD:Z:36 NM:i:0 HWUSI-EAS616:7:6:10857:18740#0 83 chr2 5000191 255 36M = 4999866 -361 GTTAGGGGCAATCCTGATTCACAGTTAGCTTCTTAG ggggggggegggggggffcfdgggggggggggdggg XA:i:0 MD:Z:36 NM:i:0 HWUSI-EAS616:7:93:7807:15274#0 163 chr2 5000304 255 36M = 5000676 408 GAGAGGGAGAGGGAGAGGGAGAATGAAGCAGGAATG hhhhhhhhhehhhhhhhhhehhhhghhhfhhhfghh XA:i:0 MD:Z:36 NM:i:0 HWUSI-EAS616:7:89:1518:3543#0 147 chr2 5000355 255 36M = 5000027 -364 AGGTCATCAGGCTGGAATTTCAGGTAAGAATTACCA R]bT]`eRd^db]baY`W_W^_\]\_XZUZVVNVHU XA:i:1 MD:Z:34A1 NM:i:1 HWUSI-EAS616:7:21:17769:5446#0 163 chr2 5000385 255 36M = 5000496 147 TTACAATTGATGTCTGGACTCCAAATCCCTCAAGTG hhhhhhghhhhhhhhhhhhhhfhhhhhhhhhgghdh XA:i:0 MD:Z:36 NM:i:0 HWUSI-EAS616:7:49:8992:4457#0 99 chr2 5000385 255 36M = 5000496 147 TTACAATTGATGTCTGGACTCCAAATCCCTCAAGTG de\dc\fffdf^cdfe\cff_ffffffdafgcgggg XA:i:0 MD:Z:36 NM:i:0 HWUSI-EAS616:7:21:17769:5446#0 83 chr2 5000496 255 36M = 5000385 -147 TACTCTCAAAGCTTTCAAATGAAAGGACCCACACAC ghhahhgghhdffccfhhhhhhhghhdfffffdfff XA:i:0 MD:Z:36 NM:i:0 HWUSI-EAS616:7:49:8992:4457#0 147 chr2 5000496 255 36M = 5000385 -147 TACTCTCAAAGCTTTCAAATGAAAGGACCCACACAC hehhhhgghhgchhghfhhfafhhffhhhhhfdfff XA:i:0 MD:Z:36 NM:i:0 HWUSI-EAS616:7:86:18020:6752#0 99 chr2 5000560 255 36M = 5000906 382 AACACCAATCACATAAAGAATGTGTCTCCACAGAAG hhgahhhhhghfhhhhhghhhh_cghfhhfhchghh XA:i:0 MD:Z:36 NM:i:0 HWUSI-EAS616:7:93:7807:15274#0 83 chr2 5000676 255 36M = 5000304 -408 AAAACTTATCAGTTTTTAAAGGTTACTGAGGGCTTG hhhghhhhhghhhhhhghhhghhhhhhhdhghhhhh XA:i:0 MD:Z:36 NM:i:0 HWUSI-EAS616:7:64:3102:21101#0 99 chr2 5000737 255 36M = 5001136 435 TTGAGGTCAACCTGGGTTACATGGCAAGACCTTGGT hhhhhhghhhhhhhhhfhhhhhhhhhhhghhhhhgf XA:i:0 MD:Z:36 NM:i:0 HWUSI-EAS616:7:36:16424:18394#0 163 chr2 5000820 255 36M = 5001193 409 TGAAAAGGCATACGGAGCAGCTGATGTTTCTCCAAC hhhhhhhghhhhhhhhhfghghhfhgdhhgehhhhh XA:i:0 MD:Z:36 NM:i:0 HWUSI-EAS616:7:50:18110:21009#0 163 chr2 5000822 255 36M = 5001123 337 AAAAGGCATACGGAGCAGCTGATGTTTCTCCAACAT ffffccafacfffcfahffdfaffc`a`^`ddfdh] XA:i:0 MD:Z:36 NM:i:0 HWUSI-EAS616:7:111:14171:9899#0 163 chr2 5000822 255 36M = 5001123 337 AAAAGGCATACGGAGCAGCTGATGTTTCTCCAACAT hhhhhhhhhhhhhhhhghhhhhgefhhhhhhhhhgh XA:i:0 MD:Z:36 NM:i:0 HWUSI-EAS616:7:114:18552:5841#0 163 chr2 5000822 255 36M = 5001123 337 AAAAGGCATACGGAGCAGCTGATGTTTCTCCAACAT hhhhhhhhhhhhhhghehhhhhhhhhhhfhhhhhhh XA:i:0 MD:Z:36 NM:i:0 HWUSI-EAS616:7:8:2829:6484#0 99 chr2 5000835 255 36M = 5001214 415 AGCAGCTGATGTTTCTCCAACATCATCCTGGTGTGG hhhfhhhghhhhhhghhhhchghhghhhghhghhhh XA:i:1 MD:Z:28C7 NM:i:1 HWUSI-EAS616:7:4:16767:6127#0 163 chr2 5000856 255 36M = 5001242 422 ATCATCCTGGTGTGGGGAGGTAGAGGCAGAGGATCA hhghhhhhhc^edeec__]_cfccfdfffW_fdad_ XA:i:1 MD:Z:7C28 NM:i:1 HWUSI-EAS616:7:66:4289:12506#0 99 chr2 5000868 255 36M = 5001183 351 TGGGGAGGTAGAGGCAGAGGATCAGGAGTTCATGTT hhhhhhhhdhhghghggghhehhhhhehehfhhhfh XA:i:0 MD:Z:36 NM:i:0 HWUSI-EAS616:7:86:18020:6752#0 147 chr2 5000906 255 36M = 5000560 -382 CCCCTAGCTTTATGCTGTCCATGGTTCATCATCTCT hchhfdhghhfghfahhhhhhhhfhhhhhhhghheh XA:i:0 MD:Z:36 NM:i:0 HWUSI-EAS616:7:23:8152:13433#0 163 chr2 5000926 255 36M = 5000988 98 ATGGTTCATCATCTCTTATGGCCCATATTAGTCATT hhhhhhhhhhhhhhhhhhhghhhhhhehhhhhhehh XA:i:0 MD:Z:36 NM:i:0 HWUSI-EAS616:7:103:13675:10395#0 163 chr2 5000926 255 36M = 5000988 98 ATGGTTCATCATCTCTTATGGCCCATATTAGTCATT ffffahhhhfffgfhffh]f]fddfd_fffdcfff\ XA:i:0 MD:Z:36 NM:i:0 HWUSI-EAS616:7:106:13391:17723#0 163 chr2 5000938 255 36M = 5001303 401 CTCTTATGGCCCATATTAGTCATTGTGCCATTCAAA hhhhhhhhhhhhhhhhhhhghhghhehhhhhhhhhh XA:i:0 MD:Z:36 NM:i:0 HWUSI-EAS616:7:23:8152:13433#0 83 chr2 5000988 255 36M = 5000926 -98 AGAAACATGTTTCACAGCTCCTACTGTATCCTGGAC hhhhghghhhhhhehhhgdhhhhhhghhhhhhhhhh XA:i:0 MD:Z:36 NM:i:0 HWUSI-EAS616:7:103:13675:10395#0 83 chr2 5000988 255 36M = 5000926 -98 AGAAACATGTTTCACAGCTCCTACTGTATCCTGGAC f_ffcfdddcaV`XZa[dadcaWcadddaccd[fcf XA:i:0 MD:Z:36 NM:i:0 HWUSI-EAS616:7:116:8653:16765#0 99 chr2 5001011 255 36M = 5001141 166 CTGTATCCTGGACCCTAGGGATGCAACAGTGGCAAG hhghghhhhfhhhhhhhhhhffhhhhgghghfhfhh XA:i:0 MD:Z:36 NM:i:0 HWUSI-EAS616:7:81:1971:19006#0 99 chr2 5001026 255 36M = 5001396 406 TAGGGATGCAATAGTGGCAAGATGTGGTTTCTGCTC hhhhhhhhhhhghfhhhhhhghhhhhhghhhhhghd XA:i:1 MD:Z:11C24 NM:i:1 HWUSI-EAS616:7:39:11820:4528#0 163 chr2 5001051 255 36M = 5001401 386 GGTTTCTGCTCTTCATTGTGAGCTGACTTGGCTGAG hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh XA:i:0 MD:Z:36 NM:i:0 HWUSI-EAS616:7:25:4767:20646#0 163 chr2 5001115 255 36M = 5001378 299 TCAGAGAGGATAACGTAAGGTAACTCAGAGATATGC ghhfhhcaahe^d`ebfddc^ad`dada[cVb`^^c XA:i:0 MD:Z:36 NM:i:0 HWUSI-EAS616:7:2:14523:20268#0 163 chr2 5001116 255 36M = 5001234 154 CAGAGAGGATAACGTAAGGTAACTCAGAGATATGCA ghghhhhhfgchghcecfchhchhhghchchehhhh XA:i:0 MD:Z:36 NM:i:0 HWUSI-EAS616:7:79:5441:2939#0 163 chr2 5001116 255 36M = 5001234 154 CAGAGAGGATAACGTAAGGTAACTCAGAGATATGCA ghcghfhhhchhhffffaffffacffa_f[fafcaf XA:i:0 MD:Z:36 NM:i:0 HWUSI-EAS616:7:50:18110:21009#0 83 chr2 5001123 255 36M = 5000822 -337 GATAACGTAAGGTAACTCAGAGATATGCACAGGAAG \Z_aa^XY^aa\aaaa\^S^cd^dddYccffb\f_f XA:i:0 MD:Z:36 NM:i:0 HWUSI-EAS616:7:111:14171:9899#0 83 chr2 5001123 255 36M = 5000822 -337 GATAACGTAAGGTAACTCAGAGATATGCACAGGAAG hhghhhhhhhhhhhhhhhhhhhhghhhhhhhhhhhh XA:i:0 MD:Z:36 NM:i:0 HWUSI-EAS616:7:114:18552:5841#0 83 chr2 5001123 255 36M = 5000822 -337 GATAACGTAAGGTAACTCAGAGATATGCACAGGAAG hhhhhhghhhhgghhhhhhhhhhhhhhhhhhhhhhh XA:i:0 MD:Z:36 NM:i:0 HWUSI-EAS616:7:64:3102:21101#0 147 chr2 5001136 255 36M = 5000737 -435 AACTCAGAGATATGCACAGGAAGTTGCATATTTGCA afghhhhgghgehghghhhhhhhhhhfhhhhhhhhh XA:i:0 MD:Z:36 NM:i:0 HWUSI-EAS616:7:116:8653:16765#0 147 chr2 5001141 255 36M = 5001011 -166 AGAGATATGCACAGGAAGTTGCATATTTGCAATAAA hhhhhhhhhgghhhhhhhhhhhhhhhhhhhhhhhhh XA:i:0 MD:Z:36 NM:i:0 HWUSI-EAS616:7:66:4289:12506#0 147 chr2 5001183 255 36M = 5000868 -351 CACAGCAGAACTATTAGATCCAGGCACTCACTCAAC hghhhhfffcfddfbdhhhfhhhhhghhhhhhhhhh XA:i:0 MD:Z:36 NM:i:0 HWUSI-EAS616:7:36:16424:18394#0 83 chr2 5001193 255 36M = 5000820 -409 CTATTAGATCCAGGCACTCACTCAACGTGGATTCTG dbddcbfhehhehffdghhghhggghhhhhhhhhhh XA:i:0 MD:Z:36 NM:i:0 HWUSI-EAS616:7:8:2829:6484#0 147 chr2 5001214 255 36M = 5000835 -415 TCAACGTGGATTCTGGGCTCTTCAGCTCTGATCTCT ghhhhhfhhhhhhhhhhhhhhhhhhhhhghhfhhgg XA:i:0 MD:Z:36 NM:i:0 HWUSI-EAS616:7:3:9592:15607#0 163 chr2 5001227 255 36M = 5001568 377 TGGGCTCTTCAGCTCTGATCTCTTTAGCTCTGATTT hhhehhhhhhhhhhfhhhhghghhhhhhhhhhhhgh XA:i:2 MD:Z:24C6C4 NM:i:2 HWUSI-EAS616:7:2:14523:20268#0 83 chr2 5001234 255 36M = 5001116 -154 TTCAGCTCTGATCTCTTCAGCTCTCATTTGCTCAGA aagggggffgaffafcafeafaggcgaggcgfeggg XA:i:0 MD:Z:36 NM:i:0 HWUSI-EAS616:7:79:5441:2939#0 83 chr2 5001234 255 36M = 5001116 -154 TTCAGCTCTGATCTCTTCGGCTCTCATTTGCTCAGA gdd`baWfafedd`ae`dKadfcfffaaffdfffff XA:i:1 MD:Z:18A17 NM:i:1 HWUSI-EAS616:7:4:16767:6127#0 83 chr2 5001242 255 36M = 5000856 -422 TGATCTCTTTAGCTCTGATTTGCTCAGACTGTCTAT fggfggaffffcefgaffddf_^ggggeggfgcgdg XA:i:2 MD:Z:9C6C19 NM:i:2 HWUSI-EAS616:7:106:13391:17723#0 83 chr2 5001303 255 36M = 5000938 -401 GTCTGCAGTCAACTGGCAGTCCCTCTCAGGGAAAAT hhhhhhhhhghghhhhhhhhhghhhfhhhhhhhhhh XA:i:0 MD:Z:36 NM:i:0 HWUSI-EAS616:7:25:4767:20646#0 83 chr2 5001378 255 36M = 5001115 -299 GAAAGTGCTCTTTGTCAGACTAAGACCTTTTAATTT gffff_ggaggfaffca^_a\ffd`afgcggggggg XA:i:0 MD:Z:36 NM:i:0 HWUSI-EAS616:7:81:1971:19006#0 147 chr2 5001396 255 36M = 5001026 -406 ACTAAGACCTTTTAATTTGTCCCATTTTAATAGTAC hhhhhhghhhhhhhhhhhhhhhhhhhhhhhhhhhhh XA:i:0 MD:Z:36 NM:i:0 HWUSI-EAS616:7:39:11820:4528#0 83 chr2 5001401 255 36M = 5001051 -386 GACCTTTTAATTTGTCCCATTTTAATAGTACATATG hhhhhhhhghhhhhhhhhghhhhhghhhhhhhhhhh XA:i:0 MD:Z:36 NM:i:0 HWUSI-EAS616:7:29:12313:10611#0 0 chr2 5001492 255 36M * 0 0 AATTGTAAGACCCCCGAAACTGGGGAGACCTCCGCT fd]aeecaaWcdfd_ffffcZ[aaa_\Z]`Z^Z___ XA:i:0 MD:Z:36 NM:i:0 HWUSI-EAS616:7:39:11820:45288#0 16 chr2 5001701 255 36M * 0 0 GACCTTTTAATTTGTCCCATTTTAATAGTACATATG hhhhhhhhghhhhhhhhhghhhhhghhhhhhhhhhh XA:i:0 MD:Z:36 NM:i:0 deepTools-2.5.0/deeptools/test/test_data/test_paired2.bam0000640000201600010240000000432112757050136022617 0ustar ryanbioinfoBC\srec``pp 23 *+/*IMr J(22504.FV 30ܣ%GBCWKVkf ;^8B EKX*eDOF@4!, Xl];G@Ilg1Yd6%لEМ].4oU/9_\|n-9|]]~ C7L4NR7pt/b!+h*GڲqE # )%•1hFcL0Ưhb yk QttDE%+hLnz.Ywңr5W\OʃqWnR͑e:ϱtFw+RP0GYCB!L뤗EGCd123B}\#K ;ro$]VdVeB){U5;v >7B9n YG6 Oxi3p}$u,t^b!*Eeɻ*P]-j^̢!w,/޽\7GQ(jrlT;\JNxE8"F86x9?;yIs~WS,k*:L}OM ^ɦR{W۞Dhʆ,whSI\ڼ09D,apY<͓L9PۋNc]~~*I]hPeVF}i>gCqWkI) (siՀ߅Pp+Bo@FS+z+3()jWwgTE֟5s&HaBI#DkǔԔy(.G<gCi7`(vQSbC+X ջwݻ߇d an]gqJ8t,nSЩYF0BE;ψ0KׅLI"D"ےԀu'i"N4:ebveԚ|΍a;qj[JhH$'ǀ9*ڲ,R+ζMIeO18ԡf;HҀ첌QA1m@1y+/UAEeJ`ЋTwTsUP J.!n%俐op8)|K_D Eth5<7#Hw"&1΢8x;d,js Z TshG9leܹQbьt:օl = jC3gm#} nUDX0c9^Y(ʇhs5j 5c_<+9Y>ȢƼY4#4!pԈ#^f~$8{Y>dZܾ?G.i'%kDZBq")/a,j)f-q!IpZ7У%S$/[s{⧚.&AhYC꺩-Gҡ-rVB}({NQʆ4ˡP#0V -88,=(hѾ >{hh =I؎ 80߱/a&x)Tb>J/j``.%M4*J-S:I?@-噒?т]QQCtTޥCp8* '=ʎbt>i<֤g6.(dme:Me7R%/T9p \}vCMQkˁ\1Ƶxx -0.1 TSS 0.1Kb 0.2 0.6 1.0 1.4 test -0.1 TSS 0.1Kb test -0.1 TSS 0.1Kb test -0.1 TSS 0.1Kb test group1.bed group2.bed group1.bed -0.1 TSS 0.1Kb gene distance (bp) group2.bed 1 2 3 4 -0.1 TSS 0.1Kb gene distance (bp) 0 2 4 -0.1 TSS 0.1Kb gene distance (bp) 1 2 3 4 -0.1 TSS 0.1Kb gene distance (bp) 0 2 4 deepTools-2.5.0/deeptools/test/test_heatmapper/heatmap_master_multi_colormap_no_box.svg0000640000201600010240000040660513067414642031167 0ustar ryanbioinfo -0.1 TSS 0.1Kb 0.2 0.6 1.0 1.4 test -0.1 TSS 0.1Kb test -0.1 TSS 0.1Kb test -0.1 TSS 0.1Kb test group1.bed group2.bed group1.bed -0.1 TSS 0.1Kb gene distance (bp) group2.bed 0 1 2 3 -0.1 TSS 0.1Kb gene distance (bp) 0 1 2 3 -0.1 TSS 0.1Kb gene distance (bp) 0 1 2 3 -0.1 TSS 0.1Kb gene distance (bp) 0 1 2 3 deepTools-2.5.0/deeptools/test/test_heatmapper/heatmap_master_multi_pergroup.svg0000640000201600010240000030465513067414642027654 0ustar ryanbioinfo -0.1 TSS 0.1Kb 0.2 0.6 1.0 1.4 group1.bed -0.1 TSS 0.1Kb group2.bed file1 file2 file3 file4 file1 file2 file3 -0.1 TSS 0.1Kb group1.bed file4 -0.1 TSS 0.1Kb group2.bed 0.0 0.3 0.6 0.9 1.2 1.5 1.8 2.1 2.4 2.7 3.0 deepTools-2.5.0/deeptools/test/test_heatmapper/make_test_data.sh0000640000201600010240000000520212757050136024266 0ustar ryanbioinfocomputeMatrix reference-point -a 100 -b 100 -S test.bw -R test2.bed -o master.mat.gz -bs 1 # unzip but keep original gz file. gunzip -c master.mat.gz > master.mat # test referencePoint center computeMatrix reference-point -a 100 -b 100 --referencePoint center -S test.bw -R test2.bed -o master_center.mat.gz -bs 1 # unzip but keep original gz file. gunzip master_center.mat.gz # test referencePoint TES computeMatrix reference-point -a 100 -b 100 --referencePoint center -S test.bw -R test2.bed -o master_TES.mat.gz -bs 1 # unzip but keep original gz file. gunzip master_center_TES.mat.gz computeMatrix reference-point -R test2.bed -S test.bw -b 100 -a 100 --outFileName master_nan_to_zero.mat.gz -bs 1 -p 1 --missingDataAsZero gunzip -c master_nan_to_zero.mat.gz > master_nan_to_zero.mat computeMatrix scale-regions -a 100 -b 100 -m 100 -S test.bw -R test2.bed -o master_scale_reg.mat.gz -bs 1 -p 1 gunzip -c master_scale_reg.mat.gz > master_scale_reg.mat plotHeatmap -m master.mat.gz --outFileName master.svg plotHeatmap -m master.mat.gz --outFileName master_relabeled.svg --regionsLabel uno dos plotHeatmap -m master_scale_reg.mat.gz --outFileName master_scale_reg.svg plotProfile -m master.mat.gz --outFileName profile_master.svg --regionsLabel uno dos --plotType std plotProfile -m master.mat.gz --outFileName profile_master_heatmap.svg --plotType heatmap # for tests with multiple bigwigs and multiple beds computeMatrix reference-point -R group1.bed group2.bed -S test.bw -b 100 -a 100 --outFileName master_multibed.mat.gz -bs 1 -p 1 gunzip -c master_multibed.mat.gz > master_multibed.mat computeMatrix reference-point -R group1.bed group2.bed -S test.bw -b 100 -a 500 --outFileName master_extend_beyond_chr_size.mat.gz -bs 1 -p 1 gunzip -c master_extend_beyond_chr_size.mat.gz > master_extend_beyond_chr_size.mat computeMatrix reference-point -R group1.bed group2.bed -S test.bw test.bw test.bw test.bw -o master_multi.mat.gz -a 100 -b 100 -bs 1 plotHeatmap -m master_multi.mat.gz --perGroup --outFileName heatmap_master_multi_pergroup.svg --samplesLabel file1 file2 file3 file4 plotHeatmap -m master_multi.mat.gz --colorList 'white,blue' 'white, red' --zMin 1 0 --zMax 4 5 -o heatmap_master_multi_color.svg plotHeatmap -m master_multi.mat.gz --colorMap Reds binary terrain --boxAroundHeatmaps no -o heatmap_master_multi_colormap_no_box.svg plotProfile -m master.mat.gz --outFileName profile_master_overlap_lines.svg --plotType overlapped_lines --yMin -1 plotProfile -m master_multi.mat.gz --outFileName profile_master_multi.svg --numPlotsPerRow 2 --yMax 1.5 plotProfile -m master_multi.mat.gz --outFileName profile_master_multi_pergroup.svg --perGroup --yMax 1.5 deepTools-2.5.0/deeptools/test/test_heatmapper/master.mat0000640000201600010240000002560413006372703022766 0ustar ryanbioinfo@{"verbose":true,"scale":1,"skip zeros":false,"nan after end":false,"sort using":"mean","unscaled 5 prime":0,"body":0,"sample_labels":["test"],"downstream":100,"unscaled 3 prime":0,"group_labels":["Group 1","Group 2"],"bin size":1,"upstream":100,"group_boundaries":[0,3,6],"sample_boundaries":[0,200],"missing data as zero":false,"ref point":"TSS","min threshold":null,"sort regions":"keep","proc number":1,"bin avg type":"mean","max threshold":null} ch1 100 150 CG11023 0.0 + 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 ch2 150 175 cda5 0.0 - 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 ch3 100 125 cda8 0.0 + 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 ch1 75 125 C11023 0.0 + nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 ch2 125 150 ca5 0.0 - 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 ch3 75 100 ca8 0.0 + nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 deepTools-2.5.0/deeptools/test/test_heatmapper/master.mat.gz0000640000201600010240000000075013006372703023400 0ustar ryanbioinfoWmaster.matj0S]dŧ[)E'-I'}ݒ Pm2_4h4f* C$yf`T!:fgn"XHc`8\"3Xd>`qw$ 6¤ŦG "YYeI)5 Drwp30P<1|q2.D s[+deepTools-2.5.0/deeptools/test/test_heatmapper/master.svg0000640000201600010240000011736113067414642023014 0ustar ryanbioinfo -0.1 TSS 0.1Kb 0.2 0.6 1.0 1.4 test Group 1 Group 2 Group 1 -0.1 TSS 0.1Kb gene distance (bp) Group 2 0.0 0.3 0.6 0.9 1.2 1.5 1.8 2.1 2.4 2.7 3.0 deepTools-2.5.0/deeptools/test/test_heatmapper/master.tab0000640000201600010240000001512612757050136022756 0ustar ryanbioinfo#bin No. Group 1 mean std Group 2 -100 0.0 0.0 0.0 0.0 -99 0.0 0.0 0.0 0.0 -98 0.0 0.0 0.0 0.0 -97 0.0 0.0 0.0 0.0 -96 0.0 0.0 0.0 0.0 -95 0.0 0.0 0.0 0.0 -94 0.0 0.0 0.0 0.0 -93 0.0 0.0 0.0 0.0 -92 0.0 0.0 0.0 0.0 -91 0.0 0.0 0.0 0.0 -90 0.0 0.0 0.0 0.0 -89 0.0 0.0 0.0 0.0 -88 0.0 0.0 0.0 0.0 -87 0.0 0.0 0.0 0.0 -86 0.0 0.0 0.0 0.0 -85 0.0 0.0 0.0 0.0 -84 0.0 0.0 0.0 0.0 -83 0.0 0.0 0.0 0.0 -82 0.0 0.0 0.0 0.0 -81 0.0 0.0 0.0 0.0 -80 0.0 0.0 0.0 0.0 -79 0.0 0.0 0.0 0.0 -78 0.0 0.0 0.0 0.0 -77 0.0 0.0 0.0 0.0 -76 0.0 0.0 0.0 0.0 -75 0.0 0.0 0.0 0.0 -74 0.0 0.0 0.0 0.0 -73 0.0 0.0 0.0 0.0 -72 0.0 0.0 0.0 0.0 -71 0.0 0.0 0.0 0.0 -70 0.0 0.0 0.0 0.0 -69 0.0 0.0 0.0 0.0 -68 0.0 0.0 0.0 0.0 -67 0.0 0.0 0.0 0.0 -66 0.0 0.0 0.0 0.0 -65 0.0 0.0 0.0 0.0 -64 0.0 0.0 0.0 0.0 -63 0.0 0.0 0.0 0.0 -62 0.0 0.0 0.0 0.0 -61 0.0 0.0 0.0 0.0 -60 0.0 0.0 0.0 0.0 -59 0.0 0.0 0.0 0.0 -58 0.0 0.0 0.0 0.0 -57 0.0 0.0 0.0 0.0 -56 0.0 0.0 0.0 0.0 -55 0.0 0.0 0.0 0.0 -54 0.0 0.0 0.0 0.0 -53 0.0 0.0 0.0 0.0 -52 0.0 0.0 0.0 0.0 -51 0.0 0.0 0.0 0.0 -50 1.0 1.41421356237 0.0 0.0 -49 1.0 1.41421356237 0.0 0.0 -48 1.0 1.41421356237 0.0 0.0 -47 1.0 1.41421356237 0.0 0.0 -46 1.0 1.41421356237 0.0 0.0 -45 1.0 1.41421356237 0.0 0.0 -44 1.0 1.41421356237 0.0 0.0 -43 1.0 1.41421356237 0.0 0.0 -42 1.0 1.41421356237 0.0 0.0 -41 1.0 1.41421356237 0.0 0.0 -40 1.0 1.41421356237 0.0 0.0 -39 1.0 1.41421356237 0.0 0.0 -38 1.0 1.41421356237 0.0 0.0 -37 1.0 1.41421356237 0.0 0.0 -36 1.0 1.41421356237 0.0 0.0 -35 1.0 1.41421356237 0.0 0.0 -34 1.0 1.41421356237 0.0 0.0 -33 1.0 1.41421356237 0.0 0.0 -32 1.0 1.41421356237 0.0 0.0 -31 1.0 1.41421356237 0.0 0.0 -30 1.0 1.41421356237 0.0 0.0 -29 1.0 1.41421356237 0.0 0.0 -28 1.0 1.41421356237 0.0 0.0 -27 1.0 1.41421356237 0.0 0.0 -26 1.0 1.41421356237 0.0 0.0 -25 0.0 0.0 1.33333333333 1.24721912892 -24 0.0 0.0 1.33333333333 1.24721912892 -23 0.0 0.0 1.33333333333 1.24721912892 -22 0.0 0.0 1.33333333333 1.24721912892 -21 0.0 0.0 1.33333333333 1.24721912892 -20 0.0 0.0 1.33333333333 1.24721912892 -19 0.0 0.0 1.33333333333 1.24721912892 -18 0.0 0.0 1.33333333333 1.24721912892 -17 0.0 0.0 1.33333333333 1.24721912892 -16 0.0 0.0 1.33333333333 1.24721912892 -15 0.0 0.0 1.33333333333 1.24721912892 -14 0.0 0.0 1.33333333333 1.24721912892 -13 0.0 0.0 1.33333333333 1.24721912892 -12 0.0 0.0 1.33333333333 1.24721912892 -11 0.0 0.0 1.33333333333 1.24721912892 -10 0.0 0.0 1.33333333333 1.24721912892 -9 0.0 0.0 1.33333333333 1.24721912892 -8 0.0 0.0 1.33333333333 1.24721912892 -7 0.0 0.0 1.33333333333 1.24721912892 -6 0.0 0.0 1.33333333333 1.24721912892 -5 0.0 0.0 1.33333333333 1.24721912892 -4 0.0 0.0 1.33333333333 1.24721912892 -3 0.0 0.0 1.33333333333 1.24721912892 -2 0.0 0.0 1.33333333333 1.24721912892 -1 0.0 0.0 1.33333333333 1.24721912892 0 1.0 0.816496580928 0.0 0.0 1 1.0 0.816496580928 0.0 0.0 2 1.0 0.816496580928 0.0 0.0 3 1.0 0.816496580928 0.0 0.0 4 1.0 0.816496580928 0.0 0.0 5 1.0 0.816496580928 0.0 0.0 6 1.0 0.816496580928 0.0 0.0 7 1.0 0.816496580928 0.0 0.0 8 1.0 0.816496580928 0.0 0.0 9 1.0 0.816496580928 0.0 0.0 10 1.0 0.816496580928 0.0 0.0 11 1.0 0.816496580928 0.0 0.0 12 1.0 0.816496580928 0.0 0.0 13 1.0 0.816496580928 0.0 0.0 14 1.0 0.816496580928 0.0 0.0 15 1.0 0.816496580928 0.0 0.0 16 1.0 0.816496580928 0.0 0.0 17 1.0 0.816496580928 0.0 0.0 18 1.0 0.816496580928 0.0 0.0 19 1.0 0.816496580928 0.0 0.0 20 1.0 0.816496580928 0.0 0.0 21 1.0 0.816496580928 0.0 0.0 22 1.0 0.816496580928 0.0 0.0 23 1.0 0.816496580928 0.0 0.0 24 1.0 0.816496580928 0.0 0.0 25 0.0 0.0 0.666666666667 0.942809041582 26 0.0 0.0 0.666666666667 0.942809041582 27 0.0 0.0 0.666666666667 0.942809041582 28 0.0 0.0 0.666666666667 0.942809041582 29 0.0 0.0 0.666666666667 0.942809041582 30 0.0 0.0 0.666666666667 0.942809041582 31 0.0 0.0 0.666666666667 0.942809041582 32 0.0 0.0 0.666666666667 0.942809041582 33 0.0 0.0 0.666666666667 0.942809041582 34 0.0 0.0 0.666666666667 0.942809041582 35 0.0 0.0 0.666666666667 0.942809041582 36 0.0 0.0 0.666666666667 0.942809041582 37 0.0 0.0 0.666666666667 0.942809041582 38 0.0 0.0 0.666666666667 0.942809041582 39 0.0 0.0 0.666666666667 0.942809041582 40 0.0 0.0 0.666666666667 0.942809041582 41 0.0 0.0 0.666666666667 0.942809041582 42 0.0 0.0 0.666666666667 0.942809041582 43 0.0 0.0 0.666666666667 0.942809041582 44 0.0 0.0 0.666666666667 0.942809041582 45 0.0 0.0 0.666666666667 0.942809041582 46 0.0 0.0 0.666666666667 0.942809041582 47 0.0 0.0 0.666666666667 0.942809041582 48 0.0 0.0 0.666666666667 0.942809041582 49 0.0 0.0 0.666666666667 0.942809041582 50 0.333333333333 0.471404520791 0.0 0.0 51 0.333333333333 0.471404520791 0.0 0.0 52 0.333333333333 0.471404520791 0.0 0.0 53 0.333333333333 0.471404520791 0.0 0.0 54 0.333333333333 0.471404520791 0.0 0.0 55 0.333333333333 0.471404520791 0.0 0.0 56 0.333333333333 0.471404520791 0.0 0.0 57 0.333333333333 0.471404520791 0.0 0.0 58 0.333333333333 0.471404520791 0.0 0.0 59 0.333333333333 0.471404520791 0.0 0.0 60 0.333333333333 0.471404520791 0.0 0.0 61 0.333333333333 0.471404520791 0.0 0.0 62 0.333333333333 0.471404520791 0.0 0.0 63 0.333333333333 0.471404520791 0.0 0.0 64 0.333333333333 0.471404520791 0.0 0.0 65 0.333333333333 0.471404520791 0.0 0.0 66 0.333333333333 0.471404520791 0.0 0.0 67 0.333333333333 0.471404520791 0.0 0.0 68 0.333333333333 0.471404520791 0.0 0.0 69 0.333333333333 0.471404520791 0.0 0.0 70 0.333333333333 0.471404520791 0.0 0.0 71 0.333333333333 0.471404520791 0.0 0.0 72 0.333333333333 0.471404520791 0.0 0.0 73 0.333333333333 0.471404520791 0.0 0.0 74 0.333333333333 0.471404520791 0.0 0.0 75 0.0 0.0 1.33333333333 1.24721912892 76 0.0 0.0 1.33333333333 1.24721912892 77 0.0 0.0 1.33333333333 1.24721912892 78 0.0 0.0 1.33333333333 1.24721912892 79 0.0 0.0 1.33333333333 1.24721912892 80 0.0 0.0 1.33333333333 1.24721912892 81 0.0 0.0 1.33333333333 1.24721912892 82 0.0 0.0 1.33333333333 1.24721912892 83 0.0 0.0 1.33333333333 1.24721912892 84 0.0 0.0 1.33333333333 1.24721912892 85 0.0 0.0 1.33333333333 1.24721912892 86 0.0 0.0 1.33333333333 1.24721912892 87 0.0 0.0 1.33333333333 1.24721912892 88 0.0 0.0 1.33333333333 1.24721912892 89 0.0 0.0 1.33333333333 1.24721912892 90 0.0 0.0 1.33333333333 1.24721912892 91 0.0 0.0 1.33333333333 1.24721912892 92 0.0 0.0 1.33333333333 1.24721912892 93 0.0 0.0 1.33333333333 1.24721912892 94 0.0 0.0 1.33333333333 1.24721912892 95 0.0 0.0 1.33333333333 1.24721912892 96 0.0 0.0 1.33333333333 1.24721912892 97 0.0 0.0 1.33333333333 1.24721912892 98 0.0 0.0 1.33333333333 1.24721912892 99 0.0 0.0 1.33333333333 1.24721912892 deepTools-2.5.0/deeptools/test/test_heatmapper/master_TES.mat0000640000201600010240000002617613006372703023506 0ustar ryanbioinfo@{"verbose":true,"scale":1,"skip zeros":false,"nan after end":false,"sort using":"mean","unscaled 5 prime":0,"body":0,"sample_labels":["test"],"downstream":100,"unscaled 3 prime":0,"group_labels":["Group 1","Group 2"],"bin size":1,"upstream":100,"group_boundaries":[0,3,6],"sample_boundaries":[0,200],"missing data as zero":false,"ref point":"TES","min threshold":null,"sort regions":"keep","proc number":1,"bin avg type":"mean","max threshold":null} ch1 100 150 CG11023 0.0 + 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 ch2 150 175 cda5 0.0 - 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 ch3 100 125 cda8 0.0 + 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 ch1 75 125 C11023 0.0 + 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 ch2 125 150 ca5 0.0 - 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 ch3 75 100 ca8 0.0 + 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 deepTools-2.5.0/deeptools/test/test_heatmapper/master_center.mat0000640000201600010240000002610013006372704024317 0ustar ryanbioinfo@{"verbose":true,"scale":1,"skip zeros":false,"nan after end":false,"sort using":"mean","unscaled 5 prime":0,"body":0,"sample_labels":["test"],"downstream":100,"unscaled 3 prime":0,"group_labels":["Group 1","Group 2"],"bin size":1,"upstream":100,"group_boundaries":[0,3,6],"sample_boundaries":[0,200],"missing data as zero":false,"ref point":"center","min threshold":null,"sort regions":"keep","proc number":1,"bin avg type":"mean","max threshold":null} ch1 100 150 CG11023 0.0 + 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 ch2 150 175 cda5 0.0 - 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 ch3 100 125 cda8 0.0 + 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 ch1 75 125 C11023 0.0 + 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 ch2 125 150 ca5 0.0 - 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 ch3 75 100 ca8 0.0 + nan nan nan nan nan nan nan nan nan nan nan nan nan 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 deepTools-2.5.0/deeptools/test/test_heatmapper/master_extend_beyond_chr_size.mat0000640000201600010240000006202513006372704027562 0ustar ryanbioinfo@{"verbose":true,"scale":1,"skip zeros":false,"nan after end":false,"sort using":"mean","unscaled 5 prime":0,"body":0,"sample_labels":["test"],"downstream":500,"unscaled 3 prime":0,"group_labels":["group1.bed","group2.bed"],"bin size":1,"upstream":100,"group_boundaries":[0,3,6],"sample_boundaries":[0,600],"missing data as zero":false,"ref point":"TSS","min threshold":null,"sort regions":"keep","proc number":1,"bin avg type":"mean","max threshold":null} ch1 100 150 CG11023 0.0 + 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan ch2 150 175 cda5 0.0 - 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan ch3 100 125 cda8 0.0 + 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan ch1 75 125 C11023 0.0 + nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan ch2 125 150 ca5 0.0 - 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan ch3 75 100 ca8 0.0 + nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan deepTools-2.5.0/deeptools/test/test_heatmapper/master_gtf.mat0000640000201600010240000000653113006372704023625 0ustar ryanbioinfo@{"verbose":true,"scale":1,"skip zeros":false,"nan after end":false,"sort using":"mean","unscaled 5 prime":20,"body":1000,"sample_labels":["test1.bw"],"downstream":300,"unscaled 3 prime":50,"group_labels":["genes"],"bin size":10,"upstream":500,"group_boundaries":[0,2],"sample_boundaries":[0,187],"missing data as zero":false,"ref point":null,"min threshold":null,"sort regions":"keep","proc number":1,"bin avg type":"mean","max threshold":null} 3R 0 1000 first . + nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan 4.000000 4.000000 5.644444 7.700000 7.700000 8.610000 9.000000 9.000000 12.000000 12.000000 12.833333 14.500000 14.500000 15.366667 15.800000 15.800000 21.700001 21.700001 24.550001 31.200001 31.200001 31.920001 32.400002 32.400002 32.400002 32.400002 33.044445 35.299999 35.299999 35.355556 35.400002 35.400002 35.311111 35.299999 35.233333 34.700001 34.700001 32.655556 30.100000 30.100000 25.900001 24.700001 24.711112 24.799999 24.799999 25.920000 27.600000 27.600000 28.790000 29.299999 29.299999 28.000000 28.000000 27.866667 27.600000 27.600000 28.333334 28.700001 28.700001 29.200001 29.200001 29.050001 28.700001 28.700001 29.977778 31.000000 31.000000 27.800000 27.400000 26.422222 23.000000 23.000000 22.222222 21.600000 21.600000 25.200000 26.100000 27.544445 39.099998 39.099998 40.211110 41.599998 41.599998 40.900000 40.700001 40.130001 35.000000 35.000000 34.920000 34.799999 34.799999 35.920001 36.400002 36.400002 42.200001 42.200001 40.800001 38.000000 38.000000 29.066667 24.600000 24.600000 20.400000 20.400000 18.700000 17.000000 17.000000 16.700001 16.700001 15.450000 14.200000 14.200000 11.000000 11.000000 7.850000 4.700000 4.700000 2.500000 2.500000 1.350000 0.200000 0.200000 nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan 3R 99 1100 second . - nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan 0.200000 0.200000 1.350000 2.500000 2.500000 4.700000 4.700000 7.850000 11.000000 11.000000 13.560000 14.200000 14.477778 16.700001 16.700001 16.833334 17.000000 17.000000 19.644444 20.400000 20.866666 24.600000 24.600000 29.960000 38.000000 38.000000 40.940001 42.200001 42.200001 36.400002 36.400002 35.866667 34.799999 34.799999 34.933333 35.000000 35.000000 40.700001 40.700001 40.970000 41.599998 41.599998 40.099998 39.099998 39.099998 27.400000 26.100000 25.100000 21.600000 21.600000 22.377778 23.000000 23.000000 26.911111 27.400000 28.120000 31.000000 31.000000 29.850000 28.700001 28.700001 29.100001 29.200001 29.144445 28.700001 28.700001 28.211112 27.600000 27.600000 27.911111 28.000000 28.130000 29.299999 29.299999 28.620000 27.600000 27.600000 25.640000 24.799999 24.799999 24.700001 24.700001 26.500001 30.100000 30.100000 33.166667 34.700001 34.700001 35.299999 35.299999 35.330000 35.400002 35.400002 35.344445 35.299999 35.299999 32.722223 32.400002 32.400002 32.400002 32.400002 31.733334 31.200001 31.200001 22.755556 21.700001 21.044445 15.800000 15.800000 15.020000 14.500000 14.250000 12.000000 12.000000 10.200000 9.000000 8.870000 7.700000 7.700000 5.480000 4.000000 4.000000 nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan deepTools-2.5.0/deeptools/test/test_heatmapper/master_metagene.mat0000640000201600010240000000654513006372704024637 0ustar ryanbioinfo@{"verbose":true,"scale":1,"skip zeros":false,"nan after end":false,"sort using":"mean","unscaled 5 prime":20,"body":1000,"sample_labels":["test1.bw"],"downstream":300,"unscaled 3 prime":50,"group_labels":["genes"],"bin size":10,"upstream":500,"group_boundaries":[0,2],"sample_boundaries":[0,187],"missing data as zero":false,"ref point":null,"min threshold":null,"sort regions":"keep","proc number":1,"bin avg type":"mean","max threshold":null} 3R 0,399,979 50,510,1000 first . + nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan 4.000000 4.000000 4.000000 4.000000 4.000000 4.000000 4.000000 7.700000 7.700000 7.700000 7.700000 7.700000 7.700000 7.700000 7.700000 7.700000 7.700000 7.700000 7.700000 7.700000 7.700000 7.700000 7.700000 7.700000 7.700000 7.700000 7.700000 7.700000 7.700000 24.700001 24.799999 24.799999 24.799999 24.799999 24.799999 24.799999 24.799999 24.799999 24.799999 24.799999 24.799999 24.799999 24.799999 24.799999 24.799999 24.799999 24.799999 24.799999 24.799999 24.799999 24.799999 24.799999 27.600000 27.600000 27.600000 27.600000 27.600000 27.600000 27.600000 27.600000 27.600000 27.600000 27.600000 27.600000 27.600000 27.600000 27.600000 27.600000 27.600000 27.600000 27.600000 27.600000 27.600000 27.600000 27.600000 29.299999 29.299999 29.299999 29.299999 29.299999 29.299999 29.299999 29.299999 29.299999 29.299999 29.299999 29.299999 29.299999 29.299999 29.299999 29.299999 29.299999 29.299999 29.299999 29.299999 29.299999 29.299999 28.000000 28.000000 28.000000 28.000000 28.000000 28.000000 27.960000 26.540000 17.000000 17.000000 16.700001 16.700001 15.450000 14.200000 14.200000 11.000000 11.000000 7.850000 4.700000 4.700000 2.500000 2.500000 1.350000 0.200000 0.200000 nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan 3R 99,499,1079 150,610,1100 second . - nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan 0.200000 0.200000 1.350000 2.500000 2.500000 4.700000 4.700000 17.850000 31.000000 31.000000 31.000000 31.000000 31.000000 31.000000 31.000000 31.000000 28.700001 28.700001 28.700001 28.700001 28.700001 28.700001 28.700001 28.700001 28.700001 28.700001 28.700001 28.700001 28.700001 28.700001 28.700001 28.700001 28.700001 28.700001 28.700001 28.700001 28.700001 28.700001 29.200001 29.200001 29.200001 29.200001 29.200001 29.200001 29.200001 29.200001 29.200001 29.200001 29.200001 29.200001 29.200001 29.200001 29.200001 29.200001 29.200001 29.200001 29.200001 29.200001 29.200001 29.200001 28.950001 28.700001 28.700001 28.700001 28.700001 28.700001 28.700001 28.700001 28.700001 28.700001 28.700001 28.700001 28.700001 28.700001 28.700001 28.700001 28.700001 28.700001 28.700001 28.700001 28.700001 28.700001 28.700001 27.600000 27.600000 27.600000 27.600000 27.600000 27.600000 27.600000 27.600000 27.600000 27.600000 27.600000 27.600000 27.600000 27.600000 27.600000 27.600000 27.600000 27.600000 27.600000 27.600000 27.600000 27.600000 28.000000 15.800000 15.800000 15.800000 15.020000 14.500000 14.250000 12.000000 12.000000 10.200000 9.000000 8.870000 7.700000 7.700000 5.480000 4.000000 4.000000 nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan deepTools-2.5.0/deeptools/test/test_heatmapper/master_multi.mat0000640000201600010240000012351613006372704024202 0ustar ryanbioinfo@{"verbose":true,"scale":1,"skip zeros":false,"nan after end":false,"sort using":"mean","unscaled 5 prime":0,"body":0,"sample_labels":["test","test","test","test"],"downstream":100,"unscaled 3 prime":0,"group_labels":["group1.bed","group2.bed"],"bin size":1,"upstream":100,"group_boundaries":[0,3,6],"sample_boundaries":[0,200,400,600,800],"missing data as zero":false,"ref point":"TSS","min threshold":null,"sort regions":"keep","proc number":32,"bin avg type":"mean","max threshold":null} ch1 100 150 CG11023 0.0 + 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 ch2 150 175 cda5 0.0 - 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 ch3 100 125 cda8 0.0 + 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 ch1 75 125 C11023 0.0 + nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 ch2 125 150 ca5 0.0 - 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 ch3 75 100 ca8 0.0 + nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 deepTools-2.5.0/deeptools/test/test_heatmapper/master_multi.mat.gz0000640000201600010240000000136213006372704024613 0ustar ryanbioinfo?Wmaster_multi.matK@NtUmȸ$gL/ᒸK\'aP[+T?17>PeukԲs6וH&z4nVWimg\dl۶v]Է]mLvQʍ1.FzTk3Sѿδ+?nfٶsFo;\7;CYf 37Yi|~̾k0YB Cų]ؗW}scMӑn9|,gn.mnnL+?9ufUugLڸ:lɌSy$~u3?:O8IS|œw p! @&Ԋ8 Ԋ8 ԊP1x0XLB/=B"9ug2!VtQ VtQ Vtioo8Lӆ6<OB}rBjEAR+:ZA,Ԋ`!Vt !qҋxjwR2p!|@8} )@8} )@8} ){]2]V,X 9k,\le\ XBH BjEAR+:ZA,`<6ds…#Á!$ ! E R`"pL )BH0/aNdeepTools-2.5.0/deeptools/test/test_heatmapper/master_multibed.mat0000640000201600010240000002561213006372704024653 0ustar ryanbioinfo@{"verbose":true,"scale":1,"skip zeros":false,"nan after end":false,"sort using":"mean","unscaled 5 prime":0,"body":0,"sample_labels":["test"],"downstream":100,"unscaled 3 prime":0,"group_labels":["group1.bed","group2.bed"],"bin size":1,"upstream":100,"group_boundaries":[0,3,6],"sample_boundaries":[0,200],"missing data as zero":false,"ref point":"TSS","min threshold":null,"sort regions":"keep","proc number":1,"bin avg type":"mean","max threshold":null} ch1 100 150 CG11023 0.0 + 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 ch2 150 175 cda5 0.0 - 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 ch3 100 125 cda8 0.0 + 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 ch1 75 125 C11023 0.0 + nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 ch2 125 150 ca5 0.0 - 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 ch3 75 100 ca8 0.0 + nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 deepTools-2.5.0/deeptools/test/test_heatmapper/master_nan_to_zero.mat0000640000201600010240000002617513006372704025370 0ustar ryanbioinfo@{"verbose":true,"scale":1,"skip zeros":false,"nan after end":false,"sort using":"mean","unscaled 5 prime":0,"body":0,"sample_labels":["test"],"downstream":100,"unscaled 3 prime":0,"group_labels":["Group 1","Group 2"],"bin size":1,"upstream":100,"group_boundaries":[0,3,6],"sample_boundaries":[0,200],"missing data as zero":true,"ref point":"TSS","min threshold":null,"sort regions":"keep","proc number":1,"bin avg type":"mean","max threshold":null} ch1 100 150 CG11023 0.0 + 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 ch2 150 175 cda5 0.0 - 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 ch3 100 125 cda8 0.0 + 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 ch1 75 125 C11023 0.0 + 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 ch2 125 150 ca5 0.0 - 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 ch3 75 100 ca8 0.0 + 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 deepTools-2.5.0/deeptools/test/test_heatmapper/master_relabeled.svg0000640000201600010240000011734113067414642025011 0ustar ryanbioinfo -0.1 TSS 0.1Kb 0.2 0.6 1.0 1.4 test uno dos uno -0.1 TSS 0.1Kb gene distance (bp) dos 0.0 0.3 0.6 0.9 1.2 1.5 1.8 2.1 2.4 2.7 3.0 deepTools-2.5.0/deeptools/test/test_heatmapper/master_scale_reg.mat0000640000201600010240000004023513006372704024770 0ustar ryanbioinfo@{"verbose":true,"scale":1,"skip zeros":false,"nan after end":false,"sort using":"mean","unscaled 5 prime":0,"body":100,"sample_labels":["test"],"downstream":100,"unscaled 3 prime":0,"group_labels":["Group 1","Group 2"],"bin size":1,"upstream":100,"group_boundaries":[0,3,6],"sample_boundaries":[0,300],"missing data as zero":false,"ref point":null,"min threshold":null,"sort regions":"keep","proc number":1,"bin avg type":"mean","max threshold":null} ch1 100 150 CG11023 0.0 + 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 ch2 150 175 cda5 0.0 - 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 ch3 100 125 cda8 0.0 + 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 ch1 75 125 C11023 0.0 + nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 ch2 125 150 ca5 0.0 - 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 ch3 75 100 ca8 0.0 + nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 deepTools-2.5.0/deeptools/test/test_heatmapper/master_scale_reg.mat.gz0000640000201600010240000000103113006372704025376 0ustar ryanbioinfokWmaster_scale_reg.matj0k)n kՠ}Ql$d${Ie2*?HG:ߟ=F[+gfʹm ~bOd嫵oTR1vdnwjl{+>T<糊:V(rчV@lhpGwΐ\TE=O{߾Ǭ? ^1?-.=NBW]^ ކqN:ɤӳCk6^9R0s[Cvd-C^+Mۓ-Sؐ }';|xY-2?Evu]2Ud3# 82fECK%E"x ՉçղZ2 '4wD" pHd)Eb~_I4E"5`$r#gRl9b(ǂDXDn(Xk"$/vbG"(~4Ȃ[ 7!B@deepTools-2.5.0/deeptools/test/test_heatmapper/master_scale_reg.svg0000640000201600010240000012172513067414642025017 0ustar ryanbioinfo -0.1 TSS TES 0.1Kb 0.2 0.6 1.0 1.4 test Group 1 Group 2 Group 1 -0.1 TSS TES 0.1Kb gene distance (bp) Group 2 0.0 0.3 0.6 0.9 1.2 1.5 1.8 2.1 2.4 2.7 3.0 deepTools-2.5.0/deeptools/test/test_heatmapper/master_unscaled.mat0000640000201600010240000000431313006372704024637 0ustar ryanbioinfo@{"verbose":true,"scale":1,"skip zeros":false,"nan after end":false,"sort using":"mean","unscaled 5 prime":100,"body":1000,"sample_labels":["unscaled"],"downstream":300,"unscaled 3 prime":50,"group_labels":["genes"],"bin size":10,"upstream":500,"group_boundaries":[0,1],"sample_boundaries":[0,195],"missing data as zero":false,"ref point":null,"min threshold":null,"sort regions":"keep","proc number":1,"bin avg type":"mean","max threshold":null} 1 500 1650 foo . . 1.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 3.000000 4.000000 4.000000 4.000000 4.000000 4.000000 5.000000 5.000000 5.000000 5.000000 5.000000 6.000000 6.000000 6.000000 6.000000 6.000000 6.000000 6.000000 6.000000 6.000000 6.000000 6.000000 6.000000 6.000000 6.000000 6.000000 6.000000 6.000000 6.000000 6.000000 6.000000 7.000000 7.000000 7.000000 7.000000 7.000000 7.000000 7.000000 7.000000 7.000000 7.000000 7.000000 7.000000 7.000000 7.000000 7.000000 7.000000 7.000000 7.000000 7.000000 7.000000 7.000000 7.000000 7.000000 7.000000 7.000000 7.000000 7.000000 7.000000 7.000000 7.000000 7.000000 7.000000 7.000000 7.000000 7.000000 7.000000 7.000000 7.000000 7.000000 7.000000 7.000000 7.000000 7.000000 7.000000 7.000000 7.000000 7.000000 7.000000 7.000000 7.000000 7.000000 7.000000 7.000000 7.000000 7.000000 7.000000 7.000000 7.000000 7.000000 7.000000 7.000000 7.000000 7.000000 7.000000 7.000000 7.000000 7.000000 7.000000 7.000000 7.000000 7.000000 7.000000 7.000000 7.000000 7.000000 7.000000 7.000000 7.000000 7.000000 7.000000 8.000000 8.000000 9.000000 9.000000 9.000000 10.000000 10.000000 10.000000 10.000000 10.000000 10.000000 10.000000 10.000000 10.000000 10.000000 10.000000 10.000000 10.000000 10.000000 10.000000 10.000000 10.000000 10.000000 10.000000 10.000000 11.000000 11.000000 11.000000 11.000000 11.000000 11.000000 11.000000 11.000000 11.000000 11.000000 deepTools-2.5.0/deeptools/test/test_heatmapper/out.bed0000640000201600010240000000010212757050136022242 0ustar ryanbioinfoch3 100 125 cda8 0 + ch1 100 150 CG11023 0 + ch2 150 175 cda5 0 - deepTools-2.5.0/deeptools/test/test_heatmapper/profile_master.png0000640000201600010240000005626212757050136024522 0ustar ryanbioinfoPNG  IHDRa*ljsBIT|d pHYsnu> IDATxyTՙ?ϹVU74Њ-":Qc@M⒀\&!2WL/Q'_gD$yd 3cbf4 "~57pct7Mw][wf޺O}rHQk-ysZe="""z ( ˆR ( ˆR ( ˆR ( ˆR ( ˆR ( ˆR ( ˆR ( ˆR ( ˆR`=Cgūuap]8#|^z)ZZZ.@iuڃìYR =tP.DGDDDc& R?~O>dC#"" ,E7/hjjB[[[!""qwd r) ,%:^~e`=Qb q~z~1c<øq QXVewuG/}K?>8>?СC0x4{$@DDTMu^<444#-*,>aMynZՈfª7ntvvb͚5Cƌ'|'Or98<^Lٶ[bԨQ@C4}̈́m۶ ZkX۶Y{yqOnᤰe˖*\ӦMÊ+0uԴC$^qL //g}6Q| /H(i RޞH(i R~ """ R_ ߾xʣ!""$1gcK.L:{lC#""fUpM7p9Oơ&aո{3ӟ4QUR |.\ qGq|MptDDDT U#p*] =2ƒN삕0TC4q F)3%aTī+^M{D:xX 1Q0#tW|U,̗AQ ѠwRĒQ{RaDTQF$] %3WgQɻ;ga>U 0"Aw,̧Z|A  Ŏ2Xitvv #2"ZH0O3AQ|M=<GBD ˆyڰuNtti<:l"a4%e e`FKX MM#Ry"~bFBc0Ͷhm050"HD"-f ]k'jW|w\aFDDDaD {ii@Ξ SsAQBrΎ$"bFDL_:R $3aTK$7#aD 83@!"?aD )sMq o /wEDT+Q 0l.G (!|i_fDD7 ˆhP|g Yw*VOTK)%Lb¨`p=nz0H.DD MnɎT~AQB/MQeH.7 ˆhP È|%LfˆˑDiyG ˆR>$@D40 ˆ&1|d(0H T|.? ˆhd_/220#JHtvLXiB(]kr$:Iz 0+W{~y۶r^҂j[V#lނ1۶lc; 60KqƏ 9n݊iӦnS0|qiQ8;^= ,aWƜ9s8ŋ3j(,]1 Fֳ}¨eve`1۶l/:v|#QAX֮]YfXd >яrNZ |=jaE4X[Fct}>fӻa+,aa~B6n܈3gC.ߏO}SiT^/'b/ſ.fˆw̧cm۶a̙xaN|M{XDDqnz*۱cf͚PJa @va> \UQe0AXuttଳ+馛pW<**_`r9j[=bV%8^`\s GET- P!$?9s&.b^z/ 8Ò|@ݫR*1F#AXaD ]e$][p-< IqS̄e3ar0#A)@h@A KYLFY:%$h3ّlH9 Oҵe0.-'/̗%z]dW- z#1i ˆ$5yP2 IŒ||ݲAQBӖw̗{mޒ-@84ID&=) kˆLQBR/0F|9CT7%+p g,G ˆ"5\ۍ@E%Y ?:Z`]ŠnG,'"SZk8 6̕R8ԔPAQBWӥlS;%][p-۷o] *̄;w裏N{(Ue1#"ySրm۰NJ{8ՀXES#%A~axK%Is1`G44UZ?@ZdaF8i*M䲂'"FY02 .`%̄ɑOQHL9^<e{QF0#JhIK RJ$mY4YQV0#Nf`n^-ebF0_wf8 hcZ>@lxIAỦ.ɻF=ФKyz (!#%;(L!fl9R '=&=Yآ(aҾ4c~ڣ02aq0WV? #6~-Ek|mH}O#aD Ҿ4~SB)iL$_e0"45ziɹnH;Y (! -(DHy(ɤt%~ܔL#`F8i_Ү Sd7k%9%H z ff5:.8& 2-*"XaȜOb,G 9`&-&MMCޱEeڕn,'0F0_d?;R6y5UL>HedyAˑT%Dv -rIK)IKA=bF0i_Ey2aJZV?xS1#A:Ex"_?LAQBEd'sIKIײ'>aүU:$"ڗ&Lڄ>aL.GRV0F0_ߙ LV)zLQNv",H T²|Jx8I[=b&(AsA<Q1#J>aa>`Kdž & r$UĆ X|JENƓusCNуExWlB.'c*w(QFH>h4= tv9Y[$kYKҵwm!ZcF 7эqʣ/% 7T_(*#]'~U8i)2>JaD \JAX,CNy4aeU t v&k3,$0CZ En+ZQAXRLi)BNDRL%gB0a0Ja9SyVɹe%T\"u"ha7eO33s)AQ^$MH=)7@7HrD (Lv?{ 4d ă09 izHf²AQ$NL#&)8oI0*3a&k2Q$ ]T L<::[VRˑ0 ܲQ* Eʄy}z^k. bQޔavG&-P-Ң/GJ̈́ųe0^8RPa~yM^ Lk W;2gq92%H|HRfĖ#YttwioX&0΄)ˑA@)p=uOy VR$aD4(H4|I<q05\aa>[TdoK&=˺w˹+70_d-4͋(!k%? 8H䆃R &7xFX,9zLQ$N=IYdhrs<'őT.z#ےI>; }EzpE*~&,x_ 0iOXf1#J/̏5E#|IJt3 wNrd1?XJ[tD ()Jb3aj|27HZPoLDMZx%O]xlQCzZ4!}Yo>%H D::G #OD.3W*08g_=HZ0XEҪ#%vQa;2~TA.Ef_= )УO#=YY$җ#2a 2^lݺp30`/=AX f²Mηeq 'ǁcĉi*%aH \.ޙÚ0|[֘nƨ$ %HpV-**TLX1&J#˺w ;=-G0#A} 6zD >!R#h @%)t-{>a2#J"ah2dʗ#f srwGr9RaD4h,#X)zz wG ZGr mXrekiiAKKK#x=;wv=FЦ_1?ee`.XkkkJ\Тܲy n޺l۲$4 ۤlݺӦMqm&%/nu^}GSYZŏa=XJJpmOò>HԎB|̹RR#]3a*;A=ߋQs|[֙QFaҥ>Yڱs'Fh9!)(Lpt)iˇaޒ va^vf>mv|cLJ;U|[֙\.S= #5;aú0yr[#b#UIQ1 M4=v[êիG[qMH׋6d%Flo0e dѢEp]|bL?0eD0.GZVt-ciT5kei ˆF-iEuEvGF?fQ,-ouAQז%g ր!(R~A ̲!*> uKЖbW3k²Mλƹg# Z/hτy  ”RՅރZTM<i:yWոxML/Ij itSIec@)vXt;Dam;JK$aّ09^oZPw&ˈՄ $ZudnixFgC@h׮إeFG|or)a'jwd._iYg´֥UVQZ֠m. {&,%τEBAN&̲( QX ˑ~0I[TJLX1#JHEE.'cB|R +;pEa'uJّR0@Aǂ0gGfOQr>j‚H-(JAEEA?` /ʘYLXxW8OXqYVo-k2Śj%&,Pώ .G&,%Dّ=wGJb*"I[FsՄYTJ)`g=ITL ̲4Ц4c_BufrLրr$k2AQB♰|^Ƅg &,gƢej-R |9Y00 ^,`LcF0S!;[X)lP )YkrR n,&eAG09=t'LJhǧ!&yO( m2?yD5Ht0 {Jp0dՃ MIo: (Zkx^&,T;[ye0[,)a 4zD iv a5a38ZTX=d|q&XvEGYX=a]>aa:,#a=JZAPB[▵LS:;TNPoO[D{$i/qͰE-GA `MX#JH 3 Odb0ii(g8ZTd7n{QBTA$ʈ2a҂0tM :עbXwF!WHmLrݒV[W 3 #Qaf‚03iЦBhP*O{Dfh>&,¦\S٢0egG2meDpHob5a(g5)Wa`)SDξ1J)X.LkV%@v&,;R^aJ)#"i ʅc{ݒJg,I: (!R3aʈəȁ`92*̏zur9CkW a:s!EEl9rd1#J@<&)lQ!<,-G%g2IٺiAfM ˆed-GB 5HY7f LXތpLk²QB0AA vo*N0_j|~&,'(lOVZб-f2AQH&- j@ ;;os2Pjw^ +X L?0 o.Gf0hoiA& ? D85Quy3j8kk[\&S|yz (-.uמ)E:*` @Y]Z b;}!P1#JmǏ5a(1p LLZk\gkYˑ=3aRa~V{xg0r0b!ˑAMR8Rha_Kʄr 2a@PտQ0#J@p-Oʖ#-a*4's9RCV{ YS@EE#J@<&c~Y OpeԄAeWEˑde´~ (Z 0k¤etHIpDVMh9Rʄb#-'p+H5aL|eun ,ʄ7U3alW*S+aD ؖra+v ) 44X0IA:jQYKr$3aR$J@,m9F,vv$.G*x&teoLUu ݑ @x*򳏯 Q< m9R$׮l swʙ{f”s?QˑZo.Gf0ر`iˑvynNّopZCǂ0K7Ր/L];; eS%Җ#]Ej4D+;rư)kʿ1 ,d3jmG2arjQa= ,u_EAԄ0WT&Lk]֢Bǭ.1#J@&,/V;X= +"|i#E#AQ\Ww2avhA9P:ni95aZNMXcg&LP* Z{āe0wGZVP)ƔiuYM+.ՄSL !f&,% ;R^MUttv@Ó KYtEȞ}$}0HiGnMDe.& L4WX&曬 8aD p(ɊS Qa>60vgf’2al,3a (r&g<'gRY/k9@Yֆ?8] m7*0 S 06P,ضՄi&14MJXM_JN Rv>aD ׄYLXlwLr&c\AgG(kQ<9#h9RZ0ۍ^3?&禧1#Jݑ>-m9g; u)#++a,p:7t1}(ljweKt.*TP^&A|92a0 ׵?uBk(քI (5a‚r6%_k:1#JLXYL8uy ,_PX"7q?i +99քe3Qx&Ldhw$!0qtY|Y)eMQZ {n#Q0YA;2 DՄ9jQĖ#< +-B t!:τI1? ˆP^&0 .I[pt]uWl5Jpj, #ΔGS9e0cFمI3B8!x9>j´(0*JyDSh6 <aD Op0jLY+ k9v*Sș02a )r {#QZA'MNO;ۉj,gܨ)(_tm :YQa ʳ.^&m9^7PvViσ.66󂂰B<c&,|j|]Vf Nplwd9tA'& aVAƹPhރn5a /Ga5a ŁTYҦT1b-*dweˑ2aMA0Os :aDU1_ӱ#!ߔ*-*n1 ݑ+ʄ2a?sf2NΧ5aAɉQvGz&k+XMf]NX]Z& ^qHk3׽GgX&5aY' Lp!gˑʳQg#vsg{#m@0?y$p:ҊY9^Y]ROU: 3MyE`Ec]׵S.QUƖz" ! ”%,-W~&L&Zw02aD jDf‚R픴`9R@CɓOyTv kr2`wrr0sr$tC LX˄}J"lj @ &KqD6TyY0h؝HCP㻑= ;}aD  )/tvd)XuT\*(C%QUʩOi0Q SNj',̇6CVUYYH _)a t]T&E)6ʄi+ 3l93k's)Y (A&0 k‚ L׊ J)/vmXn8 hjjJ{T%~&'&qZ`w?701)r<Ϡ`秠 , 3):yw$@RW:HA4|>Ui&AX\y啰mB=M'; 7vZ|wGKT 1/S*7vذaa7V}lxM|7 i# ,Ȅˑjt|ǖe‚Ȣӕ*'>PoTֈ֨S{}av8^g46hlsSen4Ck`E&\ֵFJKv۶5*uC)_u7NU3aAvy0dk׼UNC Gw4n?s{m:M`VaݑXVys9Cݑ^W7ږo< D ZV7,hT|׮~|ʣҲ]lh-س`Va#Fc{{;-]t n;78Jm0bDTq-c@ЀcN{H2Sb[aƍ0LM#b}m{Zw@ޅ68Fah3-4Q<h=|p6̱MǬW *lС6l{-oooGGG`ر{ 9 S,j*lذ9cY ƙ80yrKC)c`)ib`K ccƴT1;>6mޅ͛<4!9|4xLê5k#Lp?jY>_de&#7gx[#(LU:?y&u#"XSP"30`ϝmw 6~[Vќ9szj\~8C؈c=7tVZ;,aRL!n2xWca~VF`̄R0-vww#7azzW&N.=R j´Z0gf²! 0 @y0yr̨=EY0mI0`2w1 җ#H 3D`}̄%40HXy^x}̄eie+`D.r2}A{|dQ ˆτI cMiB9Lzrp, q8vCN(˱= ˆτI¸~̄+B)7_eD`AX1#J3aT,˂m sѐo[0n~0M9ӝi`^+jXP@N )8Hk uEvb0 #yz+aD Pf4r9f²&~:qXĤIے(A|]=?? RM7&Q aḦ́y0MvϚ`9w80L1#J@!2 x3M!ހ ~c%$8[ّ0MAVGRa~Q+L6;bf) 3 ˲`t\ٔp*cg#)$JH 0?C mí;NHm ˆd´*J=<oֆ i⚛|H&aD 2a@pൌ%1=p.0466= }bF r076HzQm+QBzf¤ #"~c%$h H ¢L0"7&QBL 3F0/..G03a.b&h`Ix&,8ZlQAD4 ˆd”RhQ+[(!AH)Y0uyx7[(!AbJTM 3IDO ˆaJ)a0.G 5dLYLQآ KI3U/L_G%5 AjM͛q.CKKK!8a,cIZΪA0vmG#ˑ7oƍ7ވٳg3#J@q ˆ 31r ^H{8АDD (!J)r!ؾ}0r3fL "aD jnnFsss " (AQ AQ W^\.q`GUmغu+F\.pۼy3<σeYm;T1Mns "dF]tgihh@WWLĨQQlݺ뢡!$0"""0( ˆR ( ˆR ( ˆR ( ˆR ( jupUWa2dM}{k?wu ( 0 a'U˃'7ߌ3gb̘1( hhh@KK >O+=܃m۶sl+VW^c=Ͱ, MMM~/_ާ ?}}>ζm}y煏'?wرx㍃)Zr%Ν ۶1b|ىv֭[38/2J)r9}(XjU{DYuc{=5N?tlڴ cǎŲe\O==\8˲pys&N4{aʕXt)}Y(J)?Ǯ_^/Zhjժ5uTں~^FT-+VRo/~ꩧW^fo'Mw,Z( }qc9P3fٳǝzz׮]{}3a R3τo{}GRz J?>0 } 6n~&Ν;n<<Ȁ()I$* W٩<1~0?%> ?:o޼>.ر?x"c#G6l2eʠG)5!JŸ'#Qya&,S?_{xw+2>jzBgqFj _~_òPkkc Zk;Xp!9昪 Rс6Ω}6lXcƍUQ* =\{~מ`/| W^ɓqgcxUk ,'Z[[1k֬0(dO_Wsw p19rGow*DT9#FYg֭[q-_2e ͛ `ŊXf 9o;U=rBOƗ%vl9'pBk _?0t0[=v7pwn u"z(~_OOnAd9!`&~9s&>~=Oo5s [h\?wyg|#7ξwy8ܹs7|s?Ko0C4YOgq?S5k֬~լ}n+tI;wbʕ{}\$g(]a 'OYOr9<1c`ʕ83€7Ǘ8t/dΜ9Fqwuw hnnih6l؀[&N8yß{M ,%'xbXppm܂ B/|Ő˗/a0 liW^g?|\WWW@XwW^7 _V={GN4pRCҥKîO<̙NUV_eDeP)l֚[o'x""N;4|;ىz+-]k׮ }aܝQi1e̞='pƎ!C`xpBC9ַʞ ,7ߌ3gSOG?QpZcXl~7 L4)K& /.\K.dzK,_z*7MÇcٲe1cVZe˖_"~_ﳋWU,_|^a/tRѣ+>fa)6m>\xhkk5\c9UVaݺuhmmihnnGO>_|1&O\&곤I%Fr ֭[ {͝;k֬޻ǒaÆ4^i"""{k׮_It>C ˿;w-_\+a_^c'Nhٳǿncc=w?/ Y1~)^-tsw[c7o=yo`fee%QHkK.??n'Ol1˭1Ʈ]֞={6nv֭6Jqֺ~+W[+])ݻG^tM MMMz裏?~qz뭒{NZܼX,:uJmmmZl?v=/T]]>k>S B :rH U7T 'ݫGwТEGjʔ)qReeq{+FGqo߮+W*##CpݭQ]R/ 5"]cLҗ$z*}' _U2hÆ I?'T(R8ѣGUVV6jolPv$-_1ϳ^rޙ3g1V:}vޭ^ӧOWOOVX/,cCɑ b~+lI9r䈢Ѩ11cFJ }̜9StoF7c%i=&??_w^}UuuuiժUGk!vdMN$ _pMZ[&=wߕW^@Xx$M Nw-YDٳ mmmaQMMK?[DҥK%IqON8e˖?H5_xc}v555t˖- B2_L hFZb~[uuuL:tI=C!yc?vء={IRF/bo善Qgdd؛onܸoɚ5k1ƾK c7o_:yd;g[XXMRV￷%%%uwnzg O -0.1 TSS 0.1Kb −0.5 0.0 0.5 1.0 1.5 2.0 2.5 3.0 test uno dos deepTools-2.5.0/deeptools/test/test_heatmapper/profile_master_heatmap.svg0000640000201600010240000003636413006372704026231 0ustar ryanbioinfo -0.1 TSS 0.1Kb Group 2 Group 1 test 0.0 0.3 0.6 0.9 1.2 1.5 1.8 2.1 2.4 2.7 3.0 deepTools-2.5.0/deeptools/test/test_heatmapper/profile_master_multi.svg0000640000201600010240000010322613006372704025734 0ustar ryanbioinfo -0.1 TSS 0.1Kb 0.0 0.2 0.4 0.6 0.8 1.0 1.2 1.4 test group1.bed group2.bed -0.1 TSS 0.1Kb test -0.1 TSS 0.1Kb 0.0 0.2 0.4 0.6 0.8 1.0 1.2 1.4 test -0.1 TSS 0.1Kb test deepTools-2.5.0/deeptools/test/test_heatmapper/profile_master_multi_pergroup.svg0000640000201600010240000005076613006372704027671 0ustar ryanbioinfo -0.1 TSS 0.1Kb 0.0 0.2 0.4 0.6 0.8 1.0 1.2 1.4 group1.bed test test test test -0.1 TSS 0.1Kb group2.bed deepTools-2.5.0/deeptools/test/test_heatmapper/profile_master_overlap_lines.svg0000640000201600010240000023060513006372704027446 0ustar ryanbioinfo -0.1 TSS 0.1Kb −1.0 −0.5 0.0 0.5 1.0 1.5 2.0 2.5 3.0 Group 2 −1.0 −0.5 0.0 0.5 1.0 1.5 2.0 2.5 3.0 Group 1 test 1.0 1.5 2.0 2.5 3.0 3.5 4.0 4.5 5.0 5.5 6.0 deepTools-2.5.0/deeptools/test/test_heatmapper/test.bed0000640000201600010240000000010212757050136022412 0ustar ryanbioinfoch1 100 150 CG11023 0 + ch2 150 175 cda5 0 - ch3 100 125 cda8 0 + deepTools-2.5.0/deeptools/test/test_heatmapper/test.bg0000640000201600010240000000121012757050136022251 0ustar ryanbioinfoch1 0 25 0 ch1 25 50 0 ch1 50 75 0 ch1 75 100 0 ch1 100 125 2 ch1 125 150 0 ch1 150 175 0 ch1 175 200 0 ch1 200 225 0 ch1 225 250 0 ch1 250 275 0 ch1 275 300 0 ch1 300 325 0 ch1 325 350 0 ch1 350 375 0 ch1 375 400 0 ch2 0 25 0 ch2 25 50 0 ch2 50 75 3 ch2 75 100 0 ch2 100 125 0 ch2 125 150 0 ch2 150 175 1 ch2 175 200 0 ch2 200 225 0 ch2 225 250 0 ch2 250 275 0 ch2 275 300 0 ch2 300 325 0 ch2 325 350 0 ch2 350 375 0 ch2 375 400 0 ch3 0 25 0 ch3 25 50 0 ch3 50 75 3 ch3 75 100 0 ch3 100 125 0 ch3 125 150 0 ch3 150 175 1 ch3 175 200 0 ch3 200 225 0 ch3 225 250 0 ch3 250 275 0 ch3 275 300 0 ch3 300 325 0 ch3 325 350 0 ch3 350 375 0 ch3 375 400 0 deepTools-2.5.0/deeptools/test/test_heatmapper/test.bw0000640000201600010240000004574512757050136022316 0ustar ryanbioinfo&X0= y33@@o@@xch1ch2ch3x=ϡ0O̠ETz@PAȂ7{'ElbVs@ :fpE`#bA4-h$@  Zxc```f/h$@  ?&deepTools-2.5.0/deeptools/test/test_plotCoverage/0000750000201600010240000000000013067415120021262 5ustar ryanbioinfodeepTools-2.5.0/deeptools/test/test_plotCoverage/make_test_files.sh0000640000201600010240000000025412757050137024766 0ustar ryanbioinfoplotCoverage --bamfiles ../test_data/test1.bam ../test_data/test2.bam --plotFile plotCoverage_default.svg --plotFileFormat svg --outRawCounts outRawCounts_default.tabular deepTools-2.5.0/deeptools/test/test_plotCoverage/outRawCounts_default.tabular0000640000201600010240000007257312757050137027046 0ustar ryanbioinfo#'chr' 'start' 'end' 'test1.bam' 'test2.bam' 3R 0 1 0.0 0.0 3R 1 2 0.0 0.0 3R 2 3 0.0 1.0 3R 3 4 0.0 1.0 3R 4 5 0.0 1.0 3R 5 6 0.0 1.0 3R 6 7 1.0 2.0 3R 7 8 1.0 2.0 3R 8 9 1.0 2.0 3R 9 10 1.0 2.0 3R 10 11 1.0 2.0 3R 11 12 1.0 2.0 3R 12 13 1.0 2.0 3R 13 14 1.0 2.0 3R 14 15 1.0 2.0 3R 15 16 1.0 2.0 3R 16 17 1.0 2.0 3R 17 18 1.0 2.0 3R 18 19 1.0 2.0 3R 19 20 1.0 2.0 3R 20 21 1.0 2.0 3R 21 22 1.0 2.0 3R 22 23 1.0 2.0 3R 23 24 1.0 2.0 3R 24 25 1.0 2.0 3R 25 26 1.0 2.0 3R 26 27 1.0 2.0 3R 27 28 1.0 2.0 3R 28 29 1.0 2.0 3R 29 30 1.0 2.0 3R 30 31 1.0 2.0 3R 31 32 1.0 2.0 3R 32 33 1.0 2.0 3R 33 34 1.0 2.0 3R 34 35 1.0 2.0 3R 35 36 1.0 2.0 3R 36 37 1.0 2.0 3R 37 38 1.0 2.0 3R 38 39 1.0 2.0 3R 39 40 1.0 2.0 3R 40 41 1.0 2.0 3R 41 42 1.0 2.0 3R 42 43 1.0 2.0 3R 43 44 1.0 2.0 3R 44 45 1.0 2.0 3R 45 46 1.0 2.0 3R 46 47 1.0 2.0 3R 47 48 1.0 2.0 3R 48 49 1.0 2.0 3R 49 50 1.0 2.0 3R 50 51 1.0 2.0 3R 51 52 1.0 2.0 3R 52 53 1.0 2.0 3R 53 54 1.0 1.0 3R 54 55 1.0 1.0 3R 55 56 1.0 1.0 3R 56 57 1.0 1.0 3R 57 58 0.0 0.0 3R 58 59 0.0 0.0 3R 59 60 0.0 0.0 3R 60 61 0.0 0.0 3R 61 62 0.0 0.0 3R 62 63 0.0 0.0 3R 63 64 0.0 0.0 3R 64 65 0.0 0.0 3R 65 66 0.0 0.0 3R 66 67 0.0 0.0 3R 67 68 0.0 0.0 3R 68 69 0.0 0.0 3R 69 70 0.0 0.0 3R 70 71 0.0 0.0 3R 71 72 0.0 0.0 3R 72 73 0.0 0.0 3R 73 74 0.0 0.0 3R 74 75 1.0 0.0 3R 75 76 1.0 0.0 3R 76 77 1.0 0.0 3R 77 78 1.0 0.0 3R 78 79 1.0 1.0 3R 79 80 1.0 1.0 3R 80 81 1.0 1.0 3R 81 82 1.0 1.0 3R 82 83 1.0 1.0 3R 83 84 1.0 1.0 3R 84 85 1.0 1.0 3R 85 86 2.0 1.0 3R 86 87 2.0 1.0 3R 87 88 2.0 2.0 3R 88 89 2.0 2.0 3R 89 90 2.0 2.0 3R 90 91 2.0 3.0 3R 91 92 2.0 3.0 3R 92 93 3.0 3.0 3R 93 94 3.0 3.0 3R 94 95 3.0 4.0 3R 95 96 3.0 4.0 3R 96 97 3.0 4.0 3R 97 98 3.0 4.0 3R 98 99 3.0 4.0 3R 99 100 3.0 4.0 3R 100 101 3.0 4.0 3R 101 102 3.0 4.0 3R 102 103 3.0 4.0 3R 103 104 3.0 4.0 3R 104 105 3.0 4.0 3R 105 106 3.0 4.0 3R 106 107 3.0 4.0 3R 107 108 3.0 6.0 3R 108 109 3.0 6.0 3R 109 110 3.0 6.0 3R 110 111 3.0 6.0 3R 111 112 3.0 6.0 3R 112 113 3.0 6.0 3R 113 114 3.0 6.0 3R 114 115 3.0 6.0 3R 115 116 3.0 6.0 3R 116 117 3.0 6.0 3R 117 118 3.0 6.0 3R 118 119 4.0 6.0 3R 119 120 4.0 6.0 3R 120 121 4.0 6.0 3R 121 122 4.0 6.0 3R 122 123 4.0 6.0 3R 123 124 4.0 6.0 3R 124 125 4.0 6.0 3R 125 126 3.0 6.0 3R 126 127 3.0 7.0 3R 127 128 3.0 7.0 3R 128 129 3.0 7.0 3R 129 130 3.0 6.0 3R 130 131 3.0 6.0 3R 131 132 3.0 7.0 3R 132 133 3.0 8.0 3R 133 134 4.0 9.0 3R 134 135 4.0 9.0 3R 135 136 4.0 9.0 3R 136 137 3.0 9.0 3R 137 138 3.0 10.0 3R 138 139 3.0 9.0 3R 139 140 3.0 9.0 3R 140 141 3.0 9.0 3R 141 142 3.0 8.0 3R 142 143 3.0 10.0 3R 143 144 2.0 10.0 3R 144 145 2.0 10.0 3R 145 146 2.0 9.0 3R 146 147 2.0 9.0 3R 147 148 2.0 9.0 3R 148 149 3.0 9.0 3R 149 150 3.0 11.0 3R 150 151 3.0 11.0 3R 151 152 4.0 11.0 3R 152 153 4.0 11.0 3R 153 154 4.0 12.0 3R 154 155 4.0 13.0 3R 155 156 6.0 13.0 3R 156 157 6.0 13.0 3R 157 158 6.0 13.0 3R 158 159 6.0 11.0 3R 159 160 7.0 12.0 3R 160 161 8.0 12.0 3R 161 162 8.0 12.0 3R 162 163 8.0 12.0 3R 163 164 8.0 12.0 3R 164 165 8.0 12.0 3R 165 166 8.0 12.0 3R 166 167 8.0 12.0 3R 167 168 9.0 12.0 3R 168 169 10.0 14.0 3R 169 170 9.0 14.0 3R 170 171 11.0 16.0 3R 171 172 12.0 19.0 3R 172 173 13.0 19.0 3R 173 174 13.0 19.0 3R 174 175 14.0 20.0 3R 175 176 16.0 20.0 3R 176 177 16.0 20.0 3R 177 178 16.0 19.0 3R 178 179 17.0 19.0 3R 179 180 17.0 20.0 3R 180 181 17.0 22.0 3R 181 182 18.0 23.0 3R 182 183 18.0 22.0 3R 183 184 19.0 22.0 3R 184 185 18.0 21.0 3R 185 186 18.0 21.0 3R 186 187 19.0 22.0 3R 187 188 20.0 22.0 3R 188 189 20.0 21.0 3R 189 190 20.0 21.0 3R 190 191 20.0 21.0 3R 191 192 20.0 22.0 3R 192 193 20.0 22.0 3R 193 194 20.0 22.0 3R 194 195 21.0 22.0 3R 195 196 21.0 22.0 3R 196 197 21.0 24.0 3R 197 198 21.0 24.0 3R 198 199 21.0 24.0 3R 199 200 20.0 24.0 3R 200 201 20.0 23.0 3R 201 202 20.0 23.0 3R 202 203 19.0 23.0 3R 203 204 19.0 23.0 3R 204 205 19.0 22.0 3R 205 206 19.0 21.0 3R 206 207 17.0 23.0 3R 207 208 17.0 24.0 3R 208 209 17.0 24.0 3R 209 210 17.0 24.0 3R 210 211 16.0 23.0 3R 211 212 15.0 24.0 3R 212 213 15.0 24.0 3R 213 214 15.0 24.0 3R 214 215 15.0 24.0 3R 215 216 15.0 24.0 3R 216 217 16.0 25.0 3R 217 218 16.0 25.0 3R 218 219 15.0 25.0 3R 219 220 14.0 23.0 3R 220 221 14.0 23.0 3R 221 222 12.0 21.0 3R 222 223 12.0 18.0 3R 223 224 11.0 18.0 3R 224 225 11.0 18.0 3R 225 226 11.0 17.0 3R 226 227 9.0 17.0 3R 227 228 9.0 17.0 3R 228 229 10.0 17.0 3R 229 230 9.0 19.0 3R 230 231 9.0 18.0 3R 231 232 9.0 17.0 3R 232 233 8.0 18.0 3R 233 234 8.0 18.0 3R 234 235 8.0 17.0 3R 235 236 10.0 17.0 3R 236 237 10.0 17.0 3R 237 238 9.0 16.0 3R 238 239 8.0 16.0 3R 239 240 8.0 16.0 3R 240 241 8.0 16.0 3R 241 242 8.0 16.0 3R 242 243 8.0 15.0 3R 243 244 8.0 15.0 3R 244 245 8.0 13.0 3R 245 246 7.0 13.0 3R 246 247 7.0 13.0 3R 247 248 7.0 11.0 3R 248 249 7.0 11.0 3R 249 250 7.0 11.0 3R 250 251 7.0 11.0 3R 251 252 7.0 10.0 3R 252 253 7.0 10.0 3R 253 254 7.0 10.0 3R 254 255 7.0 10.0 3R 255 256 7.0 10.0 3R 256 257 7.0 10.0 3R 257 258 7.0 8.0 3R 258 259 7.0 7.0 3R 259 260 7.0 7.0 3R 260 261 7.0 7.0 3R 261 262 7.0 7.0 3R 262 263 7.0 6.0 3R 263 264 7.0 6.0 3R 264 265 7.0 6.0 3R 265 266 7.0 6.0 3R 266 267 7.0 6.0 3R 267 268 6.0 5.0 3R 268 269 6.0 5.0 3R 269 270 7.0 5.0 3R 270 271 7.0 6.0 3R 271 272 7.0 6.0 3R 272 273 7.0 6.0 3R 273 274 6.0 6.0 3R 274 275 6.0 6.0 3R 275 276 6.0 6.0 3R 276 277 5.0 6.0 3R 277 278 5.0 8.0 3R 278 279 6.0 8.0 3R 279 280 5.0 8.0 3R 280 281 5.0 7.0 3R 281 282 5.0 7.0 3R 282 283 5.0 7.0 3R 283 284 5.0 5.0 3R 284 285 6.0 5.0 3R 285 286 5.0 5.0 3R 286 287 3.0 5.0 3R 287 288 3.0 5.0 3R 288 289 4.0 5.0 3R 289 290 4.0 6.0 3R 290 291 4.0 6.0 3R 291 292 4.0 7.0 3R 292 293 5.0 7.0 3R 293 294 5.0 7.0 3R 294 295 5.0 7.0 3R 295 296 5.0 7.0 3R 296 297 5.0 8.0 3R 297 298 5.0 9.0 3R 298 299 5.0 9.0 3R 299 300 5.0 10.0 3R 300 301 5.0 10.0 3R 301 302 5.0 10.0 3R 302 303 5.0 10.0 3R 303 304 6.0 10.0 3R 304 305 6.0 10.0 3R 305 306 6.0 12.0 3R 306 307 6.0 12.0 3R 307 308 6.0 12.0 3R 308 309 6.0 12.0 3R 309 310 6.0 12.0 3R 310 311 6.0 12.0 3R 311 312 6.0 12.0 3R 312 313 6.0 12.0 3R 313 314 6.0 12.0 3R 314 315 6.0 12.0 3R 315 316 6.0 12.0 3R 316 317 6.0 12.0 3R 317 318 6.0 13.0 3R 318 319 6.0 13.0 3R 319 320 6.0 13.0 3R 320 321 5.0 13.0 3R 321 322 5.0 12.0 3R 322 323 5.0 12.0 3R 323 324 5.0 12.0 3R 324 325 5.0 12.0 3R 325 326 5.0 12.0 3R 326 327 5.0 12.0 3R 327 328 5.0 12.0 3R 328 329 5.0 10.0 3R 329 330 4.0 10.0 3R 330 331 4.0 10.0 3R 331 332 4.0 9.0 3R 332 333 4.0 9.0 3R 333 334 4.0 8.0 3R 334 335 4.0 8.0 3R 335 336 3.0 10.0 3R 336 337 3.0 10.0 3R 337 338 3.0 10.0 3R 338 339 3.0 11.0 3R 339 340 2.0 11.0 3R 340 341 3.0 10.0 3R 341 342 5.0 10.0 3R 342 343 5.0 9.0 3R 343 344 4.0 9.0 3R 344 345 4.0 9.0 3R 345 346 4.0 9.0 3R 346 347 4.0 9.0 3R 347 348 4.0 8.0 3R 348 349 4.0 7.0 3R 349 350 4.0 7.0 3R 350 351 4.0 6.0 3R 351 352 4.0 6.0 3R 352 353 4.0 6.0 3R 353 354 4.0 6.0 3R 354 355 3.0 6.0 3R 355 356 3.0 6.0 3R 356 357 3.0 4.0 3R 357 358 3.0 4.0 3R 358 359 3.0 4.0 3R 359 360 3.0 4.0 3R 360 361 3.0 5.0 3R 361 362 3.0 5.0 3R 362 363 3.0 5.0 3R 363 364 3.0 5.0 3R 364 365 3.0 5.0 3R 365 366 3.0 6.0 3R 366 367 3.0 6.0 3R 367 368 3.0 6.0 3R 368 369 3.0 5.0 3R 369 370 3.0 5.0 3R 370 371 3.0 5.0 3R 371 372 3.0 5.0 3R 372 373 3.0 5.0 3R 373 374 3.0 5.0 3R 374 375 3.0 5.0 3R 375 376 3.0 6.0 3R 376 377 3.0 6.0 3R 377 378 4.0 6.0 3R 378 379 4.0 6.0 3R 379 380 4.0 6.0 3R 380 381 4.0 6.0 3R 381 382 4.0 7.0 3R 382 383 4.0 7.0 3R 383 384 5.0 9.0 3R 384 385 5.0 9.0 3R 385 386 5.0 9.0 3R 386 387 5.0 7.0 3R 387 388 5.0 7.0 3R 388 389 5.0 8.0 3R 389 390 6.0 7.0 3R 390 391 6.0 7.0 3R 391 392 5.0 7.0 3R 392 393 4.0 7.0 3R 393 394 4.0 7.0 3R 394 395 4.0 7.0 3R 395 396 5.0 7.0 3R 396 397 5.0 7.0 3R 397 398 5.0 7.0 3R 398 399 5.0 8.0 3R 399 400 5.0 9.0 3R 400 401 5.0 10.0 3R 401 402 8.0 10.0 3R 402 403 8.0 10.0 3R 403 404 8.0 10.0 3R 404 405 8.0 10.0 3R 405 406 8.0 10.0 3R 406 407 8.0 10.0 3R 407 408 8.0 12.0 3R 408 409 8.0 12.0 3R 409 410 8.0 12.0 3R 410 411 8.0 12.0 3R 411 412 8.0 11.0 3R 412 413 8.0 14.0 3R 413 414 9.0 14.0 3R 414 415 9.0 14.0 3R 415 416 9.0 16.0 3R 416 417 9.0 15.0 3R 417 418 9.0 17.0 3R 418 419 10.0 17.0 3R 419 420 10.0 17.0 3R 420 421 10.0 17.0 3R 421 422 10.0 18.0 3R 422 423 10.0 18.0 3R 423 424 10.0 19.0 3R 424 425 10.0 19.0 3R 425 426 10.0 19.0 3R 426 427 11.0 18.0 3R 427 428 11.0 18.0 3R 428 429 11.0 18.0 3R 429 430 11.0 18.0 3R 430 431 11.0 18.0 3R 431 432 11.0 18.0 3R 432 433 11.0 17.0 3R 433 434 11.0 17.0 3R 434 435 10.0 15.0 3R 435 436 12.0 17.0 3R 436 437 12.0 17.0 3R 437 438 12.0 17.0 3R 438 439 12.0 17.0 3R 439 440 12.0 16.0 3R 440 441 11.0 16.0 3R 441 442 11.0 16.0 3R 442 443 11.0 17.0 3R 443 444 10.0 17.0 3R 444 445 10.0 17.0 3R 445 446 10.0 17.0 3R 446 447 9.0 17.0 3R 447 448 11.0 17.0 3R 448 449 11.0 17.0 3R 449 450 11.0 16.0 3R 450 451 11.0 15.0 3R 451 452 11.0 14.0 3R 452 453 8.0 14.0 3R 453 454 8.0 14.0 3R 454 455 9.0 14.0 3R 455 456 9.0 14.0 3R 456 457 9.0 14.0 3R 457 458 9.0 15.0 3R 458 459 9.0 13.0 3R 459 460 9.0 13.0 3R 460 461 9.0 13.0 3R 461 462 10.0 13.0 3R 462 463 10.0 13.0 3R 463 464 10.0 11.0 3R 464 465 9.0 11.0 3R 465 466 9.0 13.0 3R 466 467 10.0 12.0 3R 467 468 10.0 12.0 3R 468 469 10.0 10.0 3R 469 470 9.0 10.0 3R 470 471 9.0 11.0 3R 471 472 10.0 11.0 3R 472 473 10.0 10.0 3R 473 474 10.0 11.0 3R 474 475 10.0 10.0 3R 475 476 10.0 10.0 3R 476 477 10.0 10.0 3R 477 478 9.0 12.0 3R 478 479 9.0 12.0 3R 479 480 8.0 12.0 3R 480 481 8.0 12.0 3R 481 482 8.0 12.0 3R 482 483 8.0 13.0 3R 483 484 8.0 13.0 3R 484 485 8.0 13.0 3R 485 486 8.0 13.0 3R 486 487 6.0 11.0 3R 487 488 7.0 11.0 3R 488 489 7.0 11.0 3R 489 490 7.0 11.0 3R 490 491 7.0 11.0 3R 491 492 7.0 11.0 3R 492 493 7.0 12.0 3R 493 494 7.0 11.0 3R 494 495 7.0 11.0 3R 495 496 7.0 13.0 3R 496 497 7.0 13.0 3R 497 498 7.0 13.0 3R 498 499 5.0 13.0 3R 499 500 5.0 13.0 3R 500 501 5.0 13.0 3R 501 502 5.0 13.0 3R 502 503 5.0 13.0 3R 503 504 5.0 13.0 3R 504 505 5.0 13.0 3R 505 506 5.0 13.0 3R 506 507 5.0 13.0 3R 507 508 5.0 13.0 3R 508 509 5.0 12.0 3R 509 510 5.0 12.0 3R 510 511 5.0 12.0 3R 511 512 5.0 12.0 3R 512 513 4.0 12.0 3R 513 514 4.0 12.0 3R 514 515 4.0 11.0 3R 515 516 4.0 11.0 3R 516 517 4.0 9.0 3R 517 518 3.0 8.0 3R 518 519 3.0 8.0 3R 519 520 3.0 8.0 3R 520 521 3.0 8.0 3R 521 522 3.0 7.0 3R 522 523 2.0 7.0 3R 523 524 3.0 7.0 3R 524 525 3.0 6.0 3R 525 526 3.0 6.0 3R 526 527 4.0 6.0 3R 527 528 4.0 6.0 3R 528 529 4.0 4.0 3R 529 530 4.0 4.0 3R 530 531 4.0 4.0 3R 531 532 4.0 4.0 3R 532 533 4.0 5.0 3R 533 534 4.0 4.0 3R 534 535 4.0 4.0 3R 535 536 4.0 4.0 3R 536 537 5.0 4.0 3R 537 538 5.0 4.0 3R 538 539 4.0 4.0 3R 539 540 4.0 4.0 3R 540 541 4.0 4.0 3R 541 542 5.0 4.0 3R 542 543 5.0 4.0 3R 543 544 6.0 3.0 3R 544 545 6.0 3.0 3R 545 546 6.0 3.0 3R 546 547 6.0 1.0 3R 547 548 6.0 1.0 3R 548 549 6.0 1.0 3R 549 550 6.0 1.0 3R 550 551 6.0 1.0 3R 551 552 6.0 1.0 3R 552 553 6.0 1.0 3R 553 554 6.0 1.0 3R 554 555 6.0 1.0 3R 555 556 6.0 2.0 3R 556 557 5.0 2.0 3R 557 558 5.0 2.0 3R 558 559 5.0 2.0 3R 559 560 5.0 2.0 3R 560 561 5.0 2.0 3R 561 562 5.0 2.0 3R 562 563 5.0 2.0 3R 563 564 5.0 2.0 3R 564 565 5.0 2.0 3R 565 566 5.0 2.0 3R 566 567 5.0 2.0 3R 567 568 5.0 2.0 3R 568 569 5.0 2.0 3R 569 570 5.0 2.0 3R 570 571 5.0 2.0 3R 571 572 5.0 2.0 3R 572 573 5.0 2.0 3R 573 574 6.0 3.0 3R 574 575 6.0 3.0 3R 575 576 7.0 4.0 3R 576 577 7.0 5.0 3R 577 578 6.0 5.0 3R 578 579 6.0 5.0 3R 579 580 7.0 8.0 3R 580 581 7.0 9.0 3R 581 582 7.0 9.0 3R 582 583 7.0 9.0 3R 583 584 8.0 8.0 3R 584 585 8.0 8.0 3R 585 586 8.0 8.0 3R 586 587 8.0 10.0 3R 587 588 9.0 11.0 3R 588 589 9.0 11.0 3R 589 590 9.0 12.0 3R 590 591 10.0 12.0 3R 591 592 10.0 12.0 3R 592 593 9.0 12.0 3R 593 594 9.0 13.0 3R 594 595 8.0 14.0 3R 595 596 8.0 14.0 3R 596 597 8.0 14.0 3R 597 598 8.0 14.0 3R 598 599 8.0 14.0 3R 599 600 8.0 16.0 3R 600 601 8.0 16.0 3R 601 602 9.0 16.0 3R 602 603 9.0 16.0 3R 603 604 9.0 16.0 3R 604 605 9.0 16.0 3R 605 606 12.0 17.0 3R 606 607 13.0 19.0 3R 607 608 13.0 19.0 3R 608 609 14.0 19.0 3R 609 610 14.0 19.0 3R 610 611 14.0 19.0 3R 611 612 14.0 20.0 3R 612 613 14.0 20.0 3R 613 614 14.0 20.0 3R 614 615 14.0 20.0 3R 615 616 14.0 22.0 3R 616 617 14.0 22.0 3R 617 618 14.0 22.0 3R 618 619 14.0 22.0 3R 619 620 14.0 22.0 3R 620 621 14.0 22.0 3R 621 622 14.0 22.0 3R 622 623 14.0 22.0 3R 623 624 14.0 22.0 3R 624 625 13.0 21.0 3R 625 626 12.0 22.0 3R 626 627 11.0 21.0 3R 627 628 11.0 22.0 3R 628 629 11.0 23.0 3R 629 630 11.0 23.0 3R 630 631 10.0 20.0 3R 631 632 10.0 19.0 3R 632 633 10.0 19.0 3R 633 634 10.0 19.0 3R 634 635 9.0 19.0 3R 635 636 9.0 20.0 3R 636 637 9.0 20.0 3R 637 638 9.0 19.0 3R 638 639 8.0 18.0 3R 639 640 8.0 18.0 3R 640 641 8.0 17.0 3R 641 642 7.0 17.0 3R 642 643 7.0 18.0 3R 643 644 7.0 18.0 3R 644 645 7.0 17.0 3R 645 646 7.0 17.0 3R 646 647 7.0 17.0 3R 647 648 7.0 17.0 3R 648 649 7.0 17.0 3R 649 650 7.0 17.0 3R 650 651 7.0 15.0 3R 651 652 7.0 15.0 3R 652 653 6.0 15.0 3R 653 654 7.0 16.0 3R 654 655 7.0 16.0 3R 655 656 8.0 16.0 3R 656 657 6.0 15.0 3R 657 658 5.0 12.0 3R 658 659 5.0 12.0 3R 659 660 4.0 12.0 3R 660 661 5.0 12.0 3R 661 662 5.0 13.0 3R 662 663 5.0 12.0 3R 663 664 5.0 12.0 3R 664 665 5.0 12.0 3R 665 666 5.0 12.0 3R 666 667 5.0 10.0 3R 667 668 5.0 10.0 3R 668 669 5.0 10.0 3R 669 670 5.0 10.0 3R 670 671 5.0 10.0 3R 671 672 5.0 10.0 3R 672 673 5.0 10.0 3R 673 674 5.0 12.0 3R 674 675 5.0 13.0 3R 675 676 5.0 13.0 3R 676 677 6.0 13.0 3R 677 678 6.0 13.0 3R 678 679 6.0 11.0 3R 679 680 6.0 10.0 3R 680 681 6.0 10.0 3R 681 682 6.0 10.0 3R 682 683 6.0 10.0 3R 683 684 6.0 10.0 3R 684 685 6.0 10.0 3R 685 686 6.0 10.0 3R 686 687 6.0 9.0 3R 687 688 6.0 9.0 3R 688 689 8.0 8.0 3R 689 690 7.0 8.0 3R 690 691 7.0 8.0 3R 691 692 7.0 8.0 3R 692 693 7.0 8.0 3R 693 694 7.0 7.0 3R 694 695 7.0 7.0 3R 695 696 7.0 7.0 3R 696 697 7.0 6.0 3R 697 698 7.0 6.0 3R 698 699 8.0 7.0 3R 699 700 8.0 7.0 3R 700 701 8.0 7.0 3R 701 702 8.0 7.0 3R 702 703 8.0 7.0 3R 703 704 8.0 7.0 3R 704 705 7.0 7.0 3R 705 706 8.0 9.0 3R 706 707 7.0 9.0 3R 707 708 6.0 10.0 3R 708 709 8.0 10.0 3R 709 710 8.0 10.0 3R 710 711 9.0 10.0 3R 711 712 8.0 10.0 3R 712 713 8.0 9.0 3R 713 714 8.0 9.0 3R 714 715 8.0 9.0 3R 715 716 8.0 9.0 3R 716 717 8.0 9.0 3R 717 718 8.0 9.0 3R 718 719 8.0 10.0 3R 719 720 8.0 10.0 3R 720 721 8.0 10.0 3R 721 722 8.0 11.0 3R 722 723 9.0 12.0 3R 723 724 9.0 12.0 3R 724 725 12.0 14.0 3R 725 726 12.0 13.0 3R 726 727 13.0 13.0 3R 727 728 12.0 12.0 3R 728 729 13.0 12.0 3R 729 730 14.0 12.0 3R 730 731 14.0 14.0 3R 731 732 14.0 15.0 3R 732 733 14.0 15.0 3R 733 734 14.0 15.0 3R 734 735 14.0 15.0 3R 735 736 14.0 15.0 3R 736 737 14.0 15.0 3R 737 738 14.0 15.0 3R 738 739 14.0 15.0 3R 739 740 12.0 15.0 3R 740 741 12.0 15.0 3R 741 742 12.0 15.0 3R 742 743 12.0 15.0 3R 743 744 12.0 15.0 3R 744 745 12.0 15.0 3R 745 746 12.0 15.0 3R 746 747 12.0 15.0 3R 747 748 12.0 15.0 3R 748 749 12.0 16.0 3R 749 750 11.0 16.0 3R 750 751 11.0 16.0 3R 751 752 11.0 17.0 3R 752 753 11.0 18.0 3R 753 754 12.0 18.0 3R 754 755 12.0 18.0 3R 755 756 12.0 17.0 3R 756 757 11.0 16.0 3R 757 758 11.0 16.0 3R 758 759 11.0 15.0 3R 759 760 10.0 15.0 3R 760 761 10.0 15.0 3R 761 762 9.0 15.0 3R 762 763 9.0 17.0 3R 763 764 9.0 17.0 3R 764 765 9.0 17.0 3R 765 766 9.0 17.0 3R 766 767 10.0 18.0 3R 767 768 10.0 18.0 3R 768 769 11.0 19.0 3R 769 770 11.0 19.0 3R 770 771 11.0 19.0 3R 771 772 11.0 19.0 3R 772 773 11.0 19.0 3R 773 774 10.0 19.0 3R 774 775 12.0 19.0 3R 775 776 9.0 15.0 3R 776 777 9.0 15.0 3R 777 778 8.0 15.0 3R 778 779 8.0 15.0 3R 779 780 7.0 15.0 3R 780 781 6.0 15.0 3R 781 782 6.0 13.0 3R 782 783 6.0 12.0 3R 783 784 6.0 12.0 3R 784 785 6.0 12.0 3R 785 786 6.0 12.0 3R 786 787 6.0 12.0 3R 787 788 6.0 12.0 3R 788 789 6.0 12.0 3R 789 790 6.0 12.0 3R 790 791 6.0 12.0 3R 791 792 6.0 12.0 3R 792 793 6.0 12.0 3R 793 794 6.0 12.0 3R 794 795 6.0 12.0 3R 795 796 6.0 12.0 3R 796 797 6.0 12.0 3R 797 798 6.0 12.0 3R 798 799 6.0 12.0 3R 799 800 6.0 11.0 3R 800 801 6.0 10.0 3R 801 802 6.0 10.0 3R 802 803 6.0 9.0 3R 803 804 6.0 8.0 3R 804 805 5.0 8.0 3R 805 806 5.0 8.0 3R 806 807 5.0 8.0 3R 807 808 5.0 7.0 3R 808 809 5.0 7.0 3R 809 810 5.0 7.0 3R 810 811 4.0 7.0 3R 811 812 4.0 7.0 3R 812 813 4.0 7.0 3R 813 814 4.0 5.0 3R 814 815 4.0 5.0 3R 815 816 4.0 5.0 3R 816 817 4.0 5.0 3R 817 818 3.0 4.0 3R 818 819 3.0 4.0 3R 819 820 2.0 3.0 3R 820 821 2.0 2.0 3R 821 822 2.0 2.0 3R 822 823 2.0 2.0 3R 823 824 3.0 1.0 3R 824 825 3.0 0.0 3R 825 826 1.0 1.0 3R 826 827 1.0 2.0 3R 827 828 1.0 2.0 3R 828 829 1.0 3.0 3R 829 830 1.0 3.0 3R 830 831 1.0 3.0 3R 831 832 1.0 3.0 3R 832 833 1.0 4.0 3R 833 834 1.0 4.0 3R 834 835 1.0 4.0 3R 835 836 1.0 4.0 3R 836 837 1.0 4.0 3R 837 838 1.0 4.0 3R 838 839 1.0 4.0 3R 839 840 1.0 4.0 3R 840 841 2.0 5.0 3R 841 842 3.0 6.0 3R 842 843 3.0 6.0 3R 843 844 3.0 6.0 3R 844 845 3.0 7.0 3R 845 846 3.0 7.0 3R 846 847 3.0 7.0 3R 847 848 3.0 7.0 3R 848 849 3.0 7.0 3R 849 850 3.0 7.0 3R 850 851 3.0 7.0 3R 851 852 3.0 8.0 3R 852 853 3.0 8.0 3R 853 854 3.0 8.0 3R 854 855 3.0 8.0 3R 855 856 3.0 8.0 3R 856 857 3.0 8.0 3R 857 858 3.0 9.0 3R 858 859 5.0 10.0 3R 859 860 5.0 10.0 3R 860 861 5.0 10.0 3R 861 862 5.0 11.0 3R 862 863 5.0 11.0 3R 863 864 5.0 11.0 3R 864 865 6.0 11.0 3R 865 866 6.0 11.0 3R 866 867 6.0 11.0 3R 867 868 15.0 11.0 3R 868 869 15.0 11.0 3R 869 870 15.0 11.0 3R 870 871 15.0 11.0 3R 871 872 15.0 11.0 3R 872 873 16.0 13.0 3R 873 874 16.0 14.0 3R 874 875 16.0 15.0 3R 875 876 19.0 15.0 3R 876 877 19.0 14.0 3R 877 878 20.0 13.0 3R 878 879 20.0 13.0 3R 879 880 21.0 12.0 3R 880 881 21.0 12.0 3R 881 882 21.0 12.0 3R 882 883 21.0 12.0 3R 883 884 22.0 11.0 3R 884 885 23.0 11.0 3R 885 886 23.0 11.0 3R 886 887 23.0 11.0 3R 887 888 23.0 11.0 3R 888 889 23.0 11.0 3R 889 890 23.0 11.0 3R 890 891 25.0 11.0 3R 891 892 24.0 10.0 3R 892 893 23.0 9.0 3R 893 894 23.0 9.0 3R 894 895 23.0 9.0 3R 895 896 23.0 9.0 3R 896 897 23.0 9.0 3R 897 898 23.0 9.0 3R 898 899 23.0 9.0 3R 899 900 24.0 9.0 3R 900 901 24.0 10.0 3R 901 902 25.0 10.0 3R 902 903 25.0 9.0 3R 903 904 25.0 9.0 3R 904 905 25.0 10.0 3R 905 906 25.0 10.0 3R 906 907 25.0 11.0 3R 907 908 25.0 11.0 3R 908 909 25.0 10.0 3R 909 910 23.0 9.0 3R 910 911 23.0 9.0 3R 911 912 23.0 9.0 3R 912 913 23.0 8.0 3R 913 914 24.0 8.0 3R 914 915 25.0 8.0 3R 915 916 24.0 8.0 3R 916 917 24.0 8.0 3R 917 918 24.0 8.0 3R 918 919 16.0 8.0 3R 919 920 16.0 8.0 3R 920 921 16.0 8.0 3R 921 922 16.0 8.0 3R 922 923 16.0 9.0 3R 923 924 16.0 7.0 3R 924 925 16.0 6.0 3R 925 926 15.0 5.0 3R 926 927 12.0 5.0 3R 927 928 12.0 5.0 3R 928 929 11.0 5.0 3R 929 930 12.0 5.0 3R 930 931 11.0 5.0 3R 931 932 11.0 5.0 3R 932 933 11.0 5.0 3R 933 934 11.0 5.0 3R 934 935 10.0 5.0 3R 935 936 9.0 5.0 3R 936 937 9.0 5.0 3R 937 938 9.0 5.0 3R 938 939 9.0 5.0 3R 939 940 9.0 5.0 3R 940 941 9.0 5.0 3R 941 942 7.0 5.0 3R 942 943 7.0 5.0 3R 943 944 7.0 5.0 3R 944 945 7.0 5.0 3R 945 946 7.0 5.0 3R 946 947 7.0 4.0 3R 947 948 7.0 4.0 3R 948 949 7.0 4.0 3R 949 950 7.0 4.0 3R 950 951 6.0 4.0 3R 951 952 6.0 4.0 3R 952 953 5.0 4.0 3R 953 954 5.0 4.0 3R 954 955 5.0 4.0 3R 955 956 5.0 3.0 3R 956 957 5.0 3.0 3R 957 958 5.0 2.0 3R 958 959 5.0 2.0 3R 959 960 5.0 2.0 3R 960 961 5.0 2.0 3R 961 962 5.0 2.0 3R 962 963 5.0 2.0 3R 963 964 5.0 2.0 3R 964 965 4.0 2.0 3R 965 966 3.0 2.0 3R 966 967 3.0 3.0 3R 967 968 3.0 3.0 3R 968 969 3.0 3.0 3R 969 970 3.0 3.0 3R 970 971 3.0 3.0 3R 971 972 3.0 3.0 3R 972 973 3.0 3.0 3R 973 974 3.0 2.0 3R 974 975 2.0 2.0 3R 975 976 2.0 2.0 3R 976 977 2.0 2.0 3R 977 978 2.0 2.0 3R 978 979 2.0 2.0 3R 979 980 2.0 2.0 3R 980 981 1.0 2.0 3R 981 982 1.0 2.0 3R 982 983 1.0 2.0 3R 983 984 1.0 2.0 3R 984 985 1.0 2.0 3R 985 986 1.0 2.0 3R 986 987 1.0 2.0 3R 987 988 1.0 2.0 3R 988 989 1.0 2.0 3R 989 990 1.0 2.0 3R 990 991 1.0 2.0 3R 991 992 1.0 2.0 3R 992 993 1.0 3.0 3R 993 994 1.0 3.0 3R 994 995 1.0 4.0 3R 995 996 1.0 4.0 3R 996 997 1.0 4.0 3R 997 998 1.0 5.0 3R 998 999 1.0 5.0 3R 999 1000 1.0 5.0 3R 1000 1001 1.0 5.0 3R 1001 1002 1.0 5.0 3R 1002 1003 1.0 4.0 3R 1003 1004 1.0 4.0 3R 1004 1005 1.0 4.0 3R 1005 1006 1.0 4.0 3R 1006 1007 1.0 4.0 3R 1007 1008 1.0 4.0 3R 1008 1009 1.0 4.0 3R 1009 1010 1.0 4.0 3R 1010 1011 1.0 4.0 3R 1011 1012 1.0 4.0 3R 1012 1013 1.0 4.0 3R 1013 1014 1.0 4.0 3R 1014 1015 1.0 4.0 3R 1015 1016 1.0 4.0 3R 1016 1017 1.0 4.0 3R 1017 1018 1.0 3.0 3R 1018 1019 1.0 3.0 3R 1019 1020 1.0 3.0 3R 1020 1021 0.0 3.0 3R 1021 1022 0.0 3.0 3R 1022 1023 0.0 3.0 3R 1023 1024 0.0 3.0 3R 1024 1025 0.0 3.0 3R 1025 1026 0.0 3.0 3R 1026 1027 0.0 3.0 3R 1027 1028 0.0 3.0 3R 1028 1029 0.0 3.0 3R 1029 1030 0.0 3.0 3R 1030 1031 0.0 3.0 3R 1031 1032 0.0 3.0 3R 1032 1033 0.0 3.0 3R 1033 1034 0.0 3.0 3R 1034 1035 0.0 3.0 3R 1035 1036 0.0 3.0 3R 1036 1037 0.0 3.0 3R 1037 1038 0.0 3.0 3R 1038 1039 0.0 3.0 3R 1039 1040 0.0 3.0 3R 1040 1041 0.0 3.0 3R 1041 1042 0.0 3.0 3R 1042 1043 0.0 3.0 3R 1043 1044 0.0 2.0 3R 1044 1045 0.0 2.0 3R 1045 1046 0.0 1.0 3R 1046 1047 0.0 1.0 3R 1047 1048 0.0 1.0 3R 1048 1049 0.0 0.0 3R 1049 1050 0.0 0.0 3R 1050 1051 0.0 0.0 3R 1051 1052 0.0 0.0 3R 1052 1053 0.0 0.0 3R 1053 1054 0.0 0.0 3R 1054 1055 0.0 0.0 3R 1055 1056 0.0 0.0 3R 1056 1057 0.0 0.0 3R 1057 1058 0.0 0.0 3R 1058 1059 0.0 0.0 3R 1059 1060 0.0 0.0 3R 1060 1061 0.0 0.0 3R 1061 1062 0.0 0.0 3R 1062 1063 0.0 0.0 3R 1063 1064 0.0 0.0 3R 1064 1065 0.0 0.0 3R 1065 1066 0.0 0.0 3R 1066 1067 0.0 0.0 3R 1067 1068 0.0 0.0 3R 1068 1069 0.0 0.0 3R 1069 1070 0.0 0.0 3R 1070 1071 0.0 0.0 3R 1071 1072 0.0 0.0 3R 1072 1073 0.0 0.0 3R 1073 1074 0.0 0.0 3R 1074 1075 0.0 0.0 3R 1075 1076 0.0 0.0 3R 1076 1077 0.0 0.0 3R 1077 1078 0.0 0.0 3R 1078 1079 0.0 0.0 3R 1079 1080 0.0 0.0 3R 1080 1081 0.0 0.0 3R 1081 1082 0.0 0.0 3R 1082 1083 0.0 0.0 3R 1083 1084 0.0 0.0 3R 1084 1085 0.0 0.0 3R 1085 1086 0.0 0.0 3R 1086 1087 0.0 0.0 3R 1087 1088 0.0 0.0 3R 1088 1089 0.0 0.0 3R 1089 1090 0.0 0.0 3R 1090 1091 0.0 0.0 3R 1091 1092 0.0 0.0 3R 1092 1093 0.0 0.0 3R 1093 1094 0.0 0.0 3R 1094 1095 0.0 0.0 3R 1095 1096 0.0 0.0 3R 1096 1097 0.0 0.0 3R 1097 1098 0.0 0.0 3R 1098 1099 0.0 0.0 3R 1099 1100 0.0 0.0 3R 1100 1101 0.0 0.0 3R 1101 1102 0.0 0.0 3R 1102 1103 0.0 0.0 3R 1103 1104 0.0 0.0 3R 1104 1105 0.0 0.0 3R 1105 1106 0.0 0.0 3R 1106 1107 0.0 0.0 3R 1107 1108 0.0 0.0 3R 1108 1109 0.0 0.0 3R 1109 1110 0.0 0.0 3R 1110 1111 0.0 0.0 3R 1111 1112 0.0 0.0 3R 1112 1113 0.0 0.0 3R 1113 1114 0.0 0.0 3R 1114 1115 0.0 0.0 3R 1115 1116 0.0 0.0 3R 1116 1117 0.0 0.0 3R 1117 1118 0.0 0.0 3R 1118 1119 0.0 0.0 3R 1119 1120 0.0 0.0 3R 1120 1121 0.0 0.0 3R 1121 1122 0.0 0.0 3R 1122 1123 0.0 0.0 3R 1123 1124 0.0 0.0 3R 1124 1125 0.0 0.0 3R 1125 1126 0.0 0.0 3R 1126 1127 0.0 0.0 3R 1127 1128 0.0 0.0 3R 1128 1129 0.0 0.0 3R 1129 1130 0.0 0.0 3R 1130 1131 0.0 0.0 3R 1131 1132 0.0 0.0 3R 1132 1133 0.0 0.0 3R 1133 1134 0.0 0.0 3R 1134 1135 0.0 0.0 3R 1135 1136 0.0 0.0 3R 1136 1137 0.0 0.0 3R 1137 1138 0.0 0.0 3R 1138 1139 0.0 0.0 3R 1139 1140 0.0 0.0 3R 1140 1141 0.0 0.0 3R 1141 1142 0.0 0.0 3R 1142 1143 0.0 0.0 3R 1143 1144 0.0 0.0 3R 1144 1145 0.0 0.0 3R 1145 1146 0.0 0.0 3R 1146 1147 0.0 0.0 3R 1147 1148 0.0 0.0 3R 1148 1149 0.0 0.0 3R 1149 1150 0.0 0.0 3R 1150 1151 0.0 0.0 3R 1151 1152 0.0 0.0 3R 1152 1153 0.0 0.0 3R 1153 1154 0.0 0.0 3R 1154 1155 0.0 0.0 3R 1155 1156 0.0 0.0 3R 1156 1157 0.0 0.0 3R 1157 1158 0.0 0.0 3R 1158 1159 0.0 0.0 3R 1159 1160 0.0 0.0 3R 1160 1161 0.0 0.0 3R 1161 1162 0.0 0.0 3R 1162 1163 0.0 0.0 3R 1163 1164 0.0 0.0 3R 1164 1165 0.0 0.0 3R 1165 1166 0.0 0.0 3R 1166 1167 0.0 0.0 3R 1167 1168 0.0 0.0 3R 1168 1169 0.0 0.0 3R 1169 1170 0.0 0.0 3R 1170 1171 0.0 0.0 3R 1171 1172 0.0 0.0 3R 1172 1173 0.0 0.0 3R 1173 1174 0.0 0.0 3R 1174 1175 0.0 0.0 3R 1175 1176 0.0 0.0 3R 1176 1177 0.0 0.0 3R 1177 1178 0.0 0.0 3R 1178 1179 0.0 0.0 3R 1179 1180 0.0 0.0 3R 1180 1181 0.0 0.0 3R 1181 1182 0.0 0.0 3R 1182 1183 0.0 0.0 3R 1183 1184 0.0 0.0 3R 1184 1185 0.0 0.0 3R 1185 1186 0.0 0.0 3R 1186 1187 0.0 0.0 3R 1187 1188 0.0 0.0 3R 1188 1189 0.0 0.0 3R 1189 1190 0.0 0.0 3R 1190 1191 0.0 0.0 3R 1191 1192 0.0 0.0 3R 1192 1193 0.0 0.0 3R 1193 1194 0.0 0.0 3R 1194 1195 0.0 0.0 3R 1195 1196 0.0 0.0 3R 1196 1197 0.0 0.0 3R 1197 1198 0.0 0.0 3R 1198 1199 0.0 0.0 3R 1199 1200 0.0 0.0 3R 1200 1201 0.0 0.0 3R 1201 1202 0.0 0.0 3R 1202 1203 0.0 0.0 3R 1203 1204 0.0 0.0 3R 1204 1205 0.0 0.0 3R 1205 1206 0.0 0.0 3R 1206 1207 0.0 0.0 3R 1207 1208 0.0 0.0 3R 1208 1209 0.0 0.0 3R 1209 1210 0.0 0.0 3R 1210 1211 0.0 0.0 3R 1211 1212 0.0 0.0 3R 1212 1213 0.0 0.0 3R 1213 1214 0.0 0.0 3R 1214 1215 0.0 0.0 3R 1215 1216 0.0 0.0 3R 1216 1217 0.0 0.0 3R 1217 1218 0.0 0.0 3R 1218 1219 0.0 0.0 3R 1219 1220 0.0 0.0 3R 1220 1221 0.0 0.0 3R 1221 1222 0.0 0.0 3R 1222 1223 0.0 0.0 3R 1223 1224 0.0 0.0 3R 1224 1225 0.0 0.0 3R 1225 1226 0.0 0.0 3R 1226 1227 0.0 0.0 3R 1227 1228 0.0 0.0 3R 1228 1229 0.0 0.0 3R 1229 1230 0.0 0.0 3R 1230 1231 0.0 0.0 3R 1231 1232 0.0 0.0 3R 1232 1233 0.0 0.0 3R 1233 1234 0.0 0.0 3R 1234 1235 0.0 0.0 3R 1235 1236 0.0 0.0 3R 1236 1237 0.0 0.0 3R 1237 1238 0.0 0.0 3R 1238 1239 0.0 0.0 3R 1239 1240 0.0 0.0 3R 1240 1241 0.0 0.0 3R 1241 1242 0.0 0.0 3R 1242 1243 0.0 0.0 3R 1243 1244 0.0 0.0 3R 1244 1245 0.0 0.0 3R 1245 1246 0.0 0.0 3R 1246 1247 0.0 0.0 3R 1247 1248 0.0 0.0 3R 1248 1249 0.0 0.0 3R 1249 1250 0.0 0.0 3R 1250 1251 0.0 0.0 3R 1251 1252 0.0 0.0 3R 1252 1253 0.0 0.0 3R 1253 1254 0.0 0.0 3R 1254 1255 0.0 0.0 3R 1255 1256 0.0 0.0 3R 1256 1257 0.0 0.0 3R 1257 1258 0.0 0.0 3R 1258 1259 0.0 0.0 3R 1259 1260 0.0 0.0 3R 1260 1261 0.0 0.0 3R 1261 1262 0.0 0.0 3R 1262 1263 0.0 0.0 3R 1263 1264 0.0 0.0 3R 1264 1265 0.0 0.0 3R 1265 1266 0.0 0.0 3R 1266 1267 0.0 0.0 3R 1267 1268 0.0 0.0 3R 1268 1269 0.0 0.0 3R 1269 1270 0.0 0.0 3R 1270 1271 0.0 0.0 3R 1271 1272 0.0 0.0 3R 1272 1273 0.0 0.0 3R 1273 1274 0.0 0.0 3R 1274 1275 0.0 0.0 3R 1275 1276 0.0 0.0 3R 1276 1277 0.0 0.0 3R 1277 1278 0.0 0.0 3R 1278 1279 0.0 0.0 3R 1279 1280 0.0 0.0 3R 1280 1281 0.0 0.0 3R 1281 1282 0.0 0.0 3R 1282 1283 0.0 0.0 3R 1283 1284 0.0 0.0 3R 1284 1285 0.0 0.0 3R 1285 1286 0.0 0.0 3R 1286 1287 0.0 0.0 3R 1287 1288 0.0 0.0 3R 1288 1289 0.0 0.0 3R 1289 1290 0.0 0.0 3R 1290 1291 0.0 0.0 3R 1291 1292 0.0 0.0 3R 1292 1293 0.0 0.0 3R 1293 1294 0.0 0.0 3R 1294 1295 0.0 0.0 3R 1295 1296 0.0 0.0 3R 1296 1297 0.0 0.0 3R 1297 1298 0.0 0.0 3R 1298 1299 0.0 0.0 3R 1299 1300 0.0 0.0 3R 1300 1301 0.0 0.0 3R 1301 1302 0.0 0.0 3R 1302 1303 0.0 0.0 3R 1303 1304 0.0 0.0 3R 1304 1305 0.0 0.0 3R 1305 1306 0.0 0.0 3R 1306 1307 0.0 0.0 3R 1307 1308 0.0 0.0 3R 1308 1309 0.0 0.0 3R 1309 1310 0.0 0.0 3R 1310 1311 0.0 0.0 3R 1311 1312 0.0 0.0 3R 1312 1313 0.0 0.0 3R 1313 1314 0.0 0.0 3R 1314 1315 0.0 0.0 3R 1315 1316 0.0 0.0 3R 1316 1317 0.0 0.0 3R 1317 1318 0.0 0.0 3R 1318 1319 0.0 0.0 3R 1319 1320 0.0 0.0 3R 1320 1321 0.0 0.0 3R 1321 1322 0.0 0.0 3R 1322 1323 0.0 0.0 3R 1323 1324 0.0 0.0 3R 1324 1325 0.0 0.0 3R 1325 1326 0.0 0.0 3R 1326 1327 0.0 0.0 3R 1327 1328 0.0 0.0 3R 1328 1329 0.0 0.0 3R 1329 1330 0.0 0.0 3R 1330 1331 0.0 0.0 3R 1331 1332 0.0 0.0 3R 1332 1333 0.0 0.0 3R 1333 1334 0.0 0.0 3R 1334 1335 0.0 0.0 3R 1335 1336 0.0 0.0 3R 1336 1337 0.0 0.0 3R 1337 1338 0.0 0.0 3R 1338 1339 0.0 0.0 3R 1339 1340 0.0 0.0 3R 1340 1341 0.0 0.0 3R 1341 1342 0.0 0.0 3R 1342 1343 0.0 0.0 3R 1343 1344 0.0 0.0 3R 1344 1345 0.0 0.0 3R 1345 1346 0.0 0.0 3R 1346 1347 0.0 0.0 3R 1347 1348 0.0 0.0 3R 1348 1349 0.0 0.0 3R 1349 1350 0.0 0.0 3R 1350 1351 0.0 0.0 3R 1351 1352 0.0 0.0 3R 1352 1353 0.0 0.0 3R 1353 1354 0.0 0.0 3R 1354 1355 0.0 0.0 3R 1355 1356 0.0 0.0 3R 1356 1357 0.0 0.0 3R 1357 1358 0.0 0.0 3R 1358 1359 0.0 0.0 3R 1359 1360 0.0 0.0 3R 1360 1361 0.0 0.0 3R 1361 1362 0.0 0.0 3R 1362 1363 0.0 0.0 3R 1363 1364 0.0 0.0 3R 1364 1365 0.0 0.0 3R 1365 1366 0.0 0.0 3R 1366 1367 0.0 0.0 3R 1367 1368 0.0 0.0 3R 1368 1369 0.0 0.0 3R 1369 1370 0.0 0.0 3R 1370 1371 0.0 0.0 3R 1371 1372 0.0 0.0 3R 1372 1373 0.0 0.0 3R 1373 1374 0.0 0.0 3R 1374 1375 0.0 0.0 3R 1375 1376 0.0 0.0 3R 1376 1377 0.0 0.0 3R 1377 1378 0.0 0.0 3R 1378 1379 0.0 0.0 3R 1379 1380 0.0 0.0 3R 1380 1381 0.0 0.0 3R 1381 1382 0.0 0.0 3R 1382 1383 0.0 0.0 3R 1383 1384 0.0 0.0 3R 1384 1385 0.0 0.0 3R 1385 1386 0.0 0.0 3R 1386 1387 0.0 0.0 3R 1387 1388 0.0 0.0 3R 1388 1389 0.0 0.0 3R 1389 1390 0.0 0.0 3R 1390 1391 0.0 0.0 3R 1391 1392 0.0 0.0 3R 1392 1393 0.0 0.0 3R 1393 1394 0.0 0.0 3R 1394 1395 0.0 0.0 3R 1395 1396 0.0 0.0 3R 1396 1397 0.0 0.0 3R 1397 1398 0.0 0.0 3R 1398 1399 0.0 0.0 3R 1399 1400 0.0 0.0 3R 1400 1401 0.0 0.0 3R 1401 1402 0.0 0.0 3R 1402 1403 0.0 0.0 3R 1403 1404 0.0 0.0 3R 1404 1405 0.0 0.0 3R 1405 1406 0.0 0.0 3R 1406 1407 0.0 0.0 3R 1407 1408 0.0 0.0 3R 1408 1409 0.0 0.0 3R 1409 1410 0.0 0.0 3R 1410 1411 0.0 0.0 3R 1411 1412 0.0 0.0 3R 1412 1413 0.0 0.0 3R 1413 1414 0.0 0.0 3R 1414 1415 0.0 0.0 3R 1415 1416 0.0 0.0 3R 1416 1417 0.0 0.0 3R 1417 1418 0.0 0.0 3R 1418 1419 0.0 0.0 3R 1419 1420 0.0 0.0 3R 1420 1421 0.0 0.0 3R 1421 1422 0.0 0.0 3R 1422 1423 0.0 0.0 3R 1423 1424 0.0 0.0 3R 1424 1425 0.0 0.0 3R 1425 1426 0.0 0.0 3R 1426 1427 0.0 0.0 3R 1427 1428 0.0 0.0 3R 1428 1429 0.0 0.0 3R 1429 1430 0.0 0.0 3R 1430 1431 0.0 0.0 3R 1431 1432 0.0 0.0 3R 1432 1433 0.0 0.0 3R 1433 1434 0.0 0.0 3R 1434 1435 0.0 0.0 3R 1435 1436 0.0 0.0 3R 1436 1437 0.0 0.0 3R 1437 1438 0.0 0.0 3R 1438 1439 0.0 0.0 3R 1439 1440 0.0 0.0 3R 1440 1441 0.0 0.0 3R 1441 1442 0.0 0.0 3R 1442 1443 0.0 0.0 3R 1443 1444 0.0 0.0 3R 1444 1445 0.0 0.0 3R 1445 1446 0.0 0.0 3R 1446 1447 0.0 0.0 3R 1447 1448 0.0 0.0 3R 1448 1449 0.0 0.0 3R 1449 1450 0.0 0.0 3R 1450 1451 0.0 0.0 3R 1451 1452 0.0 0.0 3R 1452 1453 0.0 0.0 3R 1453 1454 0.0 0.0 3R 1454 1455 0.0 0.0 3R 1455 1456 0.0 0.0 3R 1456 1457 0.0 0.0 3R 1457 1458 0.0 0.0 3R 1458 1459 0.0 0.0 3R 1459 1460 0.0 0.0 3R 1460 1461 0.0 0.0 3R 1461 1462 0.0 0.0 3R 1462 1463 0.0 0.0 3R 1463 1464 0.0 0.0 3R 1464 1465 0.0 0.0 3R 1465 1466 0.0 0.0 3R 1466 1467 0.0 0.0 3R 1467 1468 0.0 0.0 3R 1468 1469 0.0 0.0 3R 1469 1470 0.0 0.0 3R 1470 1471 0.0 0.0 3R 1471 1472 0.0 0.0 3R 1472 1473 0.0 0.0 3R 1473 1474 0.0 0.0 3R 1474 1475 0.0 0.0 3R 1475 1476 0.0 0.0 3R 1476 1477 0.0 0.0 3R 1477 1478 0.0 0.0 3R 1478 1479 0.0 0.0 3R 1479 1480 0.0 0.0 3R 1480 1481 0.0 0.0 3R 1481 1482 0.0 0.0 3R 1482 1483 0.0 0.0 3R 1483 1484 0.0 0.0 3R 1484 1485 0.0 0.0 3R 1485 1486 0.0 0.0 3R 1486 1487 0.0 0.0 3R 1487 1488 0.0 0.0 3R 1488 1489 0.0 0.0 3R 1489 1490 0.0 0.0 3R 1490 1491 0.0 0.0 3R 1491 1492 0.0 0.0 3R 1492 1493 0.0 0.0 3R 1493 1494 0.0 0.0 3R 1494 1495 0.0 0.0 3R 1495 1496 0.0 0.0 3R 1496 1497 0.0 0.0 3R 1497 1498 0.0 0.0 3R 1498 1499 0.0 0.0 3R 1499 1500 0.0 0.0 deepTools-2.5.0/deeptools/test/test_plotCoverage/plotCoverage_default.svg0000640000201600010240000005774613006372704026170 0ustar ryanbioinfo 0 5 10 15 20 coverage (#reads per bp) 0.000 0.005 0.010 0.015 0.020 0.025 0.030 0.035 0.040 fraction of bases sampled test1.bam, mean=4.9 test2.bam, mean=6.6 0 5 10 15 20 coverage (#reads per bp) 0.0 0.2 0.4 0.6 0.8 1.0 fraction of bases sampled >= coverage test1.bam test2.bam deepTools-2.5.0/deeptools/test/__init__.py0000750000201600010240000000000012757050135017701 0ustar ryanbioinfodeepTools-2.5.0/deeptools/test/test_bamCoverage_and_bamCompare.py0000640000201600010240000003361713021233660024375 0ustar ryanbioinfofrom nose.tools import assert_equal import deeptools.bamCoverage as bam_cov import deeptools.bamCompare as bam_comp import deeptools.getScaleFactor as gs import os.path import filecmp from os import unlink ROOT = os.path.dirname(os.path.abspath(__file__)) + "/test_data/" BAMFILE_A = ROOT + "testA.bam" BAMFILE_B = ROOT + "testB.bam" BAMFILE_FILTER1 = ROOT + "test_filtering.bam" BAMFILE_FILTER2 = ROOT + "test_filtering2.bam" BEDFILE_FILTER = ROOT + "test_filtering.blacklist.bed" """ The distribution of reads for the bam file is: 0 100 200 |------------------------------------------------------------| testA.bam 3R ==============> <============== testB.bam 3R <============== ==============> ==============> ==============> """ def test_bam_coverage_arguments(): """ Test minimal command line args for bamCoverage """ outfile = '/tmp/test_file.bg' args = "--bam {} -o {} --outFileFormat bedgraph".format(BAMFILE_B, outfile).split() bam_cov.main(args) _foo = open(outfile, 'r') resp = _foo.readlines() _foo.close() expected = ['3R\t0\t50\t0\n', '3R\t50\t150\t1\n', '3R\t150\t200\t2\n'] assert_equal(resp, expected) unlink(outfile) def test_bam_coverage_extend(): outfile = '/tmp/test_file.bg' args = "-b {} -o {} --extendReads 100 --outFileFormat bedgraph".format(BAMFILE_B, outfile).split() bam_cov.main(args) _foo = open(outfile, 'r') resp = _foo.readlines() _foo.close() expected = ['3R\t0\t150\t1\n', '3R\t150\t200\t3\n'] assert_equal(resp, expected) unlink(outfile) def test_bam_coverage_extend_and_normalizeto1x(): outfile = '/tmp/test_file.bg' args = "-b {} -o {} --normalizeTo1x 200 --extendReads 100 " \ "--outFileFormat bedgraph".format(BAMFILE_B, outfile).split() bam_cov.main(args) _foo = open(outfile, 'r') resp = _foo.readlines() _foo.close() # the scale factor should be 0.5, thus the result is similar to # that of the previous test divided by 0.5 expected = ['3R\t0\t150\t0.5\n', '3R\t150\t200\t1.5\n'] assert_equal(resp, expected) unlink(outfile) def test_bam_coverage_skipnas(): outfile = '/tmp/test_file.bg' args = "--bam {} -o {} --outFileFormat bedgraph --skipNAs".format(BAMFILE_B, outfile).split() bam_cov.main(args) _foo = open(outfile, 'r') resp = _foo.readlines() _foo.close() expected = ['3R\t50\t150\t1\n', '3R\t150\t200\t2\n'] assert_equal(resp, expected) unlink(outfile) def test_bam_coverage_filtering(): outfile = '/tmp/test_file.bg' args = "--bam {} -o {} --outFileFormat bedgraph --ignoreDuplicates --verbose".format(BAMFILE_B, outfile).split() bam_cov.main(args) _foo = open(outfile, 'r') resp = _foo.readlines() _foo.close() expected = ['3R\t0\t50\t0\n', '3R\t50\t200\t1\n'] assert_equal(resp, expected) unlink(outfile) def test_bam_compare_arguments(): """ Test minimal command line args for bamCoverage. The ratio between the same file is taken, therefore, the expected value is 1.0 for all bins. """ outfile = '/tmp/test_file.bg' args = "--bamfile1 {} --bamfile2 {} " \ "-o {} -p 1 --outFileFormat bedgraph --ratio ratio".format(BAMFILE_B, BAMFILE_B, outfile).split() bam_comp.main(args) _foo = open(outfile, 'r') resp = _foo.readlines() _foo.close() expected = ['3R\t0\t200\t1\n'] assert_equal(resp, expected) unlink(outfile) def test_bam_compare_diff_files(): """ Test with two different files """ outfile = '/tmp/test_file.bg' args = "--bamfile1 {} --bamfile2 {} --scaleFactors 1:1 --ratio subtract " \ "-o {} -p 1 --outFileFormat bedgraph".format(BAMFILE_A, BAMFILE_B, outfile).split() bam_comp.main(args) _foo = open(outfile, 'r') resp = _foo.readlines() _foo.close() expected = ['3R\t0\t50\t0\n', '3R\t50\t100\t-1\n', '3R\t100\t150\t0\n', '3R\t150\t200\t-1\n'] assert_equal(resp, expected) unlink(outfile) def test_get_num_kept_reads(): """ Test the scale factor functinos """ args = "--bam {} -o /tmp/test".format(BAMFILE_A, BAMFILE_B).split() args = bam_cov.process_args(args) num_kept_reads, total_reads = gs.get_num_kept_reads(args) # bam file 1 has 2 reads in 3R and 2 read in chr_cigar assert num_kept_reads == 3, "num_kept_reads is wrong" assert total_reads == 3, "num total reads is wrong" # ignore chr_cigar to count the total number of reads args = "--bam {} --ignoreForNormalization chr_cigar -o /tmp/test".format(BAMFILE_A, BAMFILE_B).split() args = bam_cov.process_args(args) num_kept_reads, total_reads = gs.get_num_kept_reads(args) # the number of kept reads should be 2 as the read on chr_cigar is skipped assert num_kept_reads == 2, "num_kept_reads is wrong ({})".format(num_kept_reads) # test filtering by read direction. Only forward reads are kept args = "--bam {} -o /tmp/test --samFlagExclude 16 --ignoreForNormalization chr_cigar ".format(BAMFILE_A, BAMFILE_B).split() args = bam_cov.process_args(args) num_kept_reads, total_reads = gs.get_num_kept_reads(args) # only one forward read is expected in assert num_kept_reads == 1, "num_kept_reads is wrong" def test_bam_compare_diff_files_skipnas(): """ Test skipnas Compared to the previous tests, any region that do not have coverage (in either of the bam files) is not included in the bedgraph file. """ outfile = '/tmp/test_file.bg' args = "--bamfile1 {} --bamfile2 {} --scaleFactors 1:1 --ratio subtract " \ "-o {} -p 1 --outFileFormat bedgraph --skipNAs".format(BAMFILE_A, BAMFILE_B, outfile).split() bam_comp.main(args) _foo = open(outfile, 'r') resp = _foo.readlines() _foo.close() expected = ['3R\t100\t150\t0\n', '3R\t150\t200\t-1\n'] assert_equal(resp, expected) unlink(outfile) def test_bam_compare_extend(): """ Test read extension """ outfile = '/tmp/test_file.bg' args = "--bamfile1 {} --bamfile2 {} --extend 100 --scaleFactors 1:1 --ratio subtract " \ "-o {} -p 1 --outFileFormat bedgraph".format(BAMFILE_A, BAMFILE_B, outfile).split() bam_comp.main(args) _foo = open(outfile, 'r') resp = _foo.readlines() _foo.close() expected = ['3R\t0\t100\t-1\n', '3R\t100\t150\t1\n', '3R\t150\t200\t-1\n'] assert_equal(resp, expected) unlink(outfile) def test_bam_compare_scale_factors_ratio(): """ Test scale factor """ outfile = '/tmp/test_file.bg' args = "--bamfile1 {} --bamfile2 {} --ratio ratio --ignoreForNormalization chr_cigar " \ "-o {} -p 1 --outFileFormat bedgraph".format(BAMFILE_A, BAMFILE_B, outfile).split() bam_comp.main(args) # The scale factors are [ 1. 0.5] because BAMFILE_B has dowble the amount of reads (4) compared to BAMFILE_A _foo = open(outfile, 'r') resp = _foo.readlines() _foo.close() """ The distribution of reads for the bam file is: 0 100 200 |------------------------------------------------------------| testA.bam 3R ==============> <============== testB.bam 3R <============== ==============> ==============> ==============> ------------------------------------------------------------------------------ ratio: 0 (0+1)/(1*0.5+1)=0.67 (1+1)/(1+2*0.5)=1 (scale factors [1,0.5]) (1+1)/(1+1*0.5)=1.33 """ expected = ['3R\t0\t50\t1\n', '3R\t50\t100\t0.666667\n', '3R\t100\t150\t1.33333\n', '3R\t150\t200\t1\n'] assert_equal(resp, expected) unlink(outfile) def test_bam_compare_scale_factors_subtract(): """ Test scale factor """ outfile = '/tmp/test_file.bg' args = "--bamfile1 {} --bamfile2 {} --ratio subtract --ignoreForNormalization chr_cigar " \ "-o {} -p 1 --outFileFormat bedgraph --normalizeTo1x 200".format(BAMFILE_A, BAMFILE_B, outfile).split() bam_comp.main(args) # The scale factors are [ 1. 0.5] because BAMFILE_B has dowble the amount of reads (4) compared to BAMFILE_A _foo = open(outfile, 'r') resp = _foo.readlines() _foo.close() """ The distribution of reads for the bam file is: 0 100 200 |------------------------------------------------------------| testA.bam 3R ==============> <============== testB.bam 3R <============== ==============> ==============> ==============> ------------------------------------------------------------------------------ subtract: scale factors [1,0.5], after applying normalize to 1x, coverage of test_A is 0.5, thus the factor to reach a coverate of 1 is x2. Thus, the final scale factors are [2,1] after applying factors: 0 -1 1 0 """ expected = ['3R\t0\t50\t0\n', '3R\t50\t100\t-1\n', '3R\t100\t150\t1\n', '3R\t150\t200\t0\n'] assert_equal(resp, expected) unlink(outfile) def test_bam_coverage_filter_blacklist(): """ Test --samFlagInclude --samFlagExclude --minMappingQuality --ignoreDuplicates and --blackListFileName """ outfile = '/tmp/test_file_filter.bg' args = "--bam {} --normalizeTo1x 1400 -p 1 -o {} -of bedgraph --samFlagInclude 512 " \ "--samFlagExclude 256 --minMappingQuality 5 --ignoreDuplicates " \ "--blackListFileName {}".format(BAMFILE_FILTER1, outfile, BEDFILE_FILTER) args = args.split() bam_cov.main(args) _foo = open(outfile, 'r') resp = _foo.readlines() _foo.close() expected = ['3R\t0\t100\t0\n', '3R\t100\t150\t1.42338\n', '3R\t150\t250\t4.88017\n', '3R\t250\t300\t3.05011\n', '3R\t300\t400\t2.23675\n', '3R\t400\t450\t3.86347\n', '3R\t450\t500\t4.06681\n', '3R\t500\t550\t2.03341\n', '3R\t550\t600\t2.44009\n', '3R\t600\t650\t4.47349\n', '3R\t650\t700\t3.45679\n', '3R\t700\t750\t3.66013\n', '3R\t750\t800\t4.06681\n', '3R\t900\t950\t2.44009\n', '3R\t950\t1000\t1.62672\n', '3R\t1000\t1050\t0.813362\n', '3R\t1050\t1500\t0\n'] assert_equal(resp, expected) unlink(outfile) def test_bam_coverage_offset1(): """ Test -bs 1 --Offset 1 """ outfile = '/tmp/test_offset.bw' args = "--Offset 1 --bam {} -p 1 -bs 1 -o {}".format(BAMFILE_A, outfile) args = args.split() bam_cov.main(args) try: # python 3 only filecmp.clear_cache() except: pass assert(filecmp.cmp(outfile, "{}testA_offset1.bw".format(ROOT)) is True) unlink(outfile) def test_bam_coverage_offset1_10(): """ Test -bs 1 --Offset 1 10 """ outfile = '/tmp/test_offset.bw' args = "--Offset 1 10 -b {} -p 1 -bs 1 -o {}".format(BAMFILE_A, outfile) args = args.split() bam_cov.main(args) try: # python 3 only filecmp.clear_cache() except: pass assert(filecmp.cmp(outfile, "{}testA_offset1_10.bw".format(ROOT)) is True) unlink(outfile) def test_bam_coverage_offset_minus1(): """ Test -bs 1 --Offset -1 """ outfile = '/tmp/test_offset.bw' args = "--Offset -1 -b {} -p 1 -bs 1 -o {}".format(BAMFILE_A, outfile) args = args.split() bam_cov.main(args) try: # python 3 only filecmp.clear_cache() except: pass assert(filecmp.cmp(outfile, "{}testA_offset-1.bw".format(ROOT)) is True) unlink(outfile) def test_bam_coverage_offset20_minus4(): """ Test -bs 1 --Offset 20 -4 """ outfile = '/tmp/test_offset.bw' args = "--Offset 20 -4 -b {} -p 1 -bs 1 -o {}".format(BAMFILE_A, outfile) args = args.split() bam_cov.main(args) try: # python 3 only filecmp.clear_cache() except: pass assert(filecmp.cmp(outfile, "{}testA_offset20_-4.bw".format(ROOT)) is True) unlink(outfile) def test_bam_compare_filter_blacklist(): """ Test --samFlagInclude --samFlagExclude --minMappingQuality --ignoreDuplicates and --blackListFileName """ outfile = '/tmp/test_file_filter.bg' args = "-b1 {} -b2 {} --normalizeTo1x 1400 -p 1 -o {} -of bedgraph --samFlagInclude 512 " \ "--samFlagExclude 256 --minMappingQuality 5 --ignoreDuplicates " \ "--blackListFileName {}".format(BAMFILE_FILTER1, BAMFILE_FILTER2, outfile, BEDFILE_FILTER) args = args.split() bam_comp.main(args) _foo = open(outfile, 'r') resp = _foo.readlines() _foo.close() expected = ['3R\t0\t100\t0\n', '3R\t100\t150\t-0.220909\n', '3R\t150\t200\t-0.159356\n', '3R\t200\t250\t-0.0718929\n', '3R\t250\t300\t0.135883\n', '3R\t300\t350\t0.103093\n', '3R\t350\t400\t-0.0895516\n', '3R\t400\t450\t0.0308374\n', '3R\t450\t500\t0.0989418\n', '3R\t500\t550\t0.207044\n', '3R\t550\t600\t0.0198996\n', '3R\t600\t650\t-0.0957241\n', '3R\t650\t700\t0.00968255\n', '3R\t700\t750\t-0.040642\n', '3R\t750\t800\t-0.123451\n', '3R\t900\t950\t0.212545\n', '3R\t950\t1000\t0.199309\n', '3R\t1000\t1050\t0.167945\n', '3R\t1050\t1500\t0\n'] assert_equal(resp, expected) unlink(outfile) deepTools-2.5.0/deeptools/test/test_bigwigCompare_and_multiBigwigSummary.py0000640000201600010240000001010113006372703026520 0ustar ryanbioinfoimport deeptools.bigwigCompare as bwComp import deeptools.multiBigwigSummary as bwCorr import numpy as np import numpy.testing as nt import os.path from os import unlink ROOT = os.path.dirname(os.path.abspath(__file__)) + "/test_data/" BIGWIG_A = ROOT + "testA_skipNAs.bw" BIGWIG_B = ROOT + "testB_skipNAs.bw" BIGWIG_C = ROOT + "test1.bw.bw" """ The distribution of reads for the bam file is: 0 100 200 |------------------------------------------------------------| testA.bam 3R ==============> <============== testB.bam 3R <============== ==============> ==============> ==============> The resulting bigwig files are as follows: testA_skipNas: 3R 100 200 1 chr_cigar 0 50 2 testB_skipNas: 3R 50 150 1 3R 150 200 2 """ def test_bigwigCompare(): outfile = '/tmp/result.bg' args = "-b1 {} -b2 {} -o {} --ratio add --outFileFormat bedgraph".format(BIGWIG_A, BIGWIG_B, outfile).split() bwComp.main(args) _foo = open(outfile, 'r') resp = _foo.readlines() _foo.close() expected = ['3R\t0\t50\t0\n', '3R\t50\t100\t1\n', '3R\t100\t150\t2\n', '3R\t150\t200\t3\n'] assert resp == expected, "{} != {}".format(resp, expected) unlink(outfile) def test_bigwigCompare_skipnas(): outfile = '/tmp/result.bg' args = "-b1 {} -b2 {} -o {} --ratio add --skipNAs " \ "--outFileFormat bedgraph".format(BIGWIG_A, BIGWIG_B, outfile).split() bwComp.main(args) _foo = open(outfile, 'r') resp = _foo.readlines() _foo.close() expected = ['3R\t100\t150\t2\n', '3R\t150\t200\t3\n'] assert resp == expected, "{} != {}".format(resp, expected) unlink(outfile) def test_multiBigwigSummary(): outfile = '/tmp/result.bg' args = "bins -b {} {} --binSize 50 -o {}".format(BIGWIG_A, BIGWIG_B, outfile).split() bwCorr.main(args) resp = np.load(outfile) matrix = resp['matrix'] labels = resp['labels'] nt.assert_equal(matrix, np.array([[np.nan, np.nan], [np.nan, 1.], [1., 1.], [1., 2.]])) nt.assert_equal(labels, ['testA_skipNAs.bw', 'testB_skipNAs.bw']) unlink(outfile) def test_multiBigwigSummary_outrawcounts(): """ Test multiBigwigSummary raw counts output """ outfile = '/tmp/result.bg' args = "bins -b {} {} --binSize 50 -o /tmp/null --outRawCounts {} ".format(BIGWIG_A, BIGWIG_B, outfile).split() bwCorr.main(args) _foo = open(outfile, 'r') resp = _foo.read() _foo.close() expected = """#'chr' 'start' 'end' 'testA_skipNAs.bw' 'testB_skipNAs.bw' 3R 0 50 nan nan 3R 50 100 nan 1.0 3R 100 150 1.0 1.0 3R 150 200 1.0 2.0 """ assert resp == expected, "{} != {}".format(resp, expected) unlink(outfile) unlink("/tmp/null") def test_multiBigwigSummary_gtf(): outfile = '/tmp/_test.npz' args = "BED-file -b {0} {0} --BED {1}/test.gtf -o {2}".format(BIGWIG_C, ROOT, outfile).split() bwCorr.main(args) resp = np.load(outfile) matrix = resp['matrix'] labels = resp['labels'] nt.assert_equal(labels, ['test1.bw.bw', 'test1.bw.bw']) nt.assert_allclose(matrix, np.array([[27.475, 27.475], [27.31248719, 27.31248719]])) unlink(outfile) def test_multiBigwigSummary_metagene(): outfile = '/tmp/_test.npz' args = "BED-file --metagene -b {0} {0} --BED {1}/test.gtf -o {2}".format(BIGWIG_C, ROOT, outfile).split() bwCorr.main(args) resp = np.load(outfile) matrix = resp['matrix'] labels = resp['labels'] nt.assert_equal(labels, ['test1.bw.bw', 'test1.bw.bw']) nt.assert_allclose(matrix, np.array([[20.28956028, 20.28956028], [22.1923501, 22.1923501]])) unlink(outfile) deepTools-2.5.0/deeptools/test/test_computeMatrixOperations.py0000640000201600010240000001767713006372703024134 0ustar ryanbioinfo# from unittest import TestCase import deeptools.computeMatrixOperations as cmo import os import hashlib import gzip import json __author__ = 'Devon' ROOT = os.path.dirname(os.path.abspath(__file__)) + "/test_data/" def getHeader(fp): s = fp.readline() if isinstance(s, bytes): s = s.decode() s = s[1:] return json.loads(s) class TestComputeMatrixOperations(object): def setUp(self): self.root = ROOT self.matrix = self.root + "computeMatrixOperations.mat.gz" self.bed = self.root + "computeMatrixOperations.bed" def testSubset(self): """ computeMatrixOperations subset """ dCorrect = {"verbose": True, "scale": 1, "skip zeros": False, "nan after end": False, "sort using": "mean", "unscaled 5 prime": 0, "body": 1000, "sample_labels": ["SRR648667.forward", "SRR648668.forward", "SRR648669.forward", "SRR648670.forward"], "downstream": 0, "unscaled 3 prime": 0, "group_labels": ["genes"], "bin size": 10, "upstream": 0, "group_boundaries": [0, 196], "sample_boundaries": [0, 100, 200, 300, 400], "max threshold": None, "ref point": None, "min threshold": None, "sort regions": "no", "proc number": 20, "bin avg type": "mean", "missing data as zero": False} oname = "/tmp/subset.mat.gz" args = "subset -m {} --sample SRR648667.forward SRR648668.forward SRR648669.forward SRR648670.forward -o {}".format(self.matrix, oname) args = args.split() cmo.main(args) f = gzip.GzipFile(oname) d = getHeader(f) # Skip the header, which can be in a different order h = hashlib.md5(f.read()).hexdigest() f.close() assert(d == dCorrect) assert(h == "edb3c8506c3f27ebb8c7ddf94d5ba594") os.remove(oname) def testfilterStrand(self): """ computeMatrixOperations filterStrand """ dCorrect = {"verbose": True, "scale": 1, "skip zeros": False, "nan after end": False, "sort using": "mean", "unscaled 5 prime": 0, "body": 1000, "sample_labels": ["SRR648667.forward", "SRR648668.forward", "SRR648669.forward", "SRR648670.forward", "SRR648667.reverse", "SRR648668.reverse", "SRR648669.reverse", "SRR648670.reverse"], "downstream": 0, "unscaled 3 prime": 0, "group_labels": ["genes"], "bin size": 10, "upstream": 0, "group_boundaries": [0, 107], "sample_boundaries": [0, 100, 200, 300, 400, 500, 600, 700, 800], "max threshold": None, "ref point": None, "min threshold": None, "sort regions": "no", "proc number": 20, "bin avg type": "mean", "missing data as zero": False} oname = "/tmp/filterStrand1.mat.gz" args = "filterStrand -m {} -o {} --strand +".format(self.matrix, oname) args = args.split() cmo.main(args) f = gzip.GzipFile(oname) d = getHeader(f) # Skip the header, which can be in a different order h = hashlib.md5(f.read()).hexdigest() f.close() assert(d == dCorrect) assert(h == "300f8000be5b5f51e803b57ef08f1c9e") os.remove(oname) dCorrect = {u'verbose': True, u'scale': 1, u'skip zeros': False, u'nan after end': False, u'sort using': u'mean', u'unscaled 5 prime': 0, u'body': 1000, u'sample_labels': [u'SRR648667.forward', u'SRR648668.forward', u'SRR648669.forward', u'SRR648670.forward', u'SRR648667.reverse', u'SRR648668.reverse', u'SRR648669.reverse', u'SRR648670.reverse'], u'downstream': 0, u'unscaled 3 prime': 0, u'group_labels': [u'genes'], u'bin size': 10, u'upstream': 0, u'group_boundaries': [0, 89], u'sample_boundaries': [0, 100, 200, 300, 400, 500, 600, 700, 800], u'missing data as zero': False, u'ref point': None, u'min threshold': None, u'sort regions': u'no', u'proc number': 20, u'bin avg type': u'mean', u'max threshold': None} oname = "/tmp/filterStrand2.mat.gz" args = "filterStrand -m {} -o {} --strand -".format(self.matrix, oname) args = args.split() cmo.main(args) f = gzip.GzipFile(oname) d = getHeader(f) # Skip the header, which can be in a different order h = hashlib.md5(f.read()).hexdigest() f.close() assert(d == dCorrect) assert(h == "0a6ca070a5ba4564f1ab950ac3b7c8f1") os.remove(oname) def testrbind(self): """ computeMatrixOperations rbind """ dCorrect = {"verbose": True, "scale": 1, "skip zeros": False, "nan after end": False, "sort using": "mean", "unscaled 5 prime": 0, "body": 1000, "sample_labels": ["SRR648667.forward", "SRR648668.forward", "SRR648669.forward", "SRR648670.forward", "SRR648667.reverse", "SRR648668.reverse", "SRR648669.reverse", "SRR648670.reverse"], "downstream": 0, "unscaled 3 prime": 0, "group_labels": ["genes"], "bin size": 10, "upstream": 0, "group_boundaries": [0, 392], "sample_boundaries": [0, 100, 200, 300, 400, 500, 600, 700, 800], "max threshold": None, "ref point": None, "min threshold": None, "sort regions": "no", "proc number": 20, "bin avg type": "mean", "missing data as zero": False} oname = "/tmp/rbind.mat.gz" args = "rbind -m {0} {0} -o {1}".format(self.matrix, oname) args = args.split() cmo.main(args) f = gzip.GzipFile(oname) d = getHeader(f) # Skip the header, which can be in a different order h = hashlib.md5(f.read()).hexdigest() f.close() assert(d == dCorrect) assert(h == "3dd96c7b05e0ca5ada21212defe57fba") os.remove(oname) def testcbind(self): """ computeMatrixOperations cbind """ dCorrect = {"verbose": True, "scale": 1, "skip zeros": False, "nan after end": False, "sort using": "mean", "unscaled 5 prime": 0, "body": 1000, "sample_labels": ["SRR648667.forward", "SRR648668.forward", "SRR648669.forward", "SRR648670.forward", "SRR648667.reverse", "SRR648668.reverse", "SRR648669.reverse", "SRR648670.reverse", "SRR648667.forward", "SRR648668.forward", "SRR648669.forward", "SRR648670.forward", "SRR648667.reverse", "SRR648668.reverse", "SRR648669.reverse", "SRR648670.reverse"], "downstream": 0, "unscaled 3 prime": 0, "group_labels": ["genes"], "bin size": 10, "upstream": 0, "group_boundaries": [0, 196], "sample_boundaries": [0, 100, 200, 300, 400, 500, 600, 700, 800, 900, 1000, 1100, 1200, 1300, 1400, 1500, 1600], "max threshold": None, "ref point": None, "min threshold": None, "sort regions": "no", "proc number": 20, "bin avg type": "mean", "missing data as zero": False} oname = "/tmp/filterStrand.mat.gz" args = "cbind -m {0} {0} -o {1}".format(self.matrix, oname) args = args.split() cmo.main(args) f = gzip.GzipFile(oname) d = getHeader(f) # Skip the header, which can be in a different order h = hashlib.md5(f.read()).hexdigest() f.close() assert(d == dCorrect) assert(h == "e55d89704bb16a11f366663a8fd90a47") os.remove(oname) def testsort(self): """ computeMatrixOperations sort """ dCorrect = {"verbose": True, "scale": 1, "skip zeros": False, "nan after end": False, "sort using": "mean", "unscaled 5 prime": 0, "body": 1000, "sample_labels": ["SRR648667.forward", "SRR648668.forward", "SRR648669.forward", "SRR648670.forward", "SRR648667.reverse", "SRR648668.reverse", "SRR648669.reverse", "SRR648670.reverse"], "downstream": 0, "unscaled 3 prime": 0, "group_labels": ["genes"], "bin size": 10, "upstream": 0, "group_boundaries": [0, 196], "sample_boundaries": [0, 100, 200, 300, 400, 500, 600, 700, 800], "max threshold": None, "ref point": None, "min threshold": None, "sort regions": "no", "proc number": 20, "bin avg type": "mean", "missing data as zero": False} oname = "/tmp/sorted.mat.gz" args = "sort -m {} -o {} -R {}".format(self.matrix, oname, self.bed) args = args.split() cmo.main(args) f = gzip.GzipFile(oname) d = getHeader(f) # Skip the header, which can be in a different order h = hashlib.md5(f.read()).hexdigest() f.close() assert(d == dCorrect) assert(h == "10ea07d1aa58f44625abe2142ef76094") os.remove(oname) deepTools-2.5.0/deeptools/test/test_countReadsPerBin.py0000640000201600010240000001537512757050136022434 0ustar ryanbioinfo# from unittest import TestCase import deeptools.countReadsPerBin as cr import numpy as np import numpy.testing as nt import os.path __author__ = 'Fidel' ROOT = os.path.dirname(os.path.abspath(__file__)) + "/test_data/" class TestCountReadsPerBin(object): def setUp(self): """ The distribution of reads between the two bam files is as follows. They cover 200 bp:: 0 100 200 |------------------------------------------------------------| A ==============> <============== B <============== ==============> ==============> ==============> """ self.root = ROOT self.bamFile1 = self.root + "testA.bam" self.bamFile2 = self.root + "testB.bam" self.bamFile_PE = self.root + "test_paired2.bam" self.chrom = '3R' step_size = 50 bin_length = 25 self.c = cr.CountReadsPerBin([self.bamFile1, self.bamFile2], binLength=bin_length, stepSize=step_size) def test_count_reads_in_region(self): self.c.skipZeros = False resp, _ = self.c.count_reads_in_region(self.chrom, 0, 200) nt.assert_equal(resp, np.array([[0, 0.], [0, 1.], [1, 1.], [1, 2.]])) def test_count_reads_in_region_extension_1(self): """ In this case when read extension is smaller than read length extension is turned off and a warning is printed. """ self.c = cr.CountReadsPerBin([self.bamFile1, self.bamFile2], binLength=1, stepSize=50, extendReads=25) resp, _ = self.c.count_reads_in_region(self.chrom, 0, 200) nt.assert_equal(resp, np.array([[0, 0.], [0, 1.], [1, 1.], [1, 2.]])) def test_count_reads_in_region_total(self): """ count the reads over the whole region 2 for the first case, and 4 for the second """ self.c.skipZeros = False self.c.stepSize = 200 self.c.binLength = 200 resp, _ = self.c.count_reads_in_region(self.chrom, 0, 200) nt.assert_equal(resp, np.array([[2, 4.]])) def test_countReadsInRegions_min_mapping_quality(self): # Test min mapping quality. self.c.minMappingQuality = 40 self.c.skipZeros = False resp, _ = self.c.count_reads_in_region(self. chrom, 0, 200) nt.assert_equal(resp, np.array([[0, 0, 0, 1.], [0, 0, 0, 1.]]).T) def test_count_reads_in_region_ignore_duplicates(self): # Test ignore duplicates self.c.skipZeros = False self.c.ignoreDuplicates = True resp, _ = self.c.count_reads_in_region(self.chrom, 0, 200) nt.assert_equal(resp, np.array([[0, 0, 1, 1.], [0, 1, 1, 1.]]).T) def test_count_reads_in_region_ignore_bed_regions(self): # Test bed regions: bed_regions = [[self.chrom, [(10, 20)], "."], [self.chrom, [(150, 160)], "."]] self.c.skipZeros = False self.c.binLength = 10 resp, _ = self.c.count_reads_in_region(self.chrom, 0, 200, bed_regions_list=bed_regions) nt.assert_equal(resp, np.array([[0, 1.], [0, 2.]]).T) def test_get_coverage_of_region_sam_flag_include(self): self.c.samFlag_include = 16 # include reverse reads only self.c.bamFilesList = [self.bamFile1] resp, _ = self.c.count_reads_in_region('3R', 0, 200) nt.assert_array_equal(resp, np.array([[0], [0], [0], [1]])) def test_get_coverage_of_region_sam_flag_exclude(self): self.c.samFlag_exclude = 16 # exclude reverse reads self.c.bamFilesList = [self.bamFile1] resp, _ = self.c.count_reads_in_region('3R', 0, 200) nt.assert_array_equal(resp, np.array([[0], [0], [1], [0]])) def test_get_coverage_of_region_large_bin(self): self.c.bamFilesList = [self.bamFile2] self.c.binLength = 200 self.c.stepSize = 200 resp, _ = self.c.count_reads_in_region('3R', 0, 200) nt.assert_array_equal(resp, np.array([[4]])) def test_get_coverage_of_region_ignore_duplicates(self): self.c.ignoreDuplicates = True self.c.bamFilesList = [self.bamFile2] resp, _ = self.c.count_reads_in_region('3R', 0, 200) nt.assert_array_equal(resp, np.array([[0.], [1.], [1.], [1.]])) # check zero to nans self.c.zerosToNans = True resp, _ = self.c.count_reads_in_region('3R', 0, 200) nt.assert_array_equal(resp, np.array([[np.nan], [1.], [1.], [1.]])) def test_get_coverage_of_region_split_read(self): """ The bamFile1 contains a read at position 10 with the following CIGAR: 10S20M10N10M10S that maps to a chromosome named chr_cigar. """ # turn of read extension self.c.extendPairedEnds = False self.c.bamFilesList = [self.bamFile1] self.c.binLength = 10 self.c.stepSize = 10 resp, _ = self.c.count_reads_in_region('chr_cigar', 0, 100) nt.assert_array_equal(resp, np.array([[0.], [1.], [1.], [0.], [1.], [0.], [0.], [0.], [0.], [0.]])) def test_get_coverage_of_region_zeros_to_nan(self): self.c.zerosToNans = True resp, _ = self.c.count_reads_in_region(self.chrom, 0, 200) nt.assert_equal(resp, np.array([[np.nan, np.nan], [np.nan, 1], [1, 1], [1, 2]])) deepTools-2.5.0/deeptools/test/test_heatmapper.py0000640000201600010240000004156613066417767021367 0ustar ryanbioinfoimport os import sys import filecmp import matplotlib as mpl import deeptools.computeMatrix import deeptools.plotHeatmap import deeptools.plotProfile import deeptools.utilities import json __author__ = 'Fidel' ROOT = os.path.dirname(os.path.abspath(__file__)) + "/test_heatmapper/" def cmpMatrices(f1, f2): """ The header produced by computeMatrix will be different every time a command is run in python3! """ rv = True file1 = open(f1) file2 = open(f2) for l1, l2 in zip(file1, file2): if isinstance(l1, bytes): l1 = l1.decode() l2 = l2.decode() l1 = l1.strip() l2 = l2.strip() if l1.startswith("@"): p1 = json.loads(l1[1:]) p2 = json.loads(l2[1:]) for k, v in p1.items(): if k not in p2.keys(): sys.stderr.write("key in {} missing: {} not in {}\n".format(f1, k, p2.keys())) rv = False if p1[k] != p2[k]: sys.stderr.write("values of '{}' is different: {} not in {}\n".format(k, p1[k], p2[k])) rv = False for k in p2.keys(): if k not in p1.keys(): sys.stderr.write("key in {} missing: {} not in {}\n".format(f2, k, p1.keys())) rv = False else: if l1 != l2: sys.stderr.write("lines differ:\n{}\n vs\n{}\n".format(l1, l2)) rv = False file1.close() file2.close() return rv class TestHeatmapper(object): def setUp(self): # the tests based on images were done with # matplotlib 1.5.0 and will fail if other # version is used self.run_image_tests = True if mpl.__version__ != '1.5.0': sys.stderr.write("\nTests based on images are skipped because of " "different matplotlib version ({}) != 1.5.0\n".format(mpl.__version__)) self.run_image_tests = False if sys.version_info[0] != 2: self.run_image_tests = False def test_computeMatrix_reference_point(self): args = "reference-point -R {0}/test2.bed -S {0}/test.bw -b 100 -a 100 " \ "--outFileName /tmp/_test.mat.gz -bs 1 -p 1".format(ROOT).split() deeptools.computeMatrix.main(args) os.system('gunzip -f /tmp/_test.mat.gz') assert cmpMatrices(ROOT + '/master.mat', '/tmp/_test.mat') is True os.remove('/tmp/_test.mat') def test_computeMatrix_reference_point_center(self): args = "reference-point -R {0}/test2.bed -S {0}/test.bw -b 100 -a 100 --referencePoint center " \ "--outFileName /tmp/_test.mat.gz -bs 1 -p 1".format(ROOT).split() deeptools.computeMatrix.main(args) os.system('gunzip -f /tmp/_test.mat.gz') assert cmpMatrices(ROOT + '/master_center.mat', '/tmp/_test.mat') is True os.remove('/tmp/_test.mat') def test_computeMatrix_reference_point_tes(self): args = "reference-point -R {0}/test2.bed -S {0}/test.bw -b 100 -a 100 --referencePoint TES " \ "--outFileName /tmp/_test.mat.gz -bs 1 -p 1".format(ROOT).split() deeptools.computeMatrix.main(args) os.system('gunzip -f /tmp/_test.mat.gz') assert cmpMatrices(ROOT + '/master_TES.mat', '/tmp/_test.mat') is True os.remove('/tmp/_test.mat') def test_computeMatrix_reference_point_missing_data_as_zero(self): args = "reference-point -R {0}/test2.bed -S {0}/test.bw -b 100 -a 100 " \ "--outFileName /tmp/_test.mat.gz -bs 1 -p 1 --missingDataAsZero".format(ROOT).split() deeptools.computeMatrix.main(args) os.system('gunzip -f /tmp/_test.mat.gz') assert cmpMatrices(ROOT + '/master_nan_to_zero.mat', '/tmp/_test.mat') is True os.remove('/tmp/_test.mat') def test_computeMatrix_scale_regions(self): args = "scale-regions -R {0}/test2.bed -S {0}/test.bw -b 100 -a 100 -m 100 " \ "--outFileName /tmp/_test2.mat.gz -bs 1 -p 1".format(ROOT).split() deeptools.computeMatrix.main(args) os.system('gunzip -f /tmp/_test2.mat.gz') assert cmpMatrices(ROOT + '/master_scale_reg.mat', '/tmp/_test2.mat') is True os.remove('/tmp/_test2.mat') def test_computeMatrix_multiple_bed(self): args = "reference-point -R {0}/group1.bed {0}/group2.bed -S {0}/test.bw -b 100 -a 100 " \ "--outFileName /tmp/_test.mat.gz -bs 1 -p 1".format(ROOT).split() deeptools.computeMatrix.main(args) os.system('gunzip -f /tmp/_test.mat.gz') assert cmpMatrices(ROOT + '/master_multibed.mat', '/tmp/_test.mat') is True os.remove('/tmp/_test.mat') def test_computeMatrix_region_extend_over_chr_end(self): args = "reference-point -R {0}/group1.bed {0}/group2.bed -S {0}/test.bw -b 100 -a 500 " \ "--outFileName /tmp/_test.mat.gz -bs 1 -p 1".format(ROOT).split() deeptools.computeMatrix.main(args) os.system('gunzip -f /tmp/_test.mat.gz') assert cmpMatrices(ROOT + '/master_extend_beyond_chr_size.mat', '/tmp/_test.mat') is True os.remove('/tmp/_test.mat') def test_computeMatrix_unscaled(self): args = "scale-regions -S {0}/unscaled.bigWig -R {0}/unscaled.bed -a 300 -b 500 --unscaled5prime 100 --unscaled3prime 50 " \ "--outFileName /tmp/_test.mat.gz -bs 10 -p 1".format(ROOT).split() deeptools.computeMatrix.main(args) os.system('gunzip -f /tmp/_test.mat.gz') assert cmpMatrices(ROOT + '/master_unscaled.mat', '/tmp/_test.mat') is True os.remove('/tmp/_test.mat') def test_computeMatrix_gtf(self): args = "scale-regions -S {0}../test_data/test1.bw.bw -R {0}../test_data/test.gtf -a 300 -b 500 --unscaled5prime 20 --unscaled3prime 50 " \ "--outFileName /tmp/_test_gtf.mat.gz -bs 10 -p 1".format(ROOT).split() deeptools.computeMatrix.main(args) os.system('gunzip -f /tmp/_test_gtf.mat.gz') assert cmpMatrices(ROOT + '/master_gtf.mat', '/tmp/_test_gtf.mat') is True os.remove('/tmp/_test_gtf.mat') def test_computeMatrix_metagene(self): args = "scale-regions -S {0}../test_data/test1.bw.bw -R {0}../test_data/test.gtf -a 300 -b 500 --unscaled5prime 20 --unscaled3prime 50 " \ "--outFileName /tmp/_test_metagene.mat.gz -bs 10 -p 1 --metagene".format(ROOT).split() deeptools.computeMatrix.main(args) os.system('gunzip -f /tmp/_test_metagene.mat.gz') assert cmpMatrices(ROOT + '/master_metagene.mat', '/tmp/_test_metagene.mat') is True os.remove('/tmp/_test_metagene.mat') def test_plotHeatmap_simple_plot(self): """ Test a simple plot generated using a matrix from the following command: computeMatrix reference-point -a 100 -b 100 -S {test_path}/test.bw \ -R {test_path}/test.bed -o /tmp/mat.gz -bs 25 """ if self.run_image_tests: args = "-m {}/master.mat.gz --outFileName /tmp/_test.svg".format(ROOT).split() deeptools.plotHeatmap.main(args) # may fail if diff version of matplotlib library is used assert self.compare_svg(ROOT + '/master.svg', '/tmp/_test.svg') is True os.remove('/tmp/_test.svg') def test_plotHeatmap_rename_labels(self): if self.run_image_tests: args = "-m {}/master.mat.gz --outFileName /tmp/_test2.svg --regionsLabel uno dos".format(ROOT).split() deeptools.plotHeatmap.main(args) assert self.compare_svg(ROOT + '/master_relabeled.svg', '/tmp/_test2.svg') is True os.remove('/tmp/_test2.svg') def test_plotHeatmap_scale_regions(self): if self.run_image_tests: args = "-m {}/master_scale_reg.mat.gz --outFileName /tmp/_test3.svg".format(ROOT).split() deeptools.plotHeatmap.main(args) assert self.compare_svg(ROOT + '/master_scale_reg.svg', '/tmp/_test3.svg') is True os.remove('/tmp/_test3.svg') def test_plotHeatmap_multi_bigwig_pergroup(self): if self.run_image_tests: args = "-m {}/master_multi.mat.gz --perGroup --samplesLabel file1 file2 file3 file4 " \ "--outFileName /tmp/_test.svg".format(ROOT).split() deeptools.plotHeatmap.main(args) assert self.compare_svg(ROOT + '/heatmap_master_multi_pergroup.svg', '/tmp/_test.svg') is True os.remove('/tmp/_test.svg') def test_plotHeatmap_multiple_colors_muti_scales(self): if self.run_image_tests: args = "-m {}/master_multi.mat.gz --colorList white,blue white,red --zMin 1 0 --zMax 4 5 " \ "--outFileName /tmp/_test.svg".format(ROOT).split() deeptools.plotHeatmap.main(args) assert self.compare_svg(ROOT + '/heatmap_master_multi_color.svg', '/tmp/_test.svg') is True os.remove('/tmp/_test.svg') def test_plotHeatmap_multiple_colormap_no_boxes(self): if self.run_image_tests: args = "-m {}/master_multi.mat.gz --colorMap Reds binary terrain --boxAroundHeatmaps no " \ "--outFileName /tmp/_test.svg".format(ROOT).split() deeptools.plotHeatmap.main(args) assert self.compare_svg(ROOT + '/heatmap_master_multi_colormap_no_box.svg', '/tmp/_test.svg') is True os.remove('/tmp/_test.svg') def test_plotProfiler(self): if self.run_image_tests: args = "-m {}/master.mat.gz --outFileName /tmp/_test.svg --regionsLabel uno dos " \ "--plotType std".format(ROOT).split() deeptools.plotProfile.main(args) assert self.compare_svg(ROOT + '/profile_master.svg', '/tmp/_test.svg') os.remove('/tmp/_test.svg') def test_plotProfiler_heatmap(self): if self.run_image_tests: args = "-m {}/master.mat.gz --outFileName /tmp/_test.svg --plotType heatmap".format(ROOT).split() deeptools.plotProfile.main(args) assert self.compare_svg(ROOT + '/profile_master_heatmap.svg', '/tmp/_test.svg') os.remove('/tmp/_test.svg') def test_plotProfiler_overlapped_lines(self): if self.run_image_tests: args = "-m {}/master.mat.gz --outFileName /tmp/_test.svg " \ "--plotType overlapped_lines --yMin -1".format(ROOT).split() deeptools.plotProfile.main(args) assert self.compare_svg(ROOT + '/profile_master_overlap_lines.svg', '/tmp/_test.svg') os.remove('/tmp/_test.svg') def test_plotProfiler_multibigwig(self): if self.run_image_tests: args = "-m {}/master_multi.mat.gz --outFileName /tmp/_test.svg " \ "--numPlotsPerRow 2 --yMax 1.5".format(ROOT).split() deeptools.plotProfile.main(args) assert self.compare_svg(ROOT + '/profile_master_multi.svg', '/tmp/_test.svg') os.remove('/tmp/_test.svg') def test_plotProfiler_multibigwig_pergroup(self): if self.run_image_tests: args = "-m {}/master_multi.mat.gz --outFileName /tmp/_test.svg " \ "--perGroup --yMax 1.5".format(ROOT).split() deeptools.plotProfile.main(args) assert self.compare_svg(ROOT + '/profile_master_multi_pergroup.svg', '/tmp/_test.svg') os.remove('/tmp/_test.svg') def test_chopRegions_body(self): region = [(0, 200), (300, 400), (800, 900)] lbins, bodybins, rbins, padLeft, padRight = deeptools.heatmapper.chopRegions(region, left=0, right=0) assert(lbins == []) assert(rbins == []) assert(bodybins == region) assert(padLeft == 0) assert(padRight == 0) # Unscaled 5', 3' lbins, bodybins, rbins, padLeft, padRight = deeptools.heatmapper.chopRegions(region, left=150, right=150) assert(lbins == [(0, 150)]) assert(rbins == [(350, 400), (800, 900)]) assert(bodybins == [(150, 200), (300, 350)]) assert(padLeft == 0) assert(padRight == 0) def test_chopRegions_TSS(self): region = [(0, 200), (300, 400), (800, 900)] # + strand, 250 downstream downstream, body, unscaled3prime, padRight, _ = deeptools.heatmapper.chopRegions(region, left=250) assert(downstream == [(0, 200), (300, 350)]) assert(body == [(350, 400), (800, 900)]) assert(unscaled3prime == []) assert(padRight == 0) assert(_ == 0) # + strand, 500 downstream downstream, body, unscaled3prime, padRight, _ = deeptools.heatmapper.chopRegions(region, left=500) assert(downstream == region) assert(body == []) assert(unscaled3prime == []) assert(padRight == 100) assert(_ == 0) # - strand, 250 downstream (labeled "upstream" due to being on the - strand) unscaled5prime, body, upstream, _, padLeft = deeptools.heatmapper.chopRegions(region, right=250) assert(upstream == [(150, 200), (300, 400), (800, 900)]) assert(body == [(0, 150)]) assert(unscaled5prime == []) assert(padLeft == 0) assert(_ == 0) # - strand, 500 downstream (labeled "upstream" due to being on the - strand) unscaled5prime, body, upstream, _, padLeft = deeptools.heatmapper.chopRegions(region, right=500) assert(upstream == region) assert(body == []) assert(unscaled5prime == []) assert(padLeft == 100) assert(_ == 0) def test_chopRegions_TES(self): region = [(0, 200), (300, 400), (800, 900)] # + strand, 250 upstream unscaled5prime, body, upstream, _, padLeft = deeptools.heatmapper.chopRegions(region, right=250) assert(unscaled5prime == []) assert(body == [(0, 150)]) assert(upstream == [(150, 200), (300, 400), (800, 900)]) assert(_ == 0) assert(padLeft == 0) # + strand, 500 upstream unscaled5prime, body, upstream, _, padLeft = deeptools.heatmapper.chopRegions(region, right=500) assert(unscaled5prime == []) assert(body == []) assert(upstream == region) assert(_ == 0) assert(padLeft == 100) # + strand, 250 downstream (labeled "upstream" due to being on the - strand) downstream, body, unscaled3prime, padRight, _ = deeptools.heatmapper.chopRegions(region, left=250) assert(downstream == [(0, 200), (300, 350)]) assert(body == [(350, 400), (800, 900)]) assert(unscaled3prime == []) assert(padRight == 0) assert(_ == 0) # + strand, 500 downstream (labeled "upstream" due to being on the - strand) downstream, body, unscaled3prime, padRight, _ = deeptools.heatmapper.chopRegions(region, left=500) assert(downstream == region) assert(body == []) assert(unscaled3prime == []) assert(padRight == 100) assert(_ == 0) def test_chopRegionsFromMiddle(self): region = [(0, 200), (300, 400), (800, 900)] # + strand, 100 upstream/200 downstream upstream, downstream, padLeft, padRight = deeptools.heatmapper.chopRegionsFromMiddle(region, left=100, right=200) assert(upstream == [(100, 200)]) assert(downstream == [(300, 400), (800, 900)]) assert(padLeft == 0) assert(padRight == 0) # + strand, 250 upstream/300 downstream upstream, downstream, padLeft, padRight = deeptools.heatmapper.chopRegionsFromMiddle(region, left=250, right=300) assert(upstream == [(0, 200)]) assert(downstream == [(300, 400), (800, 900)]) assert(padLeft == 50) assert(padRight == 100) # - strand, 100 upstream/200 downstream upstream, downstream, padLeft, padRight = deeptools.heatmapper.chopRegionsFromMiddle(region, left=200, right=100) assert(upstream == [(0, 200)]) assert(downstream == [(300, 400)]) assert(padLeft == 0) assert(padRight == 0) # - strand, 250 upstream/300 downstream upstream, downstream, padLeft, padRight = deeptools.heatmapper.chopRegionsFromMiddle(region, left=300, right=250) assert(upstream == [(0, 200)]) assert(downstream == [(300, 400), (800, 900)]) assert(padLeft == 100) assert(padRight == 50) @staticmethod def compare_svg(file1, file2): """ svg files usually differ on randomly assigned ids and xlink:href tags This code compares the files ignoring the lines that contain ids :return: bool True if files are similar """ f1 = deeptools.utilities.getTempFileName(suffix='.svg') f2 = deeptools.utilities.getTempFileName(suffix='.svg') # remove xlink:href, id and url attributes os.system('cat {} | perl -lane \'s/xlink:href=".+?"//g; s/id=".+?"//g; s/"url\(.+?\)"//g; print $_\' > {}'.format(file1, f1)) os.system('cat {} | perl -lane \'s/xlink:href=".+?"//g; s/id=".+?"//g; s/"url\(.+?\)"//g; print $_\' > {}'.format(file2, f2)) res = filecmp.cmp(f1, f2) os.remove(f1) os.remove(f2) return res deepTools-2.5.0/deeptools/test/test_multiBamSummary.py0000640000201600010240000000216412757050137022346 0ustar ryanbioinfoimport deeptools.multiBamSummary as mbs import numpy as np import numpy.testing as nt import os.path from os import unlink ROOT = os.path.dirname(os.path.abspath(__file__)) + "/test_data/" BAM = ROOT + "test1.bam" GTF = ROOT + "test.gtf" def test_multiBamSummary_gtf(): outfile = '/tmp/_test.npz' args = 'BED-file --BED {0} -b {1} {1} -o {2}'.format(GTF, BAM, outfile).split() mbs.main(args) resp = np.load(outfile) matrix = resp['matrix'] labels = resp['labels'] nt.assert_equal(labels, ['test1.bam', 'test1.bam']) nt.assert_allclose(matrix, np.array([[144.0, 144.0], [143.0, 143.0]])) unlink(outfile) def test_multiBamSummary_metagene(): outfile = '/tmp/_test.npz' args = 'BED-file --BED {0} -b {1} {1} -o {2} --metagene'.format(GTF, BAM, outfile).split() mbs.main(args) resp = np.load(outfile) matrix = resp['matrix'] labels = resp['labels'] nt.assert_equal(labels, ['test1.bam', 'test1.bam']) nt.assert_allclose(matrix, np.array([[25.0, 25.0], [31.0, 31.0]])) unlink(outfile) deepTools-2.5.0/deeptools/test/test_plotCoverage.py0000640000201600010240000000433012757050137021645 0ustar ryanbioinfoimport os import sys import filecmp import matplotlib as mpl import deeptools.plotCoverage import deeptools.utilities __author__ = 'Bjoern' TEST_DATA = os.path.dirname(os.path.abspath(__file__)) + "/test_data/" ROOT = os.path.dirname(os.path.abspath(__file__)) + "/test_plotCoverage/" class TestHeatmapper(object): def setUp(self): # the tests based on images were done with # matplotlib 1.5.0 and will fail if other # version is used self.run_image_tests = True if mpl.__version__ != '1.5.0': sys.stderr.write("\nTests based on images are skipped because of " "different matplotlib version ({}) != 1.5.0\n".format(mpl.__version__)) self.run_image_tests = False def test_plotCoverage_default(self): args = "--bamfiles {0}test1.bam {0}test2.bam --plotFile /tmp/_test.svg" \ " --plotFileFormat svg --outRawCounts /tmp/_test.tab".format(TEST_DATA).split() deeptools.plotCoverage.main(args) assert filecmp.cmp(os.path.join(ROOT, 'outRawCounts_default.tabular'), '/tmp/_test.tab') is True if self.run_image_tests and sys.version_info[0] == 2: assert self.compare_svg(os.path.join(ROOT, 'plotCoverage_default.svg'), '/tmp/_test.svg') os.remove('/tmp/_test.tab') os.remove('/tmp/_test.svg') @staticmethod def compare_svg(file1, file2): """ svg files usually differ on randomly assigned ids and xlink:href tags This code compares the files ignoring the lines that contain ids :return: bool True if files are similar """ f1 = deeptools.utilities.getTempFileName(suffix='.svg') f2 = deeptools.utilities.getTempFileName(suffix='.svg') # remove xlink:href, id and url attributes os.system('cat {} | perl -lane \'s/xlink:href=".+?"//g; s/id=".+?"//g; s/"url\(.+?\)"//g; print $_\' > {}'.format(file1, f1)) os.system('cat {} | perl -lane \'s/xlink:href=".+?"//g; s/id=".+?"//g; s/"url\(.+?\)"//g; print $_\' > {}'.format(file2, f2)) res = filecmp.cmp(f1, f2) if res is False: os.system("diff {} {}".format(f1, f2)) os.remove(f1) os.remove(f2) return res deepTools-2.5.0/deeptools/test/test_tools.py0000640000201600010240000000065512757050137020361 0ustar ryanbioinfoimport subprocess import os ROOT = os.path.dirname(os.path.abspath(__file__)) + "/../../bin" def test_tools(): """ Checks everything that is in /bin/ and tries to run it """ if os.path.isdir(ROOT): for _file in os.listdir(ROOT): print(_file) if os.path.isfile(os.path.join(ROOT, _file)): subprocess.check_call("{}/{} --version".format(ROOT, _file).split()) deepTools-2.5.0/deeptools/test/test_writeBedGraph.py0000640000201600010240000001051613006372704021740 0ustar ryanbioinfofrom unittest import TestCase from nose.tools import * import os import deeptools.writeBedGraph as wr from deeptools.writeBedGraph import scaleCoverage ROOT = os.path.dirname(os.path.abspath(__file__)) + "/test_data/" __author__ = 'fidel' class TestWriteBedGraph(TestCase): def setUp(self): """ The distribution of reads between the two bam files is as follows. They cover 200 bp:: 0 100 200 |------------------------------------------------------------| A ==============> <============== B <============== ==============> ==============> ==============> """ self.root = ROOT self.bamFile1 = self.root + "testA.bam" self.bamFile2 = self.root + "testB.bam" self.bamFile_PE = self.root + "test_paired2.bam" self.chrom = '3R' self.step_size = 50 self.bin_length = 50 self.func_args = {'scaleFactor': 1.0} self.c = wr.WriteBedGraph([self.bamFile1], binLength=self.bin_length, stepSize=self.step_size) def test_writeBedGraph_worker(self): self.c.zerosToNans = False self.c.skipZeros = False tempFile = self.c.writeBedGraph_worker('3R', 0, 200, scaleCoverage, self.func_args) _foo = open(tempFile, 'r') res = _foo.readlines() _foo.close() assert_equal(res, ['3R\t0\t100\t0\n', '3R\t100\t200\t1\n']) os.remove(tempFile) def test_writeBedGraph_worker_zerotonan(self): # turn on zeroToNan self.c.zerosToNans = True tempFile2 = self.c.writeBedGraph_worker('3R', 0, 200, scaleCoverage, self.func_args) _foo = open(tempFile2, 'r') res = _foo.readlines() _foo.close() assert_equal(res, ['3R\t100\t200\t1\n']) os.remove(tempFile2) def test_writeBedGraph_worker_scaling(self): func_args = {'scaleFactor': 3.0} tempFile = self.c.writeBedGraph_worker('3R', 0, 200, scaleCoverage, func_args) _foo = open(tempFile, 'r') res = _foo.readlines() _foo.close() assert_equal(res, ['3R\t0\t100\t0\n', '3R\t100\t200\t3\n']) os.remove(tempFile) def test_writeBedGraph_worker_ignore_duplicates(self): self.c = wr.WriteBedGraph([self.bamFile2], binLength=self.bin_length, stepSize=self.step_size, ignoreDuplicates=True) self.c.zerosToNans = True tempFile = self.c.writeBedGraph_worker('3R', 0, 200, scaleCoverage, self.func_args) _foo = open(tempFile, 'r') res = _foo.readlines() _foo.close() assert_equal(res, ['3R\t50\t200\t1\n']) os.remove(tempFile) def test_writeBedGraph_worker_smoothing(self): self.c.binLength = 20 self.c.stepSize = 20 self.c.smoothLength = 60 tempFile = self.c.writeBedGraph_worker('3R', 100, 200, scaleCoverage, self.func_args) _foo = open(tempFile, 'r') res = _foo.readlines() _foo.close() assert_equal(res, ['3R\t100\t120\t1\n', '3R\t120\t180\t1.33333\n', '3R\t180\t200\t1\n']) os.remove(tempFile) def test_writeBedGraph_cigar(self): """ The bamFile1 contains a read at position 10 with the following CIGAR: 10S20M10N10M10S that maps to a chromosome named chr_cigar. """ # turn of read extension self.c.extendPairedEnds = False self.c.binLength = 10 self.c.stepSize = 10 tempFile = self.c.writeBedGraph_worker('chr_cigar', 0, 100, scaleCoverage, self.func_args) _foo = open(tempFile, 'r') res = _foo.readlines() _foo.close() # the sigle read is split into bin 10-30, and then 40-50 assert_equal(res, ['chr_cigar\t0\t10\t0\n', 'chr_cigar\t10\t30\t1\n', 'chr_cigar\t30\t40\t0\n', 'chr_cigar\t40\t50\t1\n', 'chr_cigar\t50\t100\t0\n']) os.remove(tempFile) deepTools-2.5.0/deeptools/SES_scaleFactor.py0000640000201600010240000001515713021233660020133 0ustar ryanbioinfo#!/usr/bin/env python # -*- coding: utf-8 -*- import os import numpy as np # own packages from deeptools import bamHandler import deeptools.countReadsPerBin as countR old_settings = np.seterr(all='ignore') debug = 0 def estimateScaleFactor(bamFilesList, binLength, numberOfSamples, normalizationLength, avg_method='median', blackListFileName=None, numberOfProcessors=1, verbose=False, chrsToSkip=[]): r""" Subdivides the genome into chunks to be analyzed in parallel using several processors. The code handles the creation of workers that compute fragment counts (coverage) for different regions and then collect and integrates the results. Parameters ---------- bamFilesList : list list of bam files to normalize binLength : int the window size in bp, where reads are going to be counted. numberOfSamples : int number of sites to sample from the genome. For more info see the documentation of the CountReadsPerBin class normalizationLength : int length, in bp, to normalize the data. For a value of 1, on average 1 read per base pair is found avg_method : str defines how the different values are to be summarized. The options are 'mean' and 'median' chrsToSkip : list name of the chromosomes to be excluded from the scale estimation. Usually the chrX is included. blackListFileName : str BED file containing blacklisted regions Returns ------- dict Dictionary with the following keys:: 'size_factors' 'size_factors_based_on_mapped_reads' 'size_factors_SES' 'size_factors_based_on_mean' 'size_factors_based_on_median' 'mean' 'meanSES' 'median' 'reads_per_bin' 'std' 'sites_sampled' Examples -------- >>> test = Tester() >>> bin_length = 50 >>> num_samples = 4 >>> _dict = estimateScaleFactor([test.bamFile1, test.bamFile2], bin_length, num_samples, 1) >>> _dict['size_factors'] array([ 1. , 0.5]) >>> _dict['size_factors_based_on_mean'] array([ 1. , 0.5]) """ assert len(bamFilesList) == 2, "SES scale factors are only defined for 2 files" bamFilesHandlers = [bamHandler.openBam(x) for x in bamFilesList] mappedReads = [x.mapped for x in bamFilesHandlers] sizeFactorBasedOnMappedReads = np.array(mappedReads, dtype='float64') sizeFactorBasedOnMappedReads = sizeFactorBasedOnMappedReads.min() / sizeFactorBasedOnMappedReads cr = countR.CountReadsPerBin(bamFilesList, binLength=binLength, numberOfSamples=numberOfSamples, extendReads=False, blackListFileName=blackListFileName, numberOfProcessors=numberOfProcessors, verbose=verbose, chrsToSkip=chrsToSkip) try: num_reads_per_bin = cr.run() except Exception as detail: exit("*ERROR*: {}".format(detail)) sitesSampled = len(num_reads_per_bin) # the transpose is taken to easily iterate by columns which are now # converted to rows num_reads_per_bin = num_reads_per_bin.transpose() # size factors based on order statistics # see Signal extraction scaling (SES) method in: Diaz et al (2012) # Normalization, bias correction, and peak calling for ChIP-seq. # Statistical applications in genetics and molecular biology, 11(3). # using the same names as in Diaz paper # p refers to ChIP, q to input p = np.sort(num_reads_per_bin[0, :]).cumsum() q = np.sort(num_reads_per_bin[1, :]).cumsum() # p[-1] and q[-1] are the maximum values in the arrays. # both p and q are normalized by this value diff = np.abs(p / p[-1] - q / q[-1]) # get the lowest rank for wich the difference is the maximum maxIndex = np.flatnonzero(diff == diff.max())[0] # Take a lower rank to move to a region with probably # less peaks and more background. maxIndex = int(maxIndex * 0.8) while(maxIndex < len(p)): # in rare cases the maxIndex maps to a zero value. # In such cases, the next index is used until # a non zero value appears. cumSum = np.array([float(p[maxIndex]), float(q[maxIndex])]) if cumSum.min() > 0: break maxIndex += 1 meanSES = [np.mean(np.sort(num_reads_per_bin[0, :])[:maxIndex]), np.mean(np.sort(num_reads_per_bin[1, :])[:maxIndex])] # the maxIndex may be too close to the the signal regions # so i take a more conservative approach by taking a close number sizeFactorsSES = cumSum.min() / cumSum median = np.median(num_reads_per_bin, axis=1) # consider only those read numbers that are below the 90 # percentile to stimate the # mean and std mean = [] std = [] for values in num_reads_per_bin: maxNumReads = (np.percentile(values, 90)) if maxNumReads == 0: maxNumReads = (np.percentile(values, 99)) if maxNumReads == 0: print("all genomic regions sampled from one ") "of the bam files have no reads.\n" values = values[values <= maxNumReads] mean.append(np.mean(values)) std.append(np.std(values)) mean = np.array(mean) readsPerBin = mean if avg_method == 'mean' else median if min(median) == 0: idx_zero = [ix + 1 for ix, value in enumerate(median) if value == 0] exit("\n*ERROR*: The median coverage computed is zero for sample(s) #{}\n" "Try selecting a larger sample size or a region with coverage\n".format(idx_zero)) sizeFactor = sizeFactorsSES return {'size_factors': sizeFactor, 'size_factors_based_on_mapped_reads': sizeFactorBasedOnMappedReads, 'size_factors_SES': sizeFactorsSES, 'size_factors_based_on_mean': mean.min() / mean, 'size_factors_based_on_median': median.min() / median, 'mean': mean, 'meanSES': meanSES, 'median': median, 'reads_per_bin': readsPerBin, 'std': std, 'sites_sampled': sitesSampled} class Tester(object): def __init__(self): self.root = os.path.dirname(os.path.abspath(__file__)) + "/test/test_data/" self.bamFile1 = self.root + "testA.bam" self.bamFile2 = self.root + "testB.bam" global debug debug = 0 self.chrom = '3R' deepTools-2.5.0/deeptools/__init__.py0000640000201600010240000000000012757050135016720 0ustar ryanbioinfodeepTools-2.5.0/deeptools/_version.py0000640000201600010240000000026313067415116017017 0ustar ryanbioinfo # This file is originally generated from Git information by running 'setup.py # version'. Distribution tarballs contain a pre-generated copy of this file. __version__ = '2.5.0' deepTools-2.5.0/deeptools/bamCompare.py0000640000201600010240000003707313061773504017254 0ustar ryanbioinfo#!/usr/bin/env python # -*- coding: utf-8 -*- import argparse # to parse command line arguments import numpy as np # my packages from deeptools import writeBedGraph from deeptools.SES_scaleFactor import estimateScaleFactor from deeptools import parserCommon from deeptools import bamHandler from deeptools.getRatio import getRatio from deeptools.getScaleFactor import get_num_kept_reads debug = 0 old_settings = np.seterr(all='ignore') def parseArguments(): parentParser = parserCommon.getParentArgParse() bamParser = parserCommon.read_options() normalizationParser = parserCommon.normalization_options() requiredArgs = getRequiredArgs() optionalArgs = getOptionalArgs() outputParser = parserCommon.output() parser = argparse.ArgumentParser( parents=[requiredArgs, outputParser, optionalArgs, parentParser, normalizationParser, bamParser], formatter_class=argparse.ArgumentDefaultsHelpFormatter, description='This tool compares two BAM files based on the number of ' 'mapped reads. To compare the BAM files, the genome is partitioned ' 'into bins of equal size, then the number of reads found in each bin' ' is counted per file, and finally a summary value is ' 'reported. This value can be the ratio of the number of reads per ' 'bin, the log2 of the ratio, or the difference. This tool can ' 'normalize the number of reads in each BAM file using the SES method ' 'proposed by Diaz et al. (2012) "Normalization, bias correction, and ' 'peak calling for ChIP-seq". Statistical Applications in Genetics ' 'and Molecular Biology, 11(3). Normalization based on read counts ' 'is also available. The output is either a bedgraph or bigWig file ' 'containing the bin location and the resulting comparison value. By ' 'default, if reads are paired, the fragment length reported in the BAM ' 'file is used. Each mate, however, ' 'is treated independently to avoid a bias when a mixture of concordant ' 'and discordant pairs is present. This means that *each end* will ' 'be extended to match the fragment length.', usage=' bamCompare -b1 treatment.bam -b2 control.bam -o log2ratio.bw', add_help=False) return parser def getRequiredArgs(): parser = argparse.ArgumentParser(add_help=False) required = parser.add_argument_group('Required arguments') # define the arguments required.add_argument('--bamfile1', '-b1', metavar='BAM file', help='Sorted BAM file 1. Usually the BAM file ' 'for the treatment.', required=True) required.add_argument('--bamfile2', '-b2', metavar='BAM file', help='Sorted BAM file 2. Usually the BAM ' 'file for the control.', required=True) return parser def getOptionalArgs(): parser = argparse.ArgumentParser(add_help=False) optional = parser.add_argument_group('Optional arguments') optional.add_argument("--help", "-h", action="help", help="show this help message and exit") optional.add_argument('--scaleFactorsMethod', help='Method to use to scale the samples. ' 'Default "readCount".', choices=['readCount', 'SES'], default='readCount') optional.add_argument('--sampleLength', '-l', help='*Only relevant when SES is chosen for the ' 'scaleFactorsMethod.* To compute the SES, specify ' 'the length (in bases) of the regions (see --numberOfSamples) ' 'that will be randomly sampled to calculate the scaling factors. ' 'If you do not have a good sequencing depth for ' 'your samples consider increasing the sampling ' 'regions\' size to minimize the probability ' 'that zero-coverage regions are used.', default=1000, type=int) optional.add_argument('--numberOfSamples', '-n', help='*Only relevant when SES is chosen for the ' 'scaleFactorsMethod.* Number of samplings taken ' 'from the genome to compute the scaling factors.', default=1e5, type=int) optional.add_argument('--scaleFactors', help='Set this parameter manually to avoid the computation of ' 'scaleFactors. The format is scaleFactor1:scaleFactor2.' 'For example, --scaleFactor 0.7:1 will cause the first BAM file to' 'be multiplied by 0.7, while not scaling ' 'the second BAM file (multiplication with 1).', default=None, required=False) optional.add_argument('--ratio', help='The default is to output the log2ratio of the ' 'two samples. The reciprocal ratio returns the ' 'the negative of the inverse of the ratio ' 'if the ratio is less than 0. The resulting ' 'values are interpreted as negative fold changes. ' '*NOTE*: Only with --ratio subtract can --normalizeTo1x or ' '--normalizeUsingRPKM be used. Instead of performing a ' 'computation using both files, the scaled signal can ' 'alternatively be output for the first or second file using ' 'the \'--ratio first\' or \'--ratio second\'', default='log2', choices=['log2', 'ratio', 'subtract', 'add', 'mean', 'reciprocal_ratio', 'first', 'second'], required=False) optional.add_argument('--pseudocount', help='small number to avoid x/0. Only useful ' 'together with --ratio log2 or --ratio ratio .', default=1, type=float, required=False) return parser def process_args(args=None): args = parseArguments().parse_args(args) if args.smoothLength and args.smoothLength <= args.binSize: print("Warning: the smooth length given ({}) is smaller than the bin " "size ({}).\n\n No smoothing will be " "done".format(args.smoothLength, args.binSize)) args.smoothLength = None if not args.ignoreForNormalization: args.ignoreForNormalization = [] return args def get_scale_factors(args): if args.ratio == 'subtract': # We need raw counts in this case normalizeTo1x = args.normalizeTo1x normalizeUsingRPKM = args.normalizeUsingRPKM args.normalizeTo1x = False args.normalizeUsingRPKM = False # This is only used if we subtract mapped_reads = [None, None] if args.scaleFactors: scale_factors = list(map(float, args.scaleFactors.split(":"))) elif args.scaleFactorsMethod == 'SES': scalefactors_dict = estimateScaleFactor( [args.bamfile1, args.bamfile2], args.sampleLength, args.numberOfSamples, 1, blackListFileName=args.blackListFileName, numberOfProcessors=args.numberOfProcessors, verbose=args.verbose, chrsToSkip=args.ignoreForNormalization) scale_factors = scalefactors_dict['size_factors'] if args.verbose: bam1 = bamHandler.openBam(args.bamfile1) bam2 = bamHandler.openBam(args.bamfile2) print("Size factors using SES: {}".format(scale_factors)) print("%s regions of size %s where used " % (scalefactors_dict['sites_sampled'], args.sampleLength)) print("ignoring filtering/blacklists, size factors if the number of mapped " "reads would have been used:") print(tuple( float(min(bam1.mapped, bam2.mapped)) / np.array([bam1.mapped, bam2.mapped]))) bam1.close() bam2.close() elif args.scaleFactorsMethod == 'readCount': args.bam = args.bamfile1 args.scaleFactor = 1.0 bam1_mapped, _ = get_num_kept_reads(args) args.bam = args.bamfile2 bam2_mapped, _ = get_num_kept_reads(args) scale_factors = float(min(bam1_mapped, bam2_mapped)) / np.array([bam1_mapped, bam2_mapped]) mapped_reads = [bam1_mapped, bam2_mapped] if args.verbose: print("Size factors using total number " "of mapped reads: {}".format(scale_factors)) # in case the subtract method is used, the final difference # would be normalized according to the given method if args.ratio == 'subtract': # The next lines identify which of the samples is not scaled down. # The normalization using RPKM or normalize to 1x would use # as reference such sample. Since the other sample would be # scaled to match the un-scaled one, the normalization factor due to RPKM or normalize1x # for both samples should be based on the unscaled one. # For example, if sample A is unscaled and sample B is scaled by 0.5, # then normalizing factor for A to report RPKM read counts # is also applied to B. if args.scaleFactors is None: # check which of the two samples is not scaled down if scale_factors[0] == 1: args.bam = args.bamfile1 mapped_reads = mapped_reads[0] else: args.bam = args.bamfile2 mapped_reads = mapped_reads[1] if mapped_reads is None: mapped_reads, _ = get_num_kept_reads(args) # Replace the arguments args.normalizeTo1x = normalizeTo1x args.normalizeUsingRPKM = normalizeUsingRPKM if args.scaleFactors is None: if args.normalizeTo1x: # try to guess fragment length if the bam file contains paired end reads from deeptools.getFragmentAndReadSize import get_read_and_fragment_length frag_len_dict, read_len_dict = get_read_and_fragment_length(args.bam, return_lengths=False, blackListFileName=args.blackListFileName, numberOfProcessors=args.numberOfProcessors, verbose=args.verbose) if args.extendReads: if args.extendReads is True: # try to guess fragment length if the bam file contains paired end reads if frag_len_dict: fragment_length = frag_len_dict['median'] else: exit("*ERROR*: library is not paired-end. Please provide an extension length.") if args.verbose: print(("Fragment length based on paired en data " "estimated to be {}".format(frag_len_dict['median']))) elif args.extendReads < 1: exit("*ERROR*: read extension must be bigger than one. Value give: {} ".format(args.extendReads)) elif args.extendReads > 2000: exit("*ERROR*: read extension must be smaller that 2000. Value give: {} ".format(args.extendReads)) else: fragment_length = args.extendReads else: # set as fragment length the read length fragment_length = int(read_len_dict['median']) if args.verbose: print("Estimated read length is {}".format(int(read_len_dict['median']))) current_coverage = float(mapped_reads * fragment_length) / args.normalizeTo1x # the coverage scale factor is 1 / coverage, coverage_scale_factor = 1.0 / current_coverage scale_factors = np.array(scale_factors) * coverage_scale_factor if args.verbose: print("Estimated current coverage {}".format(current_coverage)) print("Scale factor to convert " "current coverage to 1: {}".format(coverage_scale_factor)) else: # by default normalize using RPKM # the RPKM is: # Num reads per tile/(total reads (in millions)*tile length in Kb) millionReadsMapped = float(mapped_reads) / 1e6 tileLengthInKb = float(args.binSize) / 1000 coverage_scale_factor = 1.0 / (millionReadsMapped * tileLengthInKb) scale_factors = np.array(scale_factors) * coverage_scale_factor if args.verbose: print("Scale factor for RPKM is {0}".format(coverage_scale_factor)) return scale_factors def main(args=None): """ The algorithm is composed of two parts. 1. Using the SES or read counts method, appropriate scaling factors are determined to account for sequencing depth differences. 2. The genome is transversed, scaling the BAM files, and computing the log ratio/ratio/difference for bins of fixed width given by the user. """ args = process_args(args) scale_factors = get_scale_factors(args) if args.verbose: print("Individual scale factors are {0}".format(scale_factors)) # the getRatio function is called and receives # the func_args per each tile that is considered FUNC = getRatio func_args = {'valueType': args.ratio, 'scaleFactors': scale_factors, 'pseudocount': args.pseudocount } wr = writeBedGraph.WriteBedGraph([args.bamfile1, args.bamfile2], args.binSize, 0, stepSize=args.binSize, region=args.region, numberOfProcessors=args.numberOfProcessors, extendReads=args.extendReads, blackListFileName=args.blackListFileName, minMappingQuality=args.minMappingQuality, ignoreDuplicates=args.ignoreDuplicates, center_read=args.centerReads, zerosToNans=args.skipNonCoveredRegions, samFlag_include=args.samFlagInclude, samFlag_exclude=args.samFlagExclude, minFragmentLength=args.minFragmentLength, maxFragmentLength=args.maxFragmentLength, verbose=args.verbose ) wr.run(FUNC, func_args, args.outFileName, blackListFileName=args.blackListFileName, format=args.outFileFormat, smoothLength=args.smoothLength) if __name__ == "__main__": main() deepTools-2.5.0/deeptools/bamCoverage.py0000640000201600010240000004602313067414642017415 0ustar ryanbioinfo#!/usr/bin/env python # -*- coding: utf-8 -*- # own tools import argparse import sys import numpy as np from deeptools import writeBedGraph # This should be made directly into a bigWig from deeptools import parserCommon from deeptools.getScaleFactor import get_scale_factor debug = 0 def parseArguments(): parentParser = parserCommon.getParentArgParse() bamParser = parserCommon.read_options() normalizationParser = parserCommon.normalization_options() requiredArgs = get_required_args() optionalArgs = get_optional_args() outputParser = parserCommon.output() parser = \ argparse.ArgumentParser( parents=[requiredArgs, outputParser, optionalArgs, parentParser, normalizationParser, bamParser], formatter_class=argparse.ArgumentDefaultsHelpFormatter, description='This tool takes an alignment of reads or fragments ' 'as input (BAM file) and generates a coverage track (bigWig or ' 'bedGraph) as output. ' 'The coverage is calculated as the number of reads per bin, ' 'where bins are short consecutive counting windows of a defined ' 'size. It is possible to extended the length of the reads ' 'to better reflect the actual fragment length. *bamCoverage* ' 'offers normalization by scaling factor, Reads Per Kilobase per ' 'Million mapped reads (RPKM), and 1x depth (reads per genome ' 'coverage, RPGC).\n', usage='An example usage is:' '$ bamCoverage -b reads.bam -o coverage.bw', add_help=False) return parser def get_required_args(): parser = argparse.ArgumentParser(add_help=False) required = parser.add_argument_group('Required arguments') # define the arguments required.add_argument('--bam', '-b', help='BAM file to process', metavar='BAM file', required=True) return parser def get_optional_args(): parser = argparse.ArgumentParser(add_help=False) optional = parser.add_argument_group('Optional arguments') optional.add_argument("--help", "-h", action="help", help="show this help message and exit") optional.add_argument('--scaleFactor', help='The computed scaling factor (or 1, if not applicable) will ' 'be multiplied by this.', default=1.0, type=float, required=False) optional.add_argument('--MNase', help='Determine nucleosome positions from MNase-seq data. ' 'Only 3 nucleotides at the center of each fragment are counted. ' 'The fragment ends are defined by the two mate reads. Only fragment lengths' 'between 130 - 200 bp are considered to avoid dinucleosomes or other artifacts. ' 'By default, any fragments smaller or larger than this are ignored. To ' 'over-ride this, use the --minFragmentLength and --maxFragmentLength options, ' 'which will default to 130 and 200 if not otherwise specified in the presence ' 'of --MNase. *NOTE*: Requires paired-end data. A bin size of 1 is recommended.', action='store_true') optional.add_argument('--Offset', help='Uses this offset inside of each read as the signal. This is useful in ' 'cases like RiboSeq or GROseq, where the signal is 12, 15 or 0 bases past the ' 'start of the read. This can be paired with the --filterRNAstrand option. ' 'Note that negative values indicate offsets from the end of each read. A value ' 'of 1 indicates the first base of the alignment (taking alignment orientation ' 'into account). Likewise, a value of -1 is the last base of the alignment. An ' 'offset of 0 is not permitted. If two values are specified, then they will be ' 'used to specify a range of positions. Note that specifying something like ' '--Offset 5 -1 will result in the 5th through last position being used, which ' 'is equivalent to trimming 4 bases from the 5-prime end of alignments.', metavar='INT', type=int, nargs='+', required=False) optional.add_argument('--filterRNAstrand', help='Selects RNA-seq reads (single-end or paired-end) in ' 'the given strand.', choices=['forward', 'reverse'], default=None) return parser def scaleFactor(string): try: scalefactor1, scalefactor2 = string.split(":") scalefactors = (float(scalefactor1), float(scalefactor2)) except: raise argparse.ArgumentTypeError( "Format of scaleFactors is factor1:factor2. " "The value given ( {} ) is not valid".format(string)) return scalefactors def process_args(args=None): args = parseArguments().parse_args(args) if args.scaleFactor != 1: args.normalizeTo1x = None if args.smoothLength and args.smoothLength <= args.binSize: print("Warning: the smooth length given ({}) is smaller than the bin " "size ({}).\n\n No smoothing will be done".format(args.smoothLength, args.binSize)) args.smoothLength = None return args def main(args=None): args = process_args(args) global debug if args.verbose: debug = 1 else: debug = 0 if args.normalizeTo1x or args.normalizeUsingRPKM: # if a normalization is required then compute the scale factors scale_factor = get_scale_factor(args) else: scale_factor = args.scaleFactor func_args = {'scaleFactor': scale_factor} if args.MNase: # check that library is paired end # using getFragmentAndReadSize from deeptools.getFragmentAndReadSize import get_read_and_fragment_length frag_len_dict, read_len_dict = get_read_and_fragment_length(args.bam, return_lengths=False, blackListFileName=args.blackListFileName, numberOfProcessors=args.numberOfProcessors, verbose=args.verbose) if frag_len_dict is None: sys.exit("*Error*: For the --MNAse function a paired end library is required. ") # Set some default fragment length bounds if args.minFragmentLength == 0: args.minFragmentLength = 130 if args.maxFragmentLength == 0: args.maxFragmentLength = 200 wr = CenterFragment([args.bam], binLength=args.binSize, stepSize=args.binSize, region=args.region, blackListFileName=args.blackListFileName, numberOfProcessors=args.numberOfProcessors, extendReads=args.extendReads, minMappingQuality=args.minMappingQuality, ignoreDuplicates=args.ignoreDuplicates, center_read=args.centerReads, zerosToNans=args.skipNonCoveredRegions, samFlag_include=args.samFlagInclude, samFlag_exclude=args.samFlagExclude, minFragmentLength=args.minFragmentLength, maxFragmentLength=args.maxFragmentLength, verbose=args.verbose, ) elif args.Offset: if len(args.Offset) > 1: if args.Offset[0] == 0: sys.exit("*Error*: An offset of 0 isn't allowed, since offsets are 1-based positions inside each alignment.") if args.Offset[1] > 0 and args.Offset[1] < args.Offset[0]: sys.exir("'Error*: The right side bound is less than the left-side bound. This is inappropriate.") else: if args.Offset[0] == 0: sys.exit("*Error*: An offset of 0 isn't allowed, since offsets are 1-based positions inside each alignment.") wr = OffsetFragment([args.bam], binLength=args.binSize, stepSize=args.binSize, region=args.region, numberOfProcessors=args.numberOfProcessors, extendReads=args.extendReads, minMappingQuality=args.minMappingQuality, ignoreDuplicates=args.ignoreDuplicates, center_read=args.centerReads, zerosToNans=args.skipNonCoveredRegions, samFlag_include=args.samFlagInclude, samFlag_exclude=args.samFlagExclude, minFragmentLength=args.minFragmentLength, maxFragmentLength=args.maxFragmentLength, verbose=args.verbose) wr.filter_strand = args.filterRNAstrand wr.Offset = args.Offset elif args.filterRNAstrand: wr = filterRnaStrand([args.bam], binLength=args.binSize, stepSize=args.binSize, region=args.region, numberOfProcessors=args.numberOfProcessors, extendReads=args.extendReads, minMappingQuality=args.minMappingQuality, ignoreDuplicates=args.ignoreDuplicates, center_read=args.centerReads, zerosToNans=args.skipNonCoveredRegions, samFlag_include=args.samFlagInclude, samFlag_exclude=args.samFlagExclude, minFragmentLength=args.minFragmentLength, maxFragmentLength=args.maxFragmentLength, verbose=args.verbose, ) wr.filter_strand = args.filterRNAstrand else: wr = writeBedGraph.WriteBedGraph([args.bam], binLength=args.binSize, stepSize=args.binSize, region=args.region, blackListFileName=args.blackListFileName, numberOfProcessors=args.numberOfProcessors, extendReads=args.extendReads, minMappingQuality=args.minMappingQuality, ignoreDuplicates=args.ignoreDuplicates, center_read=args.centerReads, zerosToNans=args.skipNonCoveredRegions, samFlag_include=args.samFlagInclude, samFlag_exclude=args.samFlagExclude, minFragmentLength=args.minFragmentLength, maxFragmentLength=args.maxFragmentLength, verbose=args.verbose, ) wr.run(writeBedGraph.scaleCoverage, func_args, args.outFileName, blackListFileName=args.blackListFileName, format=args.outFileFormat, smoothLength=args.smoothLength) class OffsetFragment(writeBedGraph.WriteBedGraph): """ Class to redefine the get_fragment_from_read for the --Offset case """ def filterStrand(self, read, rv): """ A generic read filtering function that gets used by everything in this class. rv is returned if the strand is correct, otherwise [(None, None)] """ # Filter by RNA strand, if desired if read.is_paired: if self.filter_strand == 'forward': if read.flag & 144 == 128 or read.flag & 96 == 64: return rv elif self.filter_strand == 'reverse': if read.flag & 144 == 144 or read.flag & 96 == 96: return rv else: return rv else: if self.filter_strand == 'forward': if read.flag & 16 == 16: return rv elif self.filter_strand == 'reverse': if read.flag & 16 == 0: return rv else: return rv return [(None, None)] def get_fragment_from_read_list(self, read, offset): """ Return the range of exons from the 0th through 1st bases, inclusive. Positions are 1-based """ rv = [(None, None)] blocks = read.get_blocks() if self.defaultFragmentLength != 'read length': if self.is_proper_pair(read, self.maxPairedFragmentLength): if read.is_reverse: foo = (read.next_reference_start, read.reference_start) if foo[0] < foo[1]: blocks.insert(0, foo) else: foo = (read.reference_end, read.reference_end + abs(read.template_length) - read.infer_query_length()) if foo[0] < foo[1]: blocks.append(foo) # Extend using the default fragment length else: if read.is_reverse: foo = (read.reference_start - self.defaultFragmentLength + read.infer_query_length(), read.reference_start) if foo[0] < 0: foo = (0, foo[1]) if foo[0] < foo[1]: blocks.insert(0, foo) else: foo = (read.reference_end, read.reference_end + self.defaultFragmentLength - read.infer_query_length()) if foo[0] < foo[1]: blocks.append(foo) stretch = [] # For the sake of simplicity, convert [(10, 20), (30, 40)] to [10, 11, 12, 13, ..., 40] # Then subset accordingly for block in blocks: stretch.extend(range(block[0], block[1])) if read.is_reverse: stretch = stretch[::-1] try: foo = stretch[offset[0]:offset[1]] except: return rv if len(foo) == 0: return rv if read.is_reverse: foo = foo[::-1] # Convert the stretch back to a list of tuples foo = np.array(foo) d = foo[1:] - foo[:-1] idx = np.argwhere(d > 1).flatten().tolist() # This now holds the interval bounds as a list idx.append(-1) last = 0 rv = [] for i in idx: rv.append((foo[last].astype("int"), foo[i].astype("int") + 1)) last = i + 1 # Handle strand filtering, if needed return self.filterStrand(read, rv) def get_fragment_from_read(self, read): """ This is mostly a wrapper for self.get_fragment_from_read_list(), which needs a list and for the offsets to be tweaked by 1. """ offset = [x for x in self.Offset] if len(offset) > 1: if offset[0] > 0: offset[0] -= 1 if offset[1] < 0: offset[1] += 1 else: if offset[0] > 0: offset[0] -= 1 offset = [offset[0], offset[0] + 1] else: offset = [offset[0], None] if offset[1] == 0: # -1 gets switched to 0, which screws things up offset = (offset[0], None) return self.get_fragment_from_read_list(read, offset) class CenterFragment(writeBedGraph.WriteBedGraph): """ Class to redefine the get_fragment_from_read for the --MNase case The coverage of the fragment is defined as the 2 or 3 basepairs at the center of the fragment length. """ def get_fragment_from_read(self, read): """ Takes a proper pair fragment of high quality and limited to a certain length and outputs the center """ fragment_start = fragment_end = None # only paired forward reads are considered # Fragments have already been filtered according to length if read.is_proper_pair and not read.is_reverse and 1 < abs(read.tlen): # distance between pairs is even return two bases at the center if read.tlen % 2 == 0: fragment_start = read.pos + read.tlen / 2 - 1 fragment_end = fragment_start + 2 # distance is odd return three bases at the center else: fragment_start = read.pos + read.tlen / 2 - 1 fragment_end = fragment_start + 3 return [(fragment_start, fragment_end)] class filterRnaStrand(writeBedGraph.WriteBedGraph): """ Class to redefine the get_fragment_from_read for the --filterRNAstrand case Only reads either forward or reverse are kept as follows: For paired-end -------------- reads forward: 1. alignments of the second in pair (128) if they map to the forward strand (~16) 2. alignments of the first in pair (64) if they map to the reverse strand (~32) 1. include 128, exclude 16 or 2. include 64 exclude 32 reads reverse: 1. alignments of the second in pair (128) if it maps to the reverse strand (16) 128 & 16 = 144 2. alignments of the first in pair (64) if their mates map to the reverse strand (32) 64 & 32 = 96 1. include 144 or 2. include 96 For single-end -------------- forward: include 16 (map forward strand) reverse: exclude 16 """ def get_fragment_from_read(self, read): """ Gets only reads for the given strand """ fragment_start = fragment_end = None # only paired forward reads are considered if read.is_paired: if self.filter_strand == 'forward': if (read.flag & 128 == 128 and read.flag & 16 == 0) or (read.flag & 64 == 64 and read.flag & 32 == 0): return read.get_blocks() else: if read.flag & 144 == 144 or read.flag & 96 == 96: return read.get_blocks() else: if self.filter_strand == 'forward' and read.flag & 16 == 16: return read.get_blocks() elif self.filter_strand == 'reverse' and read.flag & 16 == 0: return read.get_blocks() return [(fragment_start, fragment_end)] deepTools-2.5.0/deeptools/bamHandler.py0000640000201600010240000000163713006372703017233 0ustar ryanbioinfoimport sys import pysam def openBam(bamFile): try: bam = pysam.Samfile(bamFile, 'rb') except IOError: sys.exit("The file {} does not exist".format(bamFile)) except: sys.exit("The file {} does not have BAM format ".format(bamFile)) try: if 'check_index' in dir(bam): assert(bam.check_index() is not False) else: # The proper check_index() function wasn't implemented until pysam 0.8.4! assert(bam._hasIndex() is not False) except: sys.exit("{} does not appear to have an index. You MUST index the file first!".format(bamFile)) if bam.mapped == 0: sys.exit("Samtools reports that the number of mapped " "reads is zero for the file {}. Please check " "that the file is properly indexed and that " "it contains mapped reads.".format(bamFile)) return bam deepTools-2.5.0/deeptools/bamPEFragmentSize.py0000640000201600010240000002022513052517601020472 0ustar ryanbioinfo#!/usr/bin/env python # -*- coding: utf-8 -*- import argparse # own tools from deeptools.getFragmentAndReadSize import get_read_and_fragment_length from deeptools._version import __version__ def parse_arguments(): parser = argparse.ArgumentParser( description='This tool calculates the fragment sizes for read pairs given a BAM file from paired-end sequencing.' 'Several regions are sampled depending on the ' 'size of the genome and number of processors to estimate the' 'summary statistics on the fragment lengths. ' 'Properly paired reads are preferred for computation, i.e., ' 'it will only use discordant pairs if no concordant alignments ' 'overlap with a given region. ' 'The default setting simply prints the summary statistics to the screen.') parser.add_argument('--bamfiles', '-b', help='List of BAM files to process', nargs='+', metavar='bam files') parser.add_argument('--histogram', '-hist', help='Save a .png file with a histogram ' 'of the fragment length distribution.', metavar='FILE') parser.add_argument('--numberOfProcessors', '-p', help='Number of processors to use. The default is ' 'to use 1.', metavar="INT", type=int, default=1, required=False) parser.add_argument('--samplesLabel', help='Labels for the samples plotted. The ' 'default is to use the file name of the ' 'sample. The sample labels should be separated ' 'by spaces and quoted if a label itself' 'contains a space E.g. --samplesLabel label-1 "label 2" ', nargs='+') parser.add_argument('--plotTitle', '-T', help='Title of the plot, to be printed on top of ' 'the generated image. Leave blank for no title.', default='') parser.add_argument('--maxFragmentLength', help='The maximum fragment length in the histogram. A value of 0 (the default) indicates to use twice the mean fragment length', default=0, type=int) parser.add_argument('--logScale', help='Plot on the log scale', action='store_true') parser.add_argument('--binSize', '-bs', metavar='INT', help='Length in bases of the window used to sample the genome. (default 1000)', default=1000, type=int) parser.add_argument('--distanceBetweenBins', '-n', metavar='INT', help='To reduce the computation time, not every possible genomic ' 'bin is sampled. This option allows you to set the distance ' 'between bins actually sampled from. Larger numbers are sufficient ' 'for high coverage samples, while smaller values are useful for ' 'lower coverage samples. Note that if you specify a value that ' 'results in too few (<1000) reads sampled, the value will be ' 'decreased. (default 1000000)', default=1000000, type=int) parser.add_argument('--blackListFileName', '-bl', help="A BED file containing regions that should be excluded from all analyses. Currently this works by rejecting genomic chunks that happen to overlap an entry. Consequently, for BAM files, if a read partially overlaps a blacklisted region or a fragment spans over it, then the read/fragment might still be considered.", metavar="BED file", required=False) parser.add_argument('--verbose', help='Set if processing data messages are wanted.', action='store_true', required=False) parser.add_argument('--version', action='version', version='%(prog)s {}'.format(__version__)) return parser def getFragSize(bam, args): fragment_len_dict, read_len_dict = get_read_and_fragment_length(bam, return_lengths=True, blackListFileName=args.blackListFileName, numberOfProcessors=args.numberOfProcessors, verbose=args.verbose, binSize=args.binSize, distanceBetweenBins=args.distanceBetweenBins) print("\n\nBAM file : {}".format(bam)) if fragment_len_dict: if fragment_len_dict['mean'] == 0: print("No pairs were found. Is the data from a paired-end sequencing experiment?") print("Sample size: {}\n".format(fragment_len_dict['sample_size'])) print("Fragment lengths:") print("Min.: {}\n1st Qu.: {}\nMean: {}\nMedian: {}\n" "3rd Qu.: {}\nMax.: {}\nStd: {}".format(fragment_len_dict['min'], fragment_len_dict['qtile25'], fragment_len_dict['mean'], fragment_len_dict['median'], fragment_len_dict['qtile75'], fragment_len_dict['max'], fragment_len_dict['std'])) else: print("No pairs were found. Is the data from a paired-end sequencing experiment?") print("\nRead lengths:") print("Min.: {}\n1st Qu.: {}\nMean: {}\nMedian: {}\n" "3rd Qu.: {}\nMax.: {}\nStd: {}".format(read_len_dict['min'], read_len_dict['qtile25'], read_len_dict['mean'], read_len_dict['median'], read_len_dict['qtile75'], read_len_dict['max'], read_len_dict['std'])) return fragment_len_dict def main(args=None): args = parse_arguments().parse_args(args) fraglengths = {} for bam in args.bamfiles: fraglengths[bam] = getFragSize(bam, args) if args.histogram: import matplotlib matplotlib.use('Agg') matplotlib.rcParams['pdf.fonttype'] = 42 matplotlib.rcParams['svg.fonttype'] = 'none' import matplotlib.pyplot as plt if args.samplesLabel: if len(args.bamfiles) != len(args.samplesLabel): print("The number of labels does not match the number of BAM files.") exit(0) else: labels = args.samplesLabel else: labels = list(fraglengths.keys()) i = 0 for bam in fraglengths.keys(): if args.maxFragmentLength > 0: maxVal = args.maxFragmentLength else: maxVal = fraglengths[bam]['mean'] * 2 plt.hist(fraglengths[bam]['lengths'], 100, range=(fraglengths[bam]['min'], maxVal), alpha=0.5, label=labels[i], log=args.logScale, normed=True) i += 1 plt.xlabel('Fragment Length') plt.ylabel('Frequency') plt.legend(loc='upper right') plt.title(args.plotTitle) plt.savefig(args.histogram, bbox_inches=0) plt.close() if __name__ == "__main__": main() deepTools-2.5.0/deeptools/bigwigCompare.py0000640000201600010240000001577613036110117017756 0ustar ryanbioinfo#!/usr/bin/env python # -*- coding: utf-8 -*- import argparse # to parse command line arguments import sys import multiprocessing import os from deeptools import parserCommon from deeptools.getRatio import getRatio from deeptools import writeBedGraph_bam_and_bw import deeptools.deepBlue as db debug = 0 def parse_arguments(args=None): parentParser = parserCommon.getParentArgParse() outputParser = parserCommon.output() dbParser = parserCommon.deepBlueOptionalArgs() parser = argparse.ArgumentParser( parents=[parentParser, outputParser, dbParser], formatter_class=argparse.ArgumentDefaultsHelpFormatter, description='This tool compares two bigWig files based on the number ' 'of mapped reads. To compare the bigWig files, the genome is ' 'partitioned into bins of equal size, then the number of reads found ' 'in each BAM file are counted per bin and finally a summary ' 'value is reported. This value can be the ratio of the number of reads' 'per bin, the log2 of the ratio, the sum or the difference.') # define the arguments parser.add_argument('--bigwig1', '-b1', metavar='Bigwig file', help='Bigwig file 1. Usually the file for the ' 'treatment.', required=True) parser.add_argument('--bigwig2', '-b2', metavar='Bigwig file', help='Bigwig file 2. Usually the file for the ' 'control.', required=True) parser.add_argument('--scaleFactors', help='Set this parameter to multipy the bigwig values ' 'by a constant. The format is ' 'scaleFactor1:scaleFactor2. ' 'For example 0.7:1 to scale the first bigwig file ' 'by 0.7 while not scaling the second bigwig file', default=None, required=False) parser.add_argument('--pseudocount', help='small number to avoid x/0. Only useful ' 'when ratio = log2 or ratio', default=1, type=float, required=False) parser.add_argument('--ratio', help='The default is to output the log2ratio of the ' 'two samples. The reciprocal ratio returns the ' 'the negative of the inverse of the ratio ' 'if the ratio is less than 0. The resulting ' 'values are interpreted as negative fold changes. ' '*NOTE*: Only with --ratio subtract can --normalizeTo1x or ' '--normalizeUsingRPKM be used. Instead of performing a ' 'computation using both files, the scaled signal can ' 'alternatively be output for the first or second file using ' 'the \'--ratio first\' or \'--ratio second\'', default='log2', choices=['log2', 'ratio', 'subtract', 'add', 'mean', 'reciprocal_ratio', 'first', 'second'], required=False) parser.add_argument('--skipNonCoveredRegions', '--skipNAs', help='This parameter determines if non-covered regions (regions without a score) ' 'in the bigWig files should be skipped. The default is to treat those ' 'regions as having a value of zero. ' 'The decision to skip non-covered regions ' 'depends on the interpretation of the data. Non-covered regions ' 'in a bigWig file may represent repetitive regions that should ' 'be skipped. Alternatively, the interpretation of non-covered regions as ' 'zeros may be wrong and this option should be used ', action='store_true') return parser def getType(fname): """ Tries to determine if a file is a wiggle file from deepBlue or a bigWig file. Returns 'wiggle' if the file name ends with .wig, otherwise 'bigwig' """ if fname.endswith(".wig") or fname.endswith(".wiggle"): return "wiggle" elif fname.endswith(".bedgraph"): return "bedgraph" return "bigwig" def main(args=None): args = parse_arguments().parse_args(args) if args.scaleFactors: scaleFactors = [float(x) for x in args.scaleFactors.split(":")] else: scaleFactors = [1, 1] # the getRatio function is called and receives # the function_args per each tile that is considered FUNC = getRatio function_args = {'valueType': args.ratio, 'scaleFactors': scaleFactors, 'pseudocount': args.pseudocount} # Preload deepBlue files, which need to then be deleted deepBlueFiles = [] for idx, fname in enumerate([args.bigwig1, args.bigwig2]): if db.isDeepBlue(fname): deepBlueFiles.append([fname, idx]) if len(deepBlueFiles) > 0: sys.stderr.write("Preloading the following deepBlue files: {}\n".format(",".join([x[0] for x in deepBlueFiles]))) foo = db.deepBlue(deepBlueFiles[0][0], url=args.deepBlueURL, userKey=args.userKey) regs = db.makeChromTiles(foo) for x in deepBlueFiles: x.extend([args, regs]) if len(deepBlueFiles) > 1 and args.numberOfProcessors > 1: pool = multiprocessing.Pool(args.numberOfProcessors) res = pool.map_async(db.preloadWrapper, deepBlueFiles).get(9999999) else: res = list(map(db.preloadWrapper, deepBlueFiles)) # substitute the file names with the temp files for (ftuple, r) in zip(deepBlueFiles, res): if ftuple[1] == 0: args.bigwig1 = r else: args.bigwig2 = r deepBlueFiles = [[x[0], x[1]] for x in deepBlueFiles] del regs writeBedGraph_bam_and_bw.writeBedGraph( [(args.bigwig1, getType(args.bigwig1)), (args.bigwig2, getType(args.bigwig2))], args.outFileName, 0, FUNC, function_args, tileSize=args.binSize, region=args.region, blackListFileName=args.blackListFileName, verbose=args.verbose, numberOfProcessors=args.numberOfProcessors, format=args.outFileFormat, smoothLength=False, missingDataAsZero=not args.skipNonCoveredRegions, extendPairedEnds=False) # Clean up temporary bigWig files, if applicable if not args.deepBlueKeepTemp: for k, v in deepBlueFiles: if v == 0: os.remove(args.bigwig1) else: os.remove(args.bigwig2) else: for k, v in deepBlueFiles: foo = args.bigwig1 if v == 1: foo = args.bigwig2 print("{} is stored in {}".format(k, foo)) deepTools-2.5.0/deeptools/computeGCBias.py0000640000201600010240000006774613061773504017705 0ustar ryanbioinfo#!/usr/bin/env python # -*- coding: utf-8 -*- import time import multiprocessing import numpy as np import argparse from scipy.stats import poisson import py2bit import sys from deeptoolsintervals import GTF from deeptools.utilities import tbitToBamChrName, getGC_content from deeptools import parserCommon, mapReduce from deeptools.getFragmentAndReadSize import get_read_and_fragment_length from deeptools import bamHandler debug = 0 old_settings = np.seterr(all='ignore') def parse_arguments(args=None): parentParser = parserCommon.getParentArgParse(binSize=False, blackList=True) requiredArgs = getRequiredArgs() parser = argparse.ArgumentParser( parents=[requiredArgs, parentParser], formatter_class=argparse.ArgumentDefaultsHelpFormatter, description='Computes the GC-bias using Benjamini\'s method ' '[Benjamini & Speed (2012). Nucleic Acids Research, 40(10). doi: 10.1093/nar/gks001]. ' 'The GC-bias is visualized and the resulting table can be used to' 'correct the bias with `correctGCBias`.', usage='\n computeGCBias ' '-b file.bam --effectiveGenomeSize 2150570000 -g mm9.2bit -l 200 --GCbiasFrequenciesFile freq.txt [options]', conflict_handler='resolve', add_help=False) return parser def getRequiredArgs(): parser = argparse.ArgumentParser(add_help=False) required = parser.add_argument_group('Required arguments') required.add_argument('--bamfile', '-b', metavar='bam file', help='Sorted BAM file. ', required=True) required.add_argument('--effectiveGenomeSize', help='The effective genome size is the portion ' 'of the genome that is mappable. Large fractions of ' 'the genome are stretches of NNNN that should be ' 'discarded. Also, if repetitive regions were not ' 'included in the mapping of reads, the effective ' 'genome size needs to be adjusted accordingly. ' 'Common values are: mm9: 2150570000, ' 'hg19:2451960000, dm3:121400000 and ce10:93260000. ' 'See Table 2 of ' 'http://www.plosone.org/article/info:doi/10.1371/journal.pone.0030377 ' 'or http://www.nature.com/nbt/journal/v27/n1/fig_tab/nbt.1518_T1.html ' 'for several effective genome sizes. This value is ' 'needed to detect enriched regions that, if not ' 'discarded can bias the results.', default=None, type=int, required=True) required.add_argument('--genome', '-g', help='Genome in two bit format. Most genomes can be ' 'found here: http://hgdownload.cse.ucsc.edu/gbdb/ ' 'Search for the .2bit ending. Otherwise, fasta ' 'files can be converted to 2bit using the UCSC ' 'programm called faToTwoBit available for different ' 'plattforms at ' 'http://hgdownload.cse.ucsc.edu/admin/exe/', metavar='2bit FILE', required=True) required.add_argument('--fragmentLength', '-l', help='Fragment length used for the sequencing. If ' 'paired-end reads are used, the fragment length is ' 'computed based from the bam file', type=int, required=True) # define the optional arguments optional = parser.add_argument_group('Optional arguments') optional.add_argument("--help", "-h", action="help", help="show this help message and exit") optional.add_argument('--sampleSize', default=5e7, help='Number of sampling points to be considered.', type=int) optional.add_argument('--extraSampling', help='BED file containing genomic regions for which ' 'extra sampling is required because they are ' 'underrepresented in the genome.', type=argparse.FileType('r'), metavar='BED file') group = parser.add_argument_group('Output options') group.add_argument('--GCbiasFrequenciesFile', '-freq', help='Path to save the file containing ' 'the observed and expected read frequencies per %%GC-' 'content. This file is needed to run the ' 'correctGCBias tool. This is a text file.', type=argparse.FileType('w'), metavar='FILE', required=True) plot = parser.add_argument_group('Diagnostic plot options') plot.add_argument('--biasPlot', metavar='FILE NAME', help='If given, a diagnostic image summarizing ' 'the GC-bias will be saved.') plot.add_argument('--regionSize', metavar='INT', type=int, default=300, help='To plot the reads per %%GC over a region' 'the size of the region is required. By default, ' 'the bin size is set to 300 bases, which is close to the ' 'standard fragment size for Illumina machines. However, ' 'if the depth of sequencing is low, a larger bin size ' 'will be required, otherwise many bins will not ' 'overlap with any read') group.add_argument('--plotFileFormat', metavar='', help='image format type. If given, this ' 'option overrides the ' 'image format based on the plotFile ending. ' 'The available options are: "png", ' '"eps", "pdf" and "svg"', choices=['png', 'pdf', 'svg', 'eps']) return parser def getPositionsToSample(chrom, start, end, stepSize): """ check if the region submitted to the worker overlaps with the region to take extra effort to sample. If that is the case, the regions to sample array is increased to match each of the positions in the extra effort region sampled at the same stepSize along the interval. If a filter out tree is given, then from positions to sample those regions are cleaned """ positions_to_sample = np.arange(start, end, stepSize) if global_vars['filter_out']: filter_out_tree = GTF(global_vars['filter_out']) else: filter_out_tree = None if global_vars['extra_sampling_file']: extra_tree = GTF(global_vars['extra_sampling_file']) else: extra_tree = None if extra_tree: orig_len = len(positions_to_sample) try: extra_match = extra_tree.findOverlaps(chrom, start, end) except KeyError: extra_match = [] if len(extra_match) > 0: for intval in extra_match: positions_to_sample = np.append(positions_to_sample, list(range(intval[0], intval[1], stepSize))) # remove duplicates positions_to_sample = np.unique(np.sort(positions_to_sample)) if debug: print("sampling increased to {} from {}".format( len(positions_to_sample), orig_len)) # skip regions that are filtered out if filter_out_tree: try: out_match = filter_out_tree.findOverlaps(chrom, start, end) except KeyError: out_match = [] if len(out_match) > 0: for intval in out_match: positions_to_sample = \ positions_to_sample[ (positions_to_sample < intval[0]) | (positions_to_sample >= intval[1])] return positions_to_sample def countReadsPerGC_wrapper(args): return countReadsPerGC_worker(*args) def countReadsPerGC_worker(chromNameBam, start, end, stepSize, regionSize, chrNameBamToBit, verbose=False): """given a genome region defined by (start, end), the GC content is quantified for regions of size regionSize that are contiguous """ chromNameBit = chrNameBamToBit[chromNameBam] tbit = py2bit.open(global_vars['2bit']) bam = bamHandler.openBam(global_vars['bam']) c = 1 sub_reads_per_gc = [] positions_to_sample = getPositionsToSample(chromNameBit, start, end, stepSize) for index in range(len(positions_to_sample)): i = positions_to_sample[index] # stop if region extends over the chromosome end if tbit.chroms(chromNameBit) < i + regionSize: break try: gc = getGC_content(tbit, chromNameBit, int(i), int(i + regionSize)) except Exception as detail: if verbose: print("{}:{}-{}".format(chromNameBit, i, i + regionSize)) print(detail) continue numberReads = bam.count(chromNameBam, i, i + regionSize) sub_reads_per_gc.append((numberReads, gc)) c += 1 return sub_reads_per_gc def tabulateGCcontent_wrapper(args): return tabulateGCcontent_worker(*args) def tabulateGCcontent_worker(chromNameBam, start, end, stepSize, fragmentLength, chrNameBamToBit, verbose=False): r""" given genome regions, the GC content of the genome is tabulated for fragments of length 'fragmentLength' each 'stepSize' positions. >>> test = Tester() >>> args = test.testTabulateGCcontentWorker() >>> N_gc, F_gc = tabulateGCcontent_worker(*args) The forward read positions are: [1, 4, 10, 10, 16, 18] which correspond to a GC of [1, 1, 1, 1, 2, 1] The evaluated position are [0, 2, 4, 6, 8, 10, 12, 14, 16, 18] the corresponding GC is [2, 1, 1, 2, 2, 1, 2, 3, 2, 1] >>> print(N_gc) [0 4 5 1] >>> print(F_gc) [0 4 1 0] >>> test.set_filter_out_file() >>> chrNameBam2bit = {'2L': 'chr2L'} Test for the filter out option >>> N_gc, F_gc = tabulateGCcontent_worker('2L', 0, 20, 2, ... {'median': 3}, chrNameBam2bit) >>> test.unset_filter_out_file() The evaluated positions are [ 0 2 8 10 12 14 16 18] >>> print(N_gc) [0 3 4 1] >>> print(F_gc) [0 3 1 0] Test for extra_sampling option >>> test.set_extra_sampling_file() >>> chrNameBam2bit = {'2L': 'chr2L'} >>> res = tabulateGCcontent_worker('2L', 0, 20, 2, ... {'median': 3}, chrNameBam2bit) The new positions evaluated are [0, 1, 2, 3, 4, 6, 8, 10, 12, 14, 16, 18] and the GC is [2, 1, 1, 0, 1, 2, 2, 1, 2, 3, 2, 1] >>> print(res[0]) [1 5 5 1] >>> print(res[1]) [0 5 1 0] """ if start > end: raise NameError("start %d bigger that end %d" % (start, end)) chromNameBit = chrNameBamToBit[chromNameBam] # array to keep track of the GC from regions of length 'fragmentLength' # from the genome. The index of the array is used to # indicate the gc content. The values inside the # array are counts. Thus, if N_gc[10] = 3, that means # that 3 regions have a gc_content of 10. subN_gc = np.zeros(fragmentLength['median'] + 1, dtype='int') subF_gc = np.zeros(fragmentLength['median'] + 1, dtype='int') tbit = py2bit.open(global_vars['2bit']) bam = bamHandler.openBam(global_vars['bam']) peak = 0 startTime = time.time() if verbose: print("[{:.3f}] computing positions to " "sample".format(time.time() - startTime)) positions_to_sample = getPositionsToSample(chromNameBit, start, end, stepSize) read_counts = [] # Optimize IO. # if the sample regions are far apart from each # other is faster to go to each location and fetch # the reads found there. # Otherwise, if the regions to sample are close to # each other, is faster to load all the reads in # a large region into memory and consider only # those falling into the positions to sample. # The following code gets the reads # that are at sampling positions that lie close together if np.mean(np.diff(positions_to_sample)) < 1000: start_pos = min(positions_to_sample) end_pos = max(positions_to_sample) if verbose: print("[{:.3f}] caching reads".format(time.time() - startTime)) counts = np.bincount([r.pos - start_pos for r in bam.fetch(chromNameBam, start_pos, end_pos + 1) if not r.is_reverse and r.pos >= start_pos], minlength=end_pos - start_pos + 2) read_counts = counts[positions_to_sample - min(positions_to_sample)] if verbose: print("[{:.3f}] finish caching reads.".format( time.time() - startTime)) countTime = time.time() c = 1 for index in range(len(positions_to_sample)): i = positions_to_sample[index] # stop if the end of the chromosome is reached if i + fragmentLength['median'] > tbit.chroms(chromNameBit): break try: gc = getGC_content(tbit, chromNameBit, int(i), int(i + fragmentLength['median']), fraction=False) except Exception as detail: if verbose: print(detail) continue subN_gc[gc] += 1 # count all reads at position 'i' if len(read_counts) == 0: # case when no cache was done num_reads = len([x.pos for x in bam.fetch(chromNameBam, i, i + 1) if x.is_reverse is False and x.pos == i]) else: num_reads = read_counts[index] if num_reads >= global_vars['max_reads']: peak += 1 continue subF_gc[gc] += num_reads if verbose: if index % 50000 == 0: endTime = time.time() print("%s processing %d (%.1f per sec) @ %s:%s-%s %s" % (multiprocessing.current_process().name, index, index / (endTime - countTime), chromNameBit, start, end, stepSize)) c += 1 if verbose: endTime = time.time() print("%s processing %d (%.1f per sec) @ %s:%s-%s %s" % (multiprocessing.current_process().name, index, index / (endTime - countTime), chromNameBit, start, end, stepSize)) print("%s total time %.1f @ %s:%s-%s %s" % (multiprocessing.current_process().name, (endTime - startTime), chromNameBit, start, end, stepSize)) return(subN_gc, subF_gc) def tabulateGCcontent(fragmentLength, chrNameBitToBam, stepSize, chromSizes, numberOfProcessors=None, verbose=False, region=None): r""" Subdivides the genome or the reads into chunks to be analyzed in parallel using several processors. This codes handles the creation of workers that tabulate the GC content for small regions and then collects and integrates the results >>> test = Tester() >>> arg = test.testTabulateGCcontent() >>> res = tabulateGCcontent(*arg) >>> res array([[ 0. , 18. , 1. ], [ 3. , 63. , 0.45815996], [ 7. , 159. , 0.42358185], [ 25. , 192. , 1.25278115], [ 28. , 215. , 1.25301422], [ 16. , 214. , 0.71935396], [ 12. , 95. , 1.21532959], [ 9. , 24. , 3.60800971], [ 3. , 11. , 2.62400706], [ 0. , 0. , 1. ], [ 0. , 0. , 1. ]]) """ global global_vars chrNameBamToBit = dict([(v, k) for k, v in chrNameBitToBam.items()]) chunkSize = int(min(2e6, 4e5 / global_vars['reads_per_bp'])) chromSizes = [(k, v) for k, v in chromSizes if k in list(chrNameBamToBit.keys())] imap_res = mapReduce.mapReduce((stepSize, fragmentLength, chrNameBamToBit, verbose), tabulateGCcontent_wrapper, chromSizes, genomeChunkLength=chunkSize, numberOfProcessors=numberOfProcessors, region=region) for subN_gc, subF_gc in imap_res: try: F_gc += subF_gc N_gc += subN_gc except NameError: F_gc = subF_gc N_gc = subN_gc if sum(F_gc) == 0: sys.exit("No fragments included in the sampling! Consider decreasing (or maybe increasing) the --sampleSize parameter") scaling = float(sum(N_gc)) / float(sum(F_gc)) R_gc = np.array([float(F_gc[x]) / N_gc[x] * scaling if N_gc[x] and F_gc[x] > 0 else 1 for x in range(len(F_gc))]) data = np.transpose(np.vstack((F_gc, N_gc, R_gc))) return data def countReadsPerGC(regionSize, chrNameBitToBam, stepSize, chromSizes, numberOfProcessors=None, verbose=False, region=None): r""" Computes for a region of size regionSize, the GC of the region and the number of reads that overlap it. >>> test = Tester() >>> arg = test.testCountReadsPerGC() >>> reads_per_gc = countReadsPerGC(*arg) >>> reads_per_gc[0:5,:] array([[ 132. , 0.44 ], [ 132. , 0.44 ], [ 133. , 0.44 ], [ 134. , 0.43666667], [ 134. , 0.44 ]]) """ global global_vars chrNameBamToBit = dict([(v, k) for k, v in chrNameBitToBam.items()]) chunkSize = int(min(2e6, 4e5 / global_vars['reads_per_bp'])) imap_res = mapReduce.mapReduce((stepSize, regionSize, chrNameBamToBit, verbose), countReadsPerGC_wrapper, chromSizes, genomeChunkLength=chunkSize, numberOfProcessors=numberOfProcessors, region=region) reads_per_gc = [] for sub_reads_per_gc in imap_res: reads_per_gc += sub_reads_per_gc reads_per_gc = np.asarray(reads_per_gc) return reads_per_gc def smooth(x, window_len=3): """ *CURRENTLY* not being used smooths the values from the frequencies by taking the average of 'window_len' values. window_len has to be an odd number """ # do not smooth small arrays if len(x) < window_len * 2: return x i = 0 y = x[:] half_width = (window_len - 1) / 2 for i in range(0, len(x)): if i < half_width or i + half_width + 1 > len(x): continue else: y[i] = np.mean(x[i - half_width:i + half_width + 1]) # clip low values, this avoid problems with zeros return y def bin_by(x, y, nbins=10): """ Bin x by y. Returns the binned "x" values and the left edges of the bins """ bins = np.linspace(0, 1, nbins + 1) # To avoid extra bin for the max value bins[-1] += 1 indices = np.digitize(y, bins) output = [] for i in range(1, len(bins)): output.append(x[indices == i]) # Just return the left edges of the bins bins = bins[:-1] return output, bins def plotGCbias(file_name, frequencies, reads_per_gc, region_size, image_format=None): import matplotlib matplotlib.use('Agg') matplotlib.rcParams['pdf.fonttype'] = 42 matplotlib.rcParams['svg.fonttype'] = 'none' import matplotlib.pyplot as plt # prepare data for boxplot reads, GC = reads_per_gc.T reads_per_gc, bin_labels = bin_by(reads, GC, nbins=100) to_keep = [idx for idx, x in enumerate(bin_labels) if 0.2 <= x <= 0.7] reads_per_gc = [reads_per_gc[x] for x in to_keep] bin_labels = [bin_labels[x] for x in to_keep] title = "reads per regions of {} bp".format(region_size) fig = plt.figure(figsize=(6, 8)) ax1 = fig.add_subplot(211, title=title) ax2 = fig.add_subplot(212, title='normalized observed/expected read counts') # make boxplot bp = ax1.boxplot(reads_per_gc, notch=0, patch_artist=True) plt.setp(bp['boxes'], color='black', facecolor='LightGreen') plt.setp(bp['medians'], color='black') plt.setp(bp['whiskers'], color='black', linestyle='dashed') plt.setp(bp['fliers'], marker='None') # get the whisker that spands the most y_max = max([x.get_data()[1][1] for x in bp['whiskers']]) ax1.set_ylim(0 - (y_max * 0.05), y_max * 1.05) ax1.set_ylabel('Number of reads') ax1.set_xlabel('GC fraction') xticks = [idx for idx, x in enumerate(bin_labels) if int(x * 100) % 10 == 0] ax1.set_xticks(xticks) ax1.set_xticklabels(["{:.1f}".format(bin_labels[x]) for x in xticks]) x = np.linspace(0, 1, frequencies.shape[0]) ax2.plot(x, np.log2(frequencies[:, 2]), color='#8c96f0') ax2.set_xlabel('GC fraction') ax2.set_ylabel('log2ratio observed/expected') ax2.set_xlim(0.2, 0.7) plt.tight_layout() plt.savefig(file_name, bbox_inches='tight', dpi=100, format=image_format) plt.close() def main(args=None): args = parse_arguments().parse_args(args) if args.extraSampling: extra_sampling_file = args.extraSampling.name args.extraSampling.close() else: extra_sampling_file = None global global_vars global_vars = {} global_vars['2bit'] = args.genome global_vars['bam'] = args.bamfile global_vars['filter_out'] = args.blackListFileName global_vars['extra_sampling_file'] = extra_sampling_file tbit = py2bit.open(global_vars['2bit']) bam = bamHandler.openBam(global_vars['bam']) if args.fragmentLength: fragment_len_dict = \ {'median': args.fragmentLength} else: fragment_len_dict, __ = \ get_read_and_fragment_length(args.bamfile, None, numberOfProcessors=args.numberOfProcessors, verbose=args.verbose) if not fragment_len_dict: print("\nPlease provide the fragment length used for the " "sample preparation.\n") exit(1) fragment_len_dict = {'median': int(fragment_len_dict['median'])} chrNameBitToBam = tbitToBamChrName(list(tbit.chroms().keys()), bam.references) global_vars['genome_size'] = sum(tbit.chroms().values()) global_vars['total_reads'] = bam.mapped global_vars['reads_per_bp'] = \ float(global_vars['total_reads']) / args.effectiveGenomeSize confidence_p_value = float(1) / args.sampleSize # chromSizes: list of tuples chromSizes = [(bam.references[i], bam.lengths[i]) for i in range(len(bam.references))] # use poisson distribution to identify peaks that should be discarted. # I multiply by 4, because the real distribution of reads # vary depending on the gc content # and the global number of reads per bp may a be too low. # empirically, a value of at least 4 times as big as the # reads_per_bp was found. # Similarly for the min value, I divide by 4. global_vars['max_reads'] = \ poisson(4 * global_vars['reads_per_bp'] * fragment_len_dict['median']).isf(confidence_p_value) # this may be of not use, unless the depth of sequencing is really high # as this value is close to 0 global_vars['min_reads'] = \ poisson(0.25 * global_vars['reads_per_bp'] * fragment_len_dict['median']).ppf(confidence_p_value) for key in global_vars: print("{}: {}".format(key, global_vars[key])) print("computing frequencies") # the GC of the genome is sampled each stepSize bp. stepSize = max(int(global_vars['genome_size'] / args.sampleSize), 1) print("stepSize: {}".format(stepSize)) data = tabulateGCcontent(fragment_len_dict, chrNameBitToBam, stepSize, chromSizes, numberOfProcessors=args.numberOfProcessors, verbose=args.verbose, region=args.region) np.savetxt(args.GCbiasFrequenciesFile.name, data) if args.biasPlot: reads_per_gc = countReadsPerGC(args.regionSize, chrNameBitToBam, stepSize * 10, chromSizes, numberOfProcessors=args.numberOfProcessors, verbose=args.verbose, region=args.region) plotGCbias(args.biasPlot, data, reads_per_gc, args.regionSize, image_format=args.plotFileFormat) class Tester(): def __init__(self): import os self.root = os.path.dirname(os.path.abspath(__file__)) + "/test/test_corrGC/" self.tbitFile = self.root + "sequence.2bit" self.bamFile = self.root + "test.bam" self.mappability = self.root + "mappability.bw" self.chrNameBam = '2L' self.chrNameBit = 'chr2L' bam = bamHandler.openBam(self.bamFile) tbit = py2bit.open(self.tbitFile) global debug debug = 0 global global_vars global_vars = {'2bit': self.tbitFile, 'bam': self.bamFile, 'filter_out': None, 'mappability': self.mappability, 'extra_sampling_file': None, 'max_reads': 5, 'min_reads': 0, 'min_reads': 0, 'reads_per_bp': 0.3, 'total_reads': bam.mapped, 'genome_size': sum(tbit.chroms().values()) } def testTabulateGCcontentWorker(self): stepSize = 2 fragmentLength = {'min': 1, 'median': 3, 'max': 5} start = 0 end = 20 chrNameBam2bit = {'2L': 'chr2L'} return (self.chrNameBam, start, end, stepSize, fragmentLength, chrNameBam2bit) def set_filter_out_file(self): global global_vars global_vars['filter_out'] = self.root + "filter_out.bed" def unset_filter_out_file(self): global global_vars global_vars['filter_out'] = None def set_extra_sampling_file(self): global global_vars global_vars['extra_sampling_file'] = self.root + "extra_sampling.bed" def testTabulateGCcontent(self): fragmentLength = {'median': 10} chrNameBitToBam = {'chr2L': '2L'} stepSize = 1 bam = bamHandler.openBam(global_vars['bam']) chromSizes = [(bam.references[i], bam.lengths[i]) for i in range(len(bam.references))] return (fragmentLength, chrNameBitToBam, stepSize, chromSizes, 1) def testCountReadsPerGC(self): regionSize = 300 chrNameBitToBam = {'chr2L': '2L'} stepSize = 1 bam = bamHandler.openBam(global_vars['bam']) chromSizes = [(bam.references[i], bam.lengths[i]) for i in range(len(bam.references))] return (regionSize, chrNameBitToBam, stepSize, chromSizes, 1) if __name__ == "__main__": main() deepTools-2.5.0/deeptools/computeMatrix.py0000640000201600010240000005353413021231054020030 0ustar ryanbioinfo#!/usr/bin/env python # -*- coding: utf-8 -*- import argparse import sys import os import multiprocessing from deeptools.parserCommon import writableFile, numberOfProcessors from deeptools._version import __version__ import deeptools.config as cfg from deeptools import parserCommon from deeptools import heatmapper import deeptools.computeMatrixOperations as cmo import deeptools.deepBlue as db def parse_arguments(args=None): parser = \ argparse.ArgumentParser( formatter_class=argparse.RawDescriptionHelpFormatter, description=""" This tool calculates scores per genome regions and prepares an intermediate file that can be used with ``plotHeatmap`` and ``plotProfiles``. Typically, the genome regions are genes, but any other regions defined in a BED file can be used. computeMatrix accepts multiple score files (bigWig format) and multiple regions files (BED format). This tool can also be used to filter and sort regions according to their score. To learn more about the specific parameters, type: $ computeMatrix reference-point --help or $ computeMatrix scale-regions --help """, epilog='An example usage is:\n computeMatrix reference-point -S ' ' -R -b 1000\n \n') parser.add_argument('--version', action='version', version='%(prog)s {}'.format(__version__)) subparsers = parser.add_subparsers( title='Commands', dest='command', metavar='') dbParser = parserCommon.deepBlueOptionalArgs() # scale-regions mode options subparsers.add_parser( 'scale-regions', formatter_class=argparse.ArgumentDefaultsHelpFormatter, parents=[computeMatrixRequiredArgs(), computeMatrixOutputArgs(), computeMatrixOptArgs(case='scale-regions'), parserCommon.gtf_options(), dbParser], help="In the scale-regions mode, all regions in the BED file are " "stretched or shrunken to the length (in bases) indicated by the user.", usage='An example usage is:\n computeMatrix scale-regions -S ' ' -R -b 1000\n\n') # reference point arguments subparsers.add_parser( 'reference-point', formatter_class=argparse.ArgumentDefaultsHelpFormatter, parents=[computeMatrixRequiredArgs(), computeMatrixOutputArgs(), computeMatrixOptArgs(case='reference-point'), parserCommon.gtf_options(), dbParser], help="Reference-point refers to a position within a BED region " "(e.g., the starting point). In this mode, only those genomic" "positions before (upstream) and/or after (downstream) of the " "reference point will be plotted.", usage='An example usage is:\n computeMatrix reference-point -S ' ' -R -a 3000 -b 3000\n\n') return parser def computeMatrixRequiredArgs(args=None): parser = argparse.ArgumentParser(add_help=False) required = parser.add_argument_group('Required arguments') required.add_argument('--regionsFileName', '-R', metavar='File', help='File name, in BED format, containing ' 'the regions to plot. If multiple bed files are given, each one is considered a ' 'group that can be plotted separately. Also, adding a "#" symbol in the bed file ' 'causes all the regions until the previous "#" to be considered one group.', nargs='+', required=True) required.add_argument('--scoreFileName', '-S', help='bigWig file(s) containing ' 'the scores to be plotted. BigWig ' 'files can be obtained by using the bamCoverage ' 'or bamCompare tools. More information about ' 'the bigWig file format can be found at ' 'http://genome.ucsc.edu/goldenPath/help/bigWig.html ', metavar='File', nargs='+', required=True) return parser def computeMatrixOutputArgs(args=None): parser = argparse.ArgumentParser(add_help=False) output = parser.add_argument_group('Output options') output.add_argument('--outFileName', '-out', help='File name to save the gzipped matrix file ' 'needed by the "plotHeatmap" and "plotProfile" tools.', type=writableFile, required=True) # TODO This isn't implemented, see deeptools/heatmapper.py in the saveTabulatedValues() function # output.add_argument('--outFileNameData', # help='Name to save the averages per matrix ' # 'column into a text file. This corresponds to ' # 'the underlying data used to ' # 'plot a summary profile. Example: myProfile.tab', # type=argparse.FileType('w')) output.add_argument('--outFileNameMatrix', help='If this option is given, then the matrix ' 'of values underlying the heatmap will be saved ' 'using the indicated name, e.g. IndividualValues.tab.' 'This matrix can easily be loaded into R or ' 'other programs.', metavar='FILE', type=writableFile) output.add_argument('--outFileSortedRegions', help='File name in which the regions are saved ' 'after skiping zeros or min/max threshold values. The ' 'order of the regions in the file follows the sorting ' 'order selected. This is useful, for example, to ' 'generate other heatmaps keeping the sorting of the ' 'first heatmap. Example: Heatmap1sortedRegions.bed', metavar='BED file', type=argparse.FileType('w')) return parser def computeMatrixOptArgs(case=['scale-regions', 'reference-point'][0]): parser = argparse.ArgumentParser(add_help=False) optional = parser.add_argument_group('Optional arguments') optional.add_argument('--version', action='version', version='%(prog)s {}'.format(__version__)) if case == 'scale-regions': optional.add_argument('--regionBodyLength', '-m', default=1000, type=int, help='Distance in bases to which all regions will ' 'be fit.') optional.add_argument('--startLabel', default='TSS', help='Label shown in the plot for the start of ' 'the region. Default is TSS (transcription ' 'start site), but could be changed to anything, ' 'e.g. "peak start". Note that this is only ' 'useful if you plan to plot the results yourself ' 'and not, for example, with plotHeatmap, which ' 'will override this.') optional.add_argument('--endLabel', default='TES', help='Label shown in the plot for the region ' 'end. Default is TES (transcription end site). ' 'See the --startLabel option for more ' 'information. ') optional.add_argument('--beforeRegionStartLength', '-b', '--upstream', default=0, type=int, help='Distance upstream of the start site of ' 'the regions defined in the region file. If the ' 'regions are genes, this would be the distance ' 'upstream of the transcription start site.') optional.add_argument('--afterRegionStartLength', '-a', '--downstream', default=0, type=int, help='Distance downstream of the end site ' 'of the given regions. If the ' 'regions are genes, this would be the distance ' 'downstream of the transcription end site.') optional.add_argument("--unscaled5prime", default=0, type=int, help='Number of bases at the 5-prime end of the ' 'region to exclude from scaling. By default, ' 'each region is scaled to a given length (see the --regionBodyLength option). In some cases it is useful to look at unscaled signals around region boundaries, so this setting specifies the number of unscaled bases on the 5-prime end of each boundary.') optional.add_argument("--unscaled3prime", default=0, type=int, help='Like --unscaled3prime, but for the 3-prime ' 'end.') elif case == 'reference-point': optional.add_argument('--referencePoint', default='TSS', choices=['TSS', 'TES', 'center'], help='The reference point for the plotting ' 'could be either the region start (TSS), the ' 'region end (TES) or the center of the region. ' 'Note that regardless of what you specify, ' 'plotHeatmap/plotProfile will default to using "TSS" as the ' 'label.') # set region body length to zero for reference point mode optional.add_argument('--regionBodyLength', help=argparse.SUPPRESS, default=0, type=int) optional.add_argument('--unscaled5prime', default=0, type=int, help=argparse.SUPPRESS) optional.add_argument('--unscaled3prime', default=0, type=int, help=argparse.SUPPRESS) optional.add_argument('--beforeRegionStartLength', '-b', '--upstream', default=500, type=int, metavar='INT bp', help='Distance upstream of the reference-point ' 'selected.') optional.add_argument('--afterRegionStartLength', '-a', '--downstream', default=1500, metavar='INT bp', type=int, help='Distance downstream of the ' 'reference-point selected.') optional.add_argument('--nanAfterEnd', action='store_true', help='If set, any values after the region end ' 'are discarded. This is useful to visualize ' 'the region end when not using the ' 'scale-regions mode and when the reference-' 'point is set to the TSS.') optional.add_argument('--binSize', '-bs', help='Length, in bases, of the non-overlapping ' 'bins for averaging the score over the ' 'regions length.', type=int, default=10) optional.add_argument('--sortRegions', help='Whether the output file should present the ' 'regions sorted. The default is to not sort the regions. ' 'Note that this is only useful if you plan to plot ' 'the results yourself and not, for example, with ' 'plotHeatmap, which will override this. Note also that ' 'unsorted output will be in whatever order the regions ' 'happen to be processed in and not match the order in ' 'the input files. If you require the output order to ' 'match that of the input regions, then either specify ' '"keep" or use computeMatrixOperations to resort the ' 'results file.', choices=["descend", "ascend", "no", "keep"], default='keep') optional.add_argument('--sortUsing', help='Indicate which method should be used for ' 'sorting. The value is computed for each row.' 'Note that the region_length option will lead ' 'to a dotted line within the heatmap that indicates ' 'the end of the regions.', choices=["mean", "median", "max", "min", "sum", "region_length"], default='mean') optional.add_argument('--sortUsingSamples', help='List of sample numbers (order as in matrix), ' 'that are used for sorting by --sortUsing, ' 'no value uses all samples, ' 'example: --sortUsingSamples 1 3', type=int, nargs='+') optional.add_argument('--averageTypeBins', default='mean', choices=["mean", "median", "min", "max", "std", "sum"], help='Define the type of statistic that should be ' 'used over the bin size range. The ' 'options are: "mean", "median", "min", "max", "sum" ' 'and "std". The default is "mean".') optional.add_argument('--missingDataAsZero', help='If set, missing data (NAs) will be treated as zeros. ' 'The default is to ignore such cases, which will be depicted as black areas in ' 'a heatmap. (see the --missingDataColor argument ' 'of the plotHeatmap command for additional options).', action='store_true') optional.add_argument('--skipZeros', help='Whether regions with only scores of zero ' 'should be included or not. Default is to include ' 'them.', action='store_true') optional.add_argument('--minThreshold', default=None, type=float, help='Numeric value. Any region containing a ' 'value that is less than or equal to this ' 'will be skipped. This is useful to skip, ' 'for example, genes where the read count is zero ' 'for any of the bins. This could be the result of ' 'unmappable areas and can bias the overall results.') optional.add_argument('--maxThreshold', default=None, type=float, help='Numeric value. Any region containing a value ' 'greater than or equal to this ' 'will be skipped. The maxThreshold is useful to ' 'skip those few regions with very high read counts ' '(e.g. micro satellites) that may bias the average ' 'values.') optional.add_argument('--blackListFileName', '-bl', help="A BED file containing regions that should be excluded from all analyses. Currently this works by rejecting genomic chunks that happen to overlap an entry. Consequently, for BAM files, if a read partially overlaps a blacklisted region or a fragment spans over it, then the read/fragment might still be considered.", metavar="BED file", required=False) # in contrast to other tools, # computeMatrix by default outputs # messages and the --quiet flag supresses them optional.add_argument('--quiet', '-q', help='Set to remove any warning or processing ' 'messages.', action='store_true') optional.add_argument('--scale', help='If set, all values are multiplied by ' 'this number.', type=float, default=1) optional.add_argument('--numberOfProcessors', '-p', help='Number of processors to use. Type "max/2" to ' 'use half the maximum number of processors or "max" ' 'to use all available processors.', metavar="INT", type=numberOfProcessors, default=cfg.config.get('general', 'default_proc_number'), required=False) return parser def process_args(args=None): args = parse_arguments().parse_args(args) if args.quiet is False: args.verbose = True else: args.verbose = False if args.command == 'scale-regions': args.nanAfterEnd = False args.referencePoint = None elif args.command == 'reference-point': if args.beforeRegionStartLength == 0 and \ args.afterRegionStartLength == 0: sys.exit("\nUpstrean and downstream regions are both " "set to 0. Nothing to output. Maybe you want to " "use the scale-regions mode?\n") return(args) def main(args=None): args = process_args(args) parameters = {'upstream': args.beforeRegionStartLength, 'downstream': args.afterRegionStartLength, 'body': args.regionBodyLength, 'bin size': args.binSize, 'ref point': args.referencePoint, 'verbose': args.verbose, 'bin avg type': args.averageTypeBins, 'missing data as zero': args.missingDataAsZero, 'min threshold': args.minThreshold, 'max threshold': args.maxThreshold, 'scale': args.scale, 'skip zeros': args.skipZeros, 'nan after end': args.nanAfterEnd, 'proc number': args.numberOfProcessors, 'sort regions': args.sortRegions, 'sort using': args.sortUsing, 'unscaled 5 prime': args.unscaled5prime, 'unscaled 3 prime': args.unscaled3prime } hm = heatmapper.heatmapper() # Preload deepBlue files, which need to then be deleted deepBlueFiles = [] for idx, fname in enumerate(args.scoreFileName): if db.isDeepBlue(fname): deepBlueFiles.append([fname, idx]) if len(deepBlueFiles) > 0: sys.stderr.write("Preloading the following deepBlue files: {}\n".format(",".join([x[0] for x in deepBlueFiles]))) regs = db.makeRegions(args.regionsFileName, args) for x in deepBlueFiles: x.extend([args, regs]) if len(deepBlueFiles) > 1 and args.numberOfProcessors > 1: pool = multiprocessing.Pool(args.numberOfProcessors) res = pool.map_async(db.preloadWrapper, deepBlueFiles).get(9999999) else: res = list(map(db.preloadWrapper, deepBlueFiles)) # substitute the file names with the temp files for (ftuple, r) in zip(deepBlueFiles, res): args.scoreFileName[ftuple[1]] = r deepBlueFiles = [[x[0], x[1]] for x in deepBlueFiles] del regs scores_file_list = args.scoreFileName hm.computeMatrix(scores_file_list, args.regionsFileName, parameters, blackListFileName=args.blackListFileName, verbose=args.verbose, allArgs=args) if args.sortRegions not in ['no', 'keep']: sortUsingSamples = [] if args.sortUsingSamples is not None: for i in args.sortUsingSamples: if (i > 0 and i <= hm.matrix.get_num_samples()): sortUsingSamples.append(i - 1) else: exit("The value {0} for --sortUsingSamples is not valid. Only values from 1 to {1} are allowed.".format(args.sortUsingSamples, hm.matrix.get_num_samples())) print('Samples used for ordering within each group: ', sortUsingSamples) hm.matrix.sort_groups(sort_using=args.sortUsing, sort_method=args.sortRegions, sample_list=sortUsingSamples) elif args.sortRegions == 'keep': hm.parameters['group_labels'] = hm.matrix.group_labels hm.parameters["group_boundaries"] = hm.matrix.group_boundaries cmo.sortMatrix(hm, args.regionsFileName, args.transcriptID, args.transcript_id_designator) hm.save_matrix(args.outFileName) if args.outFileNameMatrix: hm.save_matrix_values(args.outFileNameMatrix) if args.outFileSortedRegions: hm.save_BED(args.outFileSortedRegions) # Clean up temporary bigWig files, if applicable if not args.deepBlueKeepTemp: for k, v in deepBlueFiles: os.remove(args.scoreFileName[v]) else: for k, v in deepBlueFiles: print("{} is stored in {}".format(k, args.scoreFileName[v])) deepTools-2.5.0/deeptools/computeMatrixOperations.py0000640000201600010240000006175313061740003022101 0ustar ryanbioinfo#!/usr/bin/env python import deeptools.heatmapper as heatmapper import deeptoolsintervals.parse as dti import numpy as np import argparse import sys import os import csv from deeptools._version import __version__ def parse_arguments(): parser = argparse.ArgumentParser( formatter_class=argparse.RawDescriptionHelpFormatter, description=""" This tool performs a variety of operations on files produced by computeMatrix. detailed help: computeMatrixOperations info -h or computeMatrixOperations subset -h or computeMatrixOperations filterStrand -h or computeMatrixOperations rbind -h or computeMatrixOperations cbind -h or computeMatrixOperations sort -h """, epilog='example usages:\n' 'computeMatrixOperations subset -m input.mat.gz -o output.mat.gz --group "group 1" "group 2" --samples "sample 3" "sample 10"\n\n' ' \n\n') subparsers = parser.add_subparsers( title='Commands', dest='command', metavar='') # info subparsers.add_parser( 'info', formatter_class=argparse.ArgumentDefaultsHelpFormatter, parents=[infoArgs()], help="Print group and sample information", usage='An example usage is:\n computeMatrixOperations info -m input.mat.gz\n\n') # subset subparsers.add_parser( 'subset', formatter_class=argparse.ArgumentDefaultsHelpFormatter, parents=[infoArgs(), subsetArgs()], help="Actually subset the matrix. The group and sample orders are honored, so one can also reorder files.", usage='An example usage is:\n computeMatrixOperations subset -m ' 'input.mat.gz -o output.mat.gz --groups "group 1" "group 2" ' '--samples "sample 3" "sample 10"\n\n') # filterStrand subparsers.add_parser( 'filterStrand', formatter_class=argparse.ArgumentDefaultsHelpFormatter, parents=[infoArgs(), filterStrandArgs()], help="Filter entries by strand.", usage='Example usage:\n computeMatrixOperations filterStrand -m ' 'input.mat.gz -o output.mat.gz --strand +\n\n') # rbind subparsers.add_parser( 'rbind', formatter_class=argparse.ArgumentDefaultsHelpFormatter, parents=[bindArgs()], help="merge multiple matrices by concatenating them head to tail. This assumes that the same samples are present in each in the same order.", usage='Example usage:\n computeMatrixOperations rbind -m ' 'input1.mat.gz input2.mat.gz -o output.mat.gz\n\n') # cbind subparsers.add_parser( 'cbind', formatter_class=argparse.ArgumentDefaultsHelpFormatter, parents=[bindArgs()], help="merge multiple matrices by concatenating them left to right. No assumptions are made about the row order. Regions not present in the first file specified are ignored. Regions missing in subsequent files will result in NAs. Note that if you cbind matrices where the samples have different widths, then the x-axis tick positions for the left-most samples will be correct and those on the right-most samples will be incorrect. The labels may also be incorrect for all but the left-most samples. This is due to ticks and labels being the same in all samples (the tick positions are scaled according to the number of data-points per row in a sample)", usage='Example usage:\n computeMatrixOperations cbind -m ' 'input1.mat.gz input2.mat.gz -o output.mat.gz\n\n') # sort subparsers.add_parser( 'sort', formatter_class=argparse.ArgumentDefaultsHelpFormatter, parents=[sortArgs()], help='Sort a matrix file to correspond to the order if entries in the desired input files. The groups of regions designated by the files must be present in the order found in the output of computeMatrix (otherwise, use the subset command first).', usage='Example usage:\n computeMatrixOperations sort -m input.mat.gz -R regions1.bed regions2.bed regions3.gtf -o input.sorted.mat.gz\n\n') parser.add_argument('--version', action='version', version='%(prog)s {}'.format(__version__)) return parser def bindArgs(): parser = argparse.ArgumentParser(add_help=False) required = parser.add_argument_group('Required arguments') required.add_argument('--matrixFile', '-m', help='Matrix files from the computeMatrix tool.', nargs='+', required=True) required.add_argument('--outFileName', '-o', help='Output file name', required=True) return parser def infoArgs(): parser = argparse.ArgumentParser(add_help=False) required = parser.add_argument_group('Required arguments') required.add_argument('--matrixFile', '-m', help='Matrix file from the computeMatrix tool.', required=True) return parser def subsetArgs(): parser = argparse.ArgumentParser(add_help=False) required = parser.add_argument_group('Required arguments') required.add_argument('--outFileName', '-o', help='Output file name', required=True) optional = parser.add_argument_group('Optional arguments') optional.add_argument('--groups', nargs='+', help="Groups to include. If none are specified then all will be included.") optional.add_argument('--samples', nargs='+', help="Samples to include. If none are specified then all will be included.") return parser def filterStrandArgs(): parser = argparse.ArgumentParser(add_help=False) required = parser.add_argument_group('Required arguments') required.add_argument('--outFileName', '-o', help='Output file name', required=True) required.add_argument('--strand', '-s', help='Strand', choices=['+', '-', '.'], required=True) return parser def sortArgs(): parser = argparse.ArgumentParser(add_help=False) required = parser.add_argument_group('Required arguments') required.add_argument('--matrixFile', '-m', help='Matrix file from the computeMatrix tool.', required=True) required.add_argument('--outFileName', '-o', help='Output file name', required=True) required.add_argument('--regionsFileName', '-R', help='File name(s), in BED or GTF format, containing the regions. ' 'If multiple bed files are given, each one is ' 'considered a group that can be plotted separately. ' 'Also, adding a "#" symbol in the bed file causes all ' 'the regions until the previous "#" to be considered ' 'one group. Alternatively for BED files, putting ' 'deepTools_group in the header can be used to indicate a ' 'column with group labels. Note that these should be ' 'sorted such that all group entries are together.', required=True, nargs='+') optional = parser.add_argument_group('Optional arguments') optional.add_argument('--transcriptID', default='transcript', help='When a GTF file is used to provide regions, only ' 'entries with this value as their feature (column 2) ' 'will be processed as transcripts.') optional.add_argument('--transcript_id_designator', default='transcript_id', help='Each region has an ID (e.g., ACTB) assigned to it, ' 'which for BED files is either column 4 (if it exists) ' 'or the interval bounds. For GTF files this is instead ' 'stored in the last column as a key:value pair (e.g., as ' '\'transcript_id "ACTB"\', for a key of transcript_id ' 'and a value of ACTB). In some cases it can be ' 'convenient to use a different identifier. To do so, set ' 'this to the desired key.') return parser def printInfo(matrix): """ Print the groups and samples """ print("Groups:") for group in matrix.matrix.group_labels: print("\t{0}".format(group)) print("Samples:") for sample in matrix.matrix.sample_labels: print("\t{0}".format(sample)) def getGroupBounds(args, matrix): """ Given the group labels, return an indexing array and the resulting boundaries """ bounds = matrix.parameters['group_boundaries'] if args.groups is None: return range(0, matrix.matrix.matrix.shape[0]), np.array(bounds) else: o = list() obounds = [0] for group in args.groups: if group not in matrix.matrix.group_labels: sys.exit("Error: '{0}' is not a valid group\n".format(group)) idx = matrix.matrix.group_labels.index(group) o.extend(range(bounds[idx], bounds[idx + 1])) obounds.append(bounds[idx + 1] - bounds[idx]) return o, np.cumsum(obounds) def getSampleBounds(args, matrix): """ Given the sample labels, return an indexing array """ bounds = matrix.parameters['sample_boundaries'] if args.samples is None: return np.arange(0, matrix.matrix.matrix.shape[1]) else: o = list() for sample in args.samples: if sample not in matrix.matrix.sample_labels: sys.exit("Error: '{0}' is not a valid sample\n".format(sample)) idx = matrix.matrix.sample_labels.index(sample) o.extend(range(bounds[idx], bounds[idx + 1])) return o def subsetRegions(hm, bounds): out = [] for x in bounds: reg = hm.matrix.regions[x] # we need to add a list of [chrom, [(start, end), (start, end)], name, 0, strand, score)] if isinstance(reg, dict): # This happens on occasion starts = reg["start"].split(",") starts = [int(x) for x in starts] ends = reg["end"].split(",") ends = [int(x) for x in ends] regs = [(x, y) for x, y in zip(starts, ends)] out.append([reg["chrom"], regs, reg["name"], 0, reg["strand"], reg["score"]]) else: out.append(reg) return out def filterHeatmap(hm, args): bounds = [0] regions = [] keep = [] for region in hm.matrix.regions: if region[4] == args.strand: keep.append(True) regions.append(region) else: keep.append(False) keep = np.array(keep) # Get the new bounds for idx in range(1, len(hm.matrix.group_boundaries)): i = int(np.sum(keep[hm.matrix.group_boundaries[idx - 1]:hm.matrix.group_boundaries[idx]])) bounds.append(bounds[idx - 1] + i) hm.matrix.group_boundaries = bounds # subset the matrix hm.matrix.matrix = hm.matrix.matrix[keep, :] hm.matrix.regions = regions def insertMatrix(hm, hm2, groupName): """ Given two heatmapper object and a region group name, insert the regions and values from hm2 for that group to the end of those for hm. """ # get the bounds for hm idx = hm.parameters["group_labels"].index(groupName) hmEnd = hm.parameters["group_boundaries"][idx + 1] # get the bounds for hm2 idx2 = hm2.parameters["group_labels"].index(groupName) hm2Start = hm2.parameters["group_boundaries"][idx2] hm2End = hm2.parameters["group_boundaries"][idx2 + 1] # Insert the subset hm2 into hm along axis 0 hm.matrix.matrix = np.insert(hm.matrix.matrix, hmEnd, hm2.matrix.matrix[hm2Start:hm2End, :], axis=0) # Insert the regions hm.matrix.regions[hmEnd:hmEnd] = hm2.matrix.regions[hm2Start:hm2End] # Increase the group boundaries bounds = [] for idx3, bound in enumerate(hm.parameters["group_boundaries"]): if idx3 > idx: bound += hm2End - hm2Start bounds.append(bound) hm.parameters["group_boundaries"] = bounds def appendMatrix(hm, hm2, groupName): """ Given two heatmapper objects and a region group name, append the values from that group in hm2 onto the end of hm. """ # get the bounds for hm2 idx2 = hm2.parameters["group_labels"].index(groupName) hm2Start = hm2.parameters["group_boundaries"][idx2] hm2End = hm2.parameters["group_boundaries"][idx2 + 1] # Append the matrix hm.matrix.matrix = np.concatenate([hm.matrix.matrix, hm2.matrix.matrix[hm2Start:hm2End, :]], axis=0) # Update the bounds hm.parameters["group_boundaries"].append(hm.parameters["group_boundaries"][-1] + hm2End - hm2Start) # Append the regions hm.matrix.regions.extend(hm2.matrix.regions[hm2Start:hm2End]) def rbindMatrices(hm, args): """ This only supports a single group at this point It's assumed that the same samples are present in both and in the exact same order """ hm2 = heatmapper.heatmapper() hm.read_matrix_file(args.matrixFile[0]) for idx in range(1, len(args.matrixFile)): hm2.read_matrix_file(args.matrixFile[idx]) for idx, group in enumerate(hm2.parameters["group_labels"]): if group in hm.parameters["group_labels"]: insertMatrix(hm, hm2, group) else: appendMatrix(hm, hm2, group) # Update the group boundaries attribute hm.matrix.group_labels = hm.parameters['group_labels'] hm.matrix.group_boundaries = hm.parameters['group_boundaries'] def cbindMatrices(hm, args): """ Bind columns from different matrices according to the group and region names Missing regions are left as NA """ hm2 = heatmapper.heatmapper() # Make a dict of region name:row associations hm.read_matrix_file(args.matrixFile[0]) d = dict({x: dict() for x in hm.parameters["group_labels"]}) for idx, group in enumerate(hm.parameters["group_labels"]): s = hm.parameters["group_boundaries"][idx] e = hm.parameters["group_boundaries"][idx + 1] for idx2, reg in enumerate(hm.matrix.regions[s:e]): d[group][reg[2]] = idx2 + s # Iterate through the other matrices for idx in range(1, len(args.matrixFile)): hm2.read_matrix_file(args.matrixFile[idx]) # Add the sample labels hm.parameters['sample_labels'].extend(hm2.parameters['sample_labels']) # Add the sample boundaries lens = [x + hm.parameters['sample_boundaries'][-1] for x in hm2.parameters['sample_boundaries']][1:] hm.parameters['sample_boundaries'].extend(lens) # Add on additional NA initialized columns ncol = hm.matrix.matrix.shape[1] hm.matrix.matrix = np.hstack((hm.matrix.matrix, np.empty(hm2.matrix.matrix.shape))) hm.matrix.matrix[:, ncol:] = np.NAN # Update the values for idx2, group in enumerate(hm2.parameters["group_labels"]): if group not in d: continue s = hm2.parameters["group_boundaries"][idx2] e = hm2.parameters["group_boundaries"][idx2 + 1] for idx3, reg in enumerate(hm2.matrix.regions[s:e]): if reg[2] not in d[group]: continue hm.matrix.matrix[d[group][reg[2]], ncol:] = hm2.matrix.matrix[s + idx3, :] # Update the sample parameters hm.matrix.sample_labels = hm.parameters['sample_labels'] hm.matrix.sample_boundaries = hm.parameters['sample_boundaries'] def loadBED(line, fp, fname, labelColumn, labels, regions, defaultGroup): """ Given a first line, possibly a label column and a list of labels and regions, add the labels and regions in the file to them """ # This is largely parseBED from deeptoolsintervals labelIdx = None localRegions = {} cols = line.strip().split("\t") if labelColumn is not None: label = cols.pop(labelColumn) if label not in labels: labels[label] = len(labels) labelIdx = labels[label] if labelIdx >= len(regions): regions.append(localRegions) else: localRegions = regions[labelIdx] if len(cols) >= 6: name = cols[3] else: name = "{0}:{1}-{2}".format(cols[0], cols[1], cols[2]) localRegions[name] = len(localRegions) for line in fp: if line.startswith("#") and labelColumn is None: if len(localRegions) > 0: label = line[1:].strip() if len(label): labels[dti.findRandomLabel(labels, label)] = len(labels) else: labels[dti.findRandomLabel(labels, os.path.basename(fname))] = len(labels) regions.append(localRegions) localRegions = dict() continue elif line.startswith("#") and labelColumn is not None: continue cols = line.strip().split("\t") if len(cols) < 3: continue if labelColumn is not None: label = cols.pop(labelColumn) if label not in labels: labels[label] = len(labels) labelIdx = labels[label] if labelIdx >= len(regions): regions.append({}) localRegions = regions[labelIdx] if len(cols) >= 6: name = cols[3] else: name = "{0}:{1}-{2}".format(cols[0], cols[1], cols[2]) name = dti.findRandomLabel(localRegions, name) localRegions[name] = len(localRegions) # Handle the last group if there is no label if labelIdx is None and len(localRegions) > 0: if defaultGroup is not None: labels[dti.findRandomLabel(labels, defaultGroup)] = len(labels) else: labels[dti.findRandomLabel(labels, os.path.basename(fname))] = len(labels) regions.append(localRegions) def loadGTFtranscript(cols, label, defaultGroup, transcript_id_designator): s = next(csv.reader([cols[8]], delimiter=' ')) if "deepTools_group" in s and s[-1] != "deepTools_group": label = s[s.index("deepTools_group") + 1].rstrip(";") elif defaultGroup is not None: label = defaultGroup if transcript_id_designator not in s or s[-1] == transcript_id_designator: sys.stderr.write("Warning: {0} is malformed!\n".format("\t".join(cols))) return None, None name = s[s.index(transcript_id_designator) + 1].rstrip(";") return label, name def loadGTF(line, fp, fname, labels, regions, transcriptID, transcript_id_designator, defaultGroup): """ Like loadBED, but for a GTF file This is largely a copy of what's in deeptoolsintervals """ file_label = dti.findRandomLabel(labels, os.path.basename(fname)) # handle the first line cols = line.split("\t") if cols[2].lower() == transcriptID.lower(): label, name = loadGTFtranscript(cols, file_label, defaultGroup, transcript_id_designator) if label is not None: if label not in labels: labels[label] = len(labels) regions.append(dict()) labelIdx = labels[label] regions[labelIdx][name] = len(regions[labelIdx]) for line in fp: if not isinstance(line, str): line = line.decode('ascii') if not line.startswith('#'): cols = line.strip().split('\t') if len(cols) == 0: continue if cols[2].lower() == transcriptID: label, name = loadGTFtranscript(cols, file_label, defaultGroup, transcript_id_designator) if label is None: continue if label not in labels: labels[label] = len(labels) regions.append(dict()) labelIdx = labels[label] regions[labelIdx][name] = len(regions[labelIdx]) def sortMatrix(hm, regionsFileName, transcriptID, transcript_id_designator): """ Iterate through the files noted by regionsFileName and sort hm accordingly """ labels = dict() regions = [] defaultGroup = None if len(regionsFileName) == 1: defaultGroup = "genes" for fname in regionsFileName: fp = dti.openPossiblyCompressed(fname) line = dti.getNext(fp) labelColumn = None while line.startswith("#"): if not labelColumn: labelColumn = dti.getLabel(line) line = dti.getNext(fp) # Find the label column subtract = 0 if labelColumn is not None: subtract = 1 # Determine the file type and load into a list (or list of lists) cols = line.strip().split("\t") if len(cols) - subtract < 3: raise RuntimeError('{0} does not seem to be a recognized file type!'.format(fname)) elif len(cols) - subtract <= 6: loadBED(line, fp, fname, labelColumn, labels, regions, defaultGroup) elif len(cols) and dti.seemsLikeGTF(cols): loadGTF(line, fp, fname, labels, regions, transcriptID, transcript_id_designator, defaultGroup) else: loadBED(line, fp, fname, labelColumn, labels, regions, defaultGroup) fp.close() # Do some sanity checking on the group labels and region names within them s1 = set(hm.parameters['group_labels']) for e in labels: if e not in s1: sys.exit("The computeMatrix output is missing the '{}' region group. It has [] but the specified regions have {}.\n".format(e, s1, labels.keys())) # Make a dictionary out of current labels and regions d = dict() pos = 0 groupSizes = dict() for idx, label in enumerate(hm.parameters['group_labels']): s = hm.parameters['group_boundaries'][idx] e = hm.parameters['group_boundaries'][idx + 1] if label not in labels: continue d[label] = dict() groupSize = 0 for reg in hm.matrix.regions[s:e]: d[label][reg[2]] = pos pos += 1 groupSize += 1 groupSizes[label] = groupSize # Convert labels to an ordered list labelsList = [""] * len(labels) for k, v in labels.items(): labelsList[v] = k # Reorder order = [] boundaries = [0] for idx, label in enumerate(labelsList): # Make an ordered list out of the region names in this region group _ = [""] * len(regions[idx]) for k, v in regions[idx].items(): _[v] = k for name in _: if name not in d[label]: sys.stderr.write("Skipping {}, due to being absent in the computeMatrix output.\n".format(name)) continue order.append(d[label][name]) boundaries.append(groupSizes[label] + boundaries[-1]) hm.matrix.regions = [hm.matrix.regions[i] for i in order] order = np.array(order) hm.matrix.matrix = hm.matrix.matrix[order, :] # Update the parameters hm.parameters["group_labels"] = labelsList hm.matrix.group_labels = labelsList hm.parameters["group_boundaries"] = boundaries hm.matrix.group_boundaries = boundaries def main(args=None): if len(sys.argv) == 1: args = ["-h"] if len(sys.argv) == 2: args = [sys.argv[1], "-h"] args = parse_arguments().parse_args(args) hm = heatmapper.heatmapper() if not isinstance(args.matrixFile, list): hm.read_matrix_file(args.matrixFile) if args.command == 'info': printInfo(hm) elif args.command == 'subset': sIdx = getSampleBounds(args, hm) gIdx, gBounds = getGroupBounds(args, hm) # groups hm.matrix.regions = subsetRegions(hm, gIdx) # matrix hm.matrix.matrix = hm.matrix.matrix[gIdx, :] hm.matrix.matrix = hm.matrix.matrix[:, sIdx] # boundaries if args.samples is None: args.samples = hm.matrix.sample_labels hm.matrix.sample_boundaries = hm.matrix.sample_boundaries[0:len(args.samples) + 1] hm.matrix.group_boundaries = gBounds.tolist() # labels hm.matrix.sample_labels = args.samples if args.groups is None: args.groups = hm.matrix.group_labels hm.matrix.group_labels = args.groups # save hm.save_matrix(args.outFileName) elif args.command == 'filterStrand': filterHeatmap(hm, args) hm.save_matrix(args.outFileName) elif args.command == 'rbind': rbindMatrices(hm, args) hm.save_matrix(args.outFileName) elif args.command == 'cbind': cbindMatrices(hm, args) hm.save_matrix(args.outFileName) elif args.command == 'sort': sortMatrix(hm, args.regionsFileName, args.transcriptID, args.transcript_id_designator) hm.save_matrix(args.outFileName) else: sys.exit("Unknown command {0}!\n".format(args.command)) deepTools-2.5.0/deeptools/correctGCBias.py0000640000201600010240000006402213006372703017645 0ustar ryanbioinfo#!/usr/bin/env python # -*- coding: utf-8 -*- import os import shutil import time import subprocess import sys import py2bit import pysam import multiprocessing import numpy as np import argparse from scipy.stats import binom from deeptools.utilities import tbitToBamChrName, getGC_content from deeptools import writeBedGraph, parserCommon, mapReduce from deeptools import utilities old_settings = np.seterr(all='ignore') def parse_arguments(args=None): parentParser = parserCommon.getParentArgParse(binSize=True, blackList=False) requiredArgs = getRequiredArgs() parser = argparse.ArgumentParser( parents=[requiredArgs, parentParser], formatter_class=argparse.ArgumentDefaultsHelpFormatter, description='This tool corrects the GC-bias using the' ' method proposed by [Benjamini & Speed (2012). ' 'Nucleic Acids Research, 40(10)]. It will remove reads' ' from regions with too high coverage compared to the' ' expected values (typically GC-rich regions) and will' ' add reads to regions where too few reads are seen ' '(typically AT-rich regions). ' 'The tool ``computeGCBias`` needs to be run first to generate the ' 'frequency table needed here.', usage='An example usage is:\n correctGCBias ' '-b file.bam --effectiveGenomeSize 2150570000 -g mm9.2bit ' '--GCbiasFrequenciesFile freq.txt -o gc_corrected.bam ' '[options]', conflict_handler='resolve', add_help=False) return parser def process_args(args=None): args = parse_arguments().parse_args(args) return args def getRequiredArgs(): parser = argparse.ArgumentParser(add_help=False) required = parser.add_argument_group('Required arguments') # define the arguments required.add_argument('--bamfile', '-b', metavar='BAM file', help='Sorted BAM file to correct.', required=True) required.add_argument('--effectiveGenomeSize', help='The effective genome size is the portion ' 'of the genome that is mappable. Large fractions of ' 'the genome are stretches of NNNN that should be ' 'discarded. Also, if repetitive regions were not ' 'included in the mapping of reads, the effective ' 'genome size needs to be adjusted accordingly. ' 'Common values are: mm9: 2150570000, ' 'hg19:2451960000, dm3:121400000 and ce10:93260000. ' 'See Table 2 of ' 'http://www.plosone.org/article/info:doi/10.1371/journal.pone.0030377 ' 'or http://www.nature.com/nbt/journal/v27/n1/fig_tab/nbt.1518_T1.html ' 'for several effective genome sizes. This value is ' 'needed to detect enriched regions that, if not ' 'discarded, could bias the results.', default=None, type=int, required=True) required.add_argument('--genome', '-g', help='Genome in two bit format. Most genomes can be ' 'found here: http://hgdownload.cse.ucsc.edu/gbdb/ ' 'Search for the .2bit ending. Otherwise, fasta ' 'files can be converted to 2bit using faToTwoBit ' 'available here: ' 'http://hgdownload.cse.ucsc.edu/admin/exe/', metavar='two bit file', required=True) required.add_argument('--GCbiasFrequenciesFile', '-freq', help='Indicate the output file from ' 'computeGCBias containing ' 'the observed and expected read frequencies per GC-' 'content.', type=argparse.FileType('r'), metavar='FILE', required=True) output = parser.add_argument_group('Output options') output.add_argument('--correctedFile', '-o', help='Name of the corrected file. The ending will ' 'be used to decide the output file format. The options ' 'are ".bam", ".bw" for a bigWig file, ".bg" for a ' 'bedGraph file.', metavar='FILE', type=argparse.FileType('w'), required=True) # define the optional arguments optional = parser.add_argument_group('Optional arguments') optional.add_argument("--help", "-h", action="help", help="show this help message and exit") return parser def getReadGCcontent(tbit, read, fragmentLength, chrNameBit): """ The fragments for forward and reverse reads are defined as follows:: |- read.pos |- read.aend ---+=================>-----------------------+--------- Forward strand |-fragStart |-fragEnd ---+-----------------------<=================+--------- Reverse strand |-read.pos |-read.aend |-----------------------------------------| read.tlen """ fragStart = None fragEnd = None if read.is_paired and read.is_proper_pair and abs(read.tlen) < 2 * fragmentLength: if read.is_reverse and read.tlen < 0: fragEnd = read.reference_end fragStart = read.reference_end + read.template_length elif read.template_length >= read.query_alignment_length: fragStart = read.pos fragEnd = read.pos + read.template_length if not fragStart: if read.is_reverse: fragEnd = read.reference_end fragStart = read.reference_end - fragmentLength else: fragStart = read.pos fragEnd = fragStart + fragmentLength fragStart = max(0, fragStart) try: gc = getGC_content(tbit, chrNameBit, fragStart, fragEnd) except Exception: return None if gc is None: return None # match the gc to the given fragmentLength gc = int(np.round(gc * fragmentLength)) return gc def writeCorrected_wrapper(args): return writeCorrected_worker(*args) def writeCorrected_worker(chrNameBam, chrNameBit, start, end, step): r"""writes a bedgraph file containing the GC correction of a region from the genome >>> test = Tester() >>> tempFile = writeCorrected_worker(*test.testWriteCorrectedChunk()) >>> open(tempFile, 'r').readlines() ['chr2L\t200\t225\t31.6\n', 'chr2L\t225\t250\t33.8\n', 'chr2L\t250\t275\t37.9\n', 'chr2L\t275\t300\t40.9\n'] >>> os.remove(tempFile) """ global R_gc fragmentLength = len(R_gc) - 1 cvg_corr = np.zeros(end - start) i = 0 tbit = py2bit.open(global_vars['2bit']) bam = pysam.Samfile(global_vars['bam']) read_repetitions = 0 removed_duplicated_reads = 0 startTime = time.time() # caching seems to be faster # r.flag & 4 == 0 is to skip unmapped # reads that nevertheless are asigned # to a genomic position reads = [r for r in bam.fetch(chrNameBam, start, end) if r.flag & 4 == 0] bam.close() r_index = -1 for read in reads: r_index += 1 try: # calculate GC content of read fragment gc = getReadGCcontent(tbit, read, fragmentLength, chrNameBit) except Exception as detail: print(detail) """ this exception happens when the end of a chromosome is reached """ continue if not gc: continue # is this read in the same orientation and position as the previous? if r_index > 0 and read.pos == reads[r_index - 1].pos and \ read.is_reverse == reads[r_index - 1].is_reverse \ and read.pnext == reads[r_index - 1].pnext: read_repetitions += 1 if read_repetitions >= global_vars['max_dup_gc'][gc]: removed_duplicated_reads += 1 continue else: read_repetitions = 0 try: fragmentStart, fragmentEnd = getFragmentFromRead(read, fragmentLength, extendPairedEnds=True) vectorStart = max(fragmentStart - start, 0) vectorEnd = min(fragmentEnd - start, end - start) except TypeError: # the get_fragment_from_read functions returns None in some cases. # Those cases are to be skipped, hence the continue line. continue cvg_corr[vectorStart:vectorEnd] += float(1) / R_gc[gc] i += 1 if debug: endTime = time.time() print("{}, processing {} ({:.1f} per sec) ") "reads @ {}:{}-{}".format(multiprocessing.current_process().name, i, i / (endTime - startTime), chrNameBit, start, end) if i == 0: return None _file = open(utilities.getTempFileName(suffix='.bg'), 'w') # save in bedgraph format for bin in range(0, len(cvg_corr), step): value = np.mean(cvg_corr[bin:min(bin + step, end)]) if value > 0: writeStart = start + bin writeEnd = min(start + bin + step, end) _file.write("%s\t%d\t%d\t%.1f\n" % (chrNameBit, writeStart, writeEnd, value)) tempFileName = _file.name _file.close() return tempFileName def numCopiesOfRead(value): """ Based int he R_gc value, decides whether to keep, duplicate, triplicate or delete the read. It returns an integer, that tells the number of copies of the read that should be keep. >>> np.random.seed(1) >>> numCopiesOfRead(0.8) 1 >>> numCopiesOfRead(2.5) 2 >>> numCopiesOfRead(None) 1 """ copies = 1 if value: copies = int(value) + (1 if np.random.rand() < value % 1 else 0) return copies def writeCorrectedSam_wrapper(args): return writeCorrectedSam_worker(*args) def writeCorrectedSam_worker(chrNameBam, chrNameBit, start, end, step=None, tag_but_not_change_number=False, verbose=True): r""" Writes a BAM file, deleting and adding some reads in order to compensate for the GC bias. **This is a stochastic method.** >>> np.random.seed(1) >>> test = Tester() >>> args = test.testWriteCorrectedSam() >>> tempFile = writeCorrectedSam_worker(*args, \ ... tag_but_not_change_number=True, verbose=False) >>> try: ... import StringIO ... except ImportError: ... from io import StringIO >>> ostdout = sys.stdout >>> import tempfile >>> sys.stdout = tempfile.TemporaryFile() >>> idx = pysam.index(tempFile) >>> sys.stdout = ostdout >>> bam = pysam.Samfile(tempFile) >>> [dict(r.tags)['YN'] for r in bam.fetch(args[0], 200, 250)] [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1] >>> res = os.remove(tempFile) >>> res = os.remove(tempFile+".bai") >>> tempFile = \ ... writeCorrectedSam_worker(*test.testWriteCorrectedSam_paired(),\ ... tag_but_not_change_number=True, verbose=False) >>> sys.stdout = tempfile.TemporaryFile() >>> idx = pysam.index(tempFile) >>> sys.stdout = ostdout >>> bam = pysam.Samfile(tempFile) >>> [dict(r.tags)['YN'] for r in bam.fetch('chr2L', 0, 50)] [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1] >>> res = os.remove(tempFile) >>> res = os.remove(tempFile+".bai") """ global R_gc fragmentLength = len(R_gc) - 1 if verbose: print("Sam for %s %s %s " % (chrNameBit, start, end)) i = 0 tbit = py2bit.open(global_vars['2bit']) bam = pysam.Samfile(global_vars['bam']) tempFileName = utilities.getTempFileName(suffix='.bam') outfile = pysam.Samfile(tempFileName, 'wb', template=bam) startTime = time.time() matePairs = {} read_repetitions = 0 removed_duplicated_reads = 0 # cache data # r.flag & 4 == 0 is to filter unmapped reads that # have a genomic position reads = [r for r in bam.fetch(chrNameBam, start, end) if r.pos > start and r.flag & 4 == 0] r_index = -1 for read in reads: r_index += 1 copies = None gc = None # check if a mate has already been procesed # to apply the same correction try: copies = matePairs[read.qname]['copies'] gc = matePairs[read.qname]['gc'] del(matePairs[read.qname]) except: # this exception happens when a mate is # not present. This could # happen because of removal of the mate # by some filtering gc = getReadGCcontent(tbit, read, fragmentLength, chrNameBit) if gc: copies = numCopiesOfRead(float(1) / R_gc[gc]) else: copies = 1 # is this read in the same orientation and position as the previous? if gc and r_index > 0 and read.pos == reads[r_index - 1].pos \ and read.is_reverse == reads[r_index - 1].is_reverse \ and read.pnext == reads[r_index - 1].pnext: read_repetitions += 1 if read_repetitions >= global_vars['max_dup_gc'][gc]: copies = 0 # in other words do not take into account this read removed_duplicated_reads += 1 else: read_repetitions = 0 readName = read.qname # Each tag is a tuple of (tag name, value, type) # Note that get_tags() returns ord(type) rather than type and this must # be fixed! # It turns out that the "with_value_type" option only started working in # pysam-0.8.4, so we can't reliably add tags on earlier versions without # potentially creating BAM files that break HTSJDK/IGV/etc. readTag = read.get_tags(with_value_type=True) replace_tags = False if len(readTag) > 0: if len(readTag[0]) == 3: if type(readTag[2]) is int: readTag = [(x[0], x[1], chr(x[2])) for x in readTag] replace_tags = True else: replace_tags = True if gc: GC = int(100 * np.round(float(gc) / fragmentLength, decimals=2)) readTag.append( ('YC', float(round(float(1) / R_gc[gc], 2)), "f")) readTag.append(('YN', copies, "i")) else: GC = -1 readTag.append(('YG', GC, "i")) if replace_tags: read.set_tags(readTag) if read.is_paired and read.is_proper_pair \ and not read.mate_is_unmapped \ and not read.is_reverse: matePairs[readName] = {'copies': copies, 'gc': gc} """ outfile.write(read) """ if tag_but_not_change_number: outfile.write(read) continue for numCop in range(1, copies + 1): # the read has to be renamed such that newly # formed pairs will match if numCop > 1: read.qname = readName + "_%d" % (numCop) outfile.write(read) if verbose: if i % 500000 == 0 and i > 0: endTime = time.time() print("{}, processing {} ({:.1f} per sec) reads " "@ {}:{}-{}".format(multiprocessing.current_process().name, i, i / (endTime - startTime), chrNameBit, start, end)) i += 1 outfile.close() if verbose: endTime = time.time() print("{}, processing {} ({:.1f} per sec) reads " "@ {}:{}-{}".format(multiprocessing.current_process().name, i, i / (endTime - startTime), chrNameBit, start, end)) percentage = float(removed_duplicated_reads) * 100 / len(reads) \ if len(reads) > 0 else 0 print("duplicated reads removed %d of %d (%.2f) " % (removed_duplicated_reads, len(reads), percentage)) return tempFileName def getFragmentFromRead(read, defaultFragmentLength, extendPairedEnds=True): """ The read has to be pysam object. The following values are defined (for forward reads):: |-- -- read.tlen -- --| |-- read.alen --| -----|===============>------------<==============|---- | | | read.pos read.aend read.pnext and for reverse reads |-- -- read.tlen -- --| |-- read.alen --| -----|===============>-----------<===============|---- | | | read.pnext read.pos read.aend this is a sketch of a pair-end reads The function returns the fragment start and end, either using the paired end information (if available) or extending the read in the appropriate direction if this is single-end. Parameters ---------- read : pysam read object Returns ------- tuple (fragment start, fragment end) """ # convert reads to fragments # this option indicates that the paired ends correspond # to the fragment ends # condition read.tlen < maxPairedFragmentLength is added to avoid read pairs # that span thousands of base pairs if extendPairedEnds is True and read.is_paired and 0 < abs(read.tlen) < 1000: if read.is_reverse: fragmentStart = read.pnext fragmentEnd = read.aend else: fragmentStart = read.pos # the end of the fragment is defined as # the start of the forward read plus the insert length fragmentEnd = read.pos + read.tlen else: if defaultFragmentLength <= read.aend - read.pos: fragmentStart = read.pos fragmentEnd = read.aend else: if read.is_reverse: fragmentStart = read.aend - defaultFragmentLength fragmentEnd = read.aend else: fragmentStart = read.pos fragmentEnd = read.pos + defaultFragmentLength return fragmentStart, fragmentEnd def run_shell_command(command): """ Runs the given shell command. Report any errors found. """ try: subprocess.check_call(command, shell=True) except subprocess.CalledProcessError as error: sys.stderr.write('Error{}\n'.format(error)) exit(1) except Exception as error: sys.stderr.write('Error: {}\n'.format(error)) exit(1) def main(args=None): args = process_args(args) global F_gc, N_gc, R_gc data = np.loadtxt(args.GCbiasFrequenciesFile.name) F_gc = data[:, 0] N_gc = data[:, 1] R_gc = data[:, 2] global global_vars global_vars = {} global_vars['2bit'] = args.genome global_vars['bam'] = args.bamfile # compute the probability to find more than one read (a redundant read) # at a certain position based on the gc of the read fragment # the binomial function is used for that max_dup_gc = [binom.isf(1e-7, F_gc[x], 1.0 / N_gc[x]) if F_gc[x] > 0 and N_gc[x] > 0 else 1 for x in range(len(F_gc))] global_vars['max_dup_gc'] = max_dup_gc tbit = py2bit.open(global_vars['2bit']) bam = pysam.Samfile(global_vars['bam']) global_vars['genome_size'] = sum(tbit.chroms().values()) global_vars['total_reads'] = bam.mapped global_vars['reads_per_bp'] = \ float(global_vars['total_reads']) / args.effectiveGenomeSize # apply correction print("applying correction") # divide the genome in fragments containing about 4e5 reads. # This amount of reads takes about 20 seconds # to process per core (48 cores, 256 Gb memory) chunkSize = int(4e5 / global_vars['reads_per_bp']) # chromSizes: list of tuples chromSizes = [(bam.references[i], bam.lengths[i]) for i in range(len(bam.references))] regionStart = 0 if args.region: chromSizes, regionStart, regionEnd, chunkSize = \ mapReduce.getUserRegion(chromSizes, args.region, max_chunk_size=chunkSize) print("genome partition size for multiprocessing: {}".format(chunkSize)) print("using region {}".format(args.region)) mp_args = [] bedGraphStep = args.binSize chrNameBitToBam = tbitToBamChrName(list(tbit.chroms().keys()), bam.references) chrNameBamToBit = dict([(v, k) for k, v in chrNameBitToBam.items()]) print(chrNameBitToBam, chrNameBamToBit) c = 1 for chrom, size in chromSizes: start = 0 if regionStart == 0 else regionStart for i in range(start, size, chunkSize): try: chrNameBamToBit[chrom] except KeyError: print("no sequence information for ") "chromosome {} in 2bit file".format(chrom) print("Reads in this chromosome will be skipped") continue length = min(size, i + chunkSize) mp_args.append((chrom, chrNameBamToBit[chrom], i, length, bedGraphStep)) c += 1 pool = multiprocessing.Pool(args.numberOfProcessors) if args.correctedFile.name.endswith('bam'): if len(mp_args) > 1 and args.numberOfProcessors > 1: print(("using {} processors for {} " "number of tasks".format(args.numberOfProcessors, len(mp_args)))) res = pool.map_async( writeCorrectedSam_wrapper, mp_args).get(9999999) else: res = list(map(writeCorrectedSam_wrapper, mp_args)) if len(res) == 1: command = "cp {} {}".format(res[0], args.correctedFile.name) run_shell_command(command) else: print("concatenating (sorted) intermediate BAMs") header = pysam.Samfile(res[0]) of = pysam.Samfile(args.correctedFile.name, "wb", template=header) header.close() for f in res: f = pysam.Samfile(f) for e in f.fetch(until_eof=True): of.write(e) f.close() of.close() print("indexing BAM") pysam.index(args.correctedFile.name) for tempFileName in res: os.remove(tempFileName) if args.correctedFile.name.endswith('bg') or \ args.correctedFile.name.endswith('bw'): _temp_bg_file_name = utilities.getTempFileName(suffix='_all.bg') if len(mp_args) > 1 and args.numberOfProcessors > 1: res = pool.map_async(writeCorrected_wrapper, mp_args).get(9999999) else: res = list(map(writeCorrected_wrapper, mp_args)) # concatenate intermediary bedgraph files _temp_bg_file = open(_temp_bg_file_name, 'w') for tempFileName in res: if tempFileName: # concatenate all intermediate tempfiles into one # bedgraph file shutil.copyfileobj(open(tempFileName, 'rb'), _temp_bg_file) os.remove(tempFileName) _temp_bg_file.close() args.correctedFile.close() if args.correctedFile.name.endswith('bg'): shutil.move(_temp_bg_file_name, args.correctedFile.name) else: chromSizes = [(k, v) for k, v in tbit.chroms().items()] writeBedGraph.bedGraphToBigWig(chromSizes, _temp_bg_file_name, args.correctedFile.name) os.remove(_temp_bg_file) class Tester(): def __init__(self): import os self.root = os.path.dirname(os.path.abspath(__file__)) + "/test/test_corrGC/" self.tbitFile = self.root + "sequence.2bit" self.bamFile = self.root + "test.bam" self.chrNameBam = '2L' self.chrNameBit = 'chr2L' bam = pysam.Samfile(self.bamFile) tbit = py2bit.open(self.tbitFile) global debug debug = 0 global global_vars global_vars = {'2bit': self.tbitFile, 'bam': self.bamFile, 'filter_out': None, 'extra_sampling_file': None, 'max_reads': 5, 'min_reads': 0, 'min_reads': 0, 'reads_per_bp': 0.3, 'total_reads': bam.mapped, 'genome_size': sum(tbit.chroms().values())} def testWriteCorrectedChunk(self): """ prepare arguments for test """ global R_gc, R_gc_min, R_gc_max R_gc = np.loadtxt(self.root + "R_gc_paired.txt") global_vars['max_dup_gc'] = np.ones(301) start = 200 end = 300 bedGraphStep = 25 return (self.chrNameBam, self.chrNameBit, start, end, bedGraphStep) def testWriteCorrectedSam(self): """ prepare arguments for test """ global R_gc, R_gc_min, R_gc_max R_gc = np.loadtxt(self.root + "R_gc_paired.txt") global_vars['max_dup_gc'] = np.ones(301) start = 200 end = 250 return (self.chrNameBam, self.chrNameBit, start, end) def testWriteCorrectedSam_paired(self): """ prepare arguments for test. """ global R_gc, R_gc_min, R_gc_max R_gc = np.loadtxt(self.root + "R_gc_paired.txt") start = 0 end = 500 global global_vars global_vars['bam'] = self.root + "paired.bam" return 'chr2L', 'chr2L', start, end if __name__ == "__main__": main() deepTools-2.5.0/deeptools/correctReadCounts.py0000640000201600010240000001651412757050135020633 0ustar ryanbioinfo#!/usr/bin/env python # -*- coding: utf-8 -*- import numpy as np from scipy.stats import poisson from deeptools import writeBedGraph from deeptools.SES_scaleFactor import estimateScaleFactor debug = 1 old_settings = np.seterr(all='ignore') def computeLambda(tileCoverage, args): """ This function is called by the writeBedGraph workers for every tile in the genome that is considered """ treatmentWindowTags = tileCoverage[0] controlWindowTags = tileCoverage[1] treatmentExtraSignalTags = treatmentWindowTags - args['treatmentMean'] controlLambda = args['controlMean'] + (treatmentExtraSignalTags * args['controlSignalRatio']) log10pvalue = -1 * poisson.logsf(controlWindowTags, controlLambda) / np.log(10) return log10pvalue def computePvalue(tileCoverage, args): """ This function is called by the writeBedGraph workers for every tile in the genome that is considered It computes a pvalue based on an expected lambda comming from the correction of treatment when the input is considered. """ treatmentWindowTags = tileCoverage[0] controlWindowTags = tileCoverage[1] treatmentLambda = controlWindowTags * args['treatmentControlRatio'] log10pvalue = min(300, -1 * poisson.logsf(treatmentWindowTags, treatmentLambda) / np.log(10)) return log10pvalue def computeCorrectedReadcounts(tileCoverage, args): """ This function is called by the writeBedGraph workers for every tile in the genome that is considered It computes a pvalue based on an expected lambda comming from the correction of treatment when the input is considered. """ treatmentWindowTags = tileCoverage[0] controlWindowTags = tileCoverage[1] treatmentCorrectedTags = treatmentWindowTags - args['treatmentControlRatio'] * (controlWindowTags - args['controlMean']) return treatmentCorrectedTags def correctReadCounts(bamFilesList, binLength, numberOfSamples, defaultFragmentLength, outFileName, outFileFormat, outFileNameCorr=None, region=None, extendPairedEnds=True, numberOfProcessors=1, Nsigmas=2, maxSignalRatio=10, blackListFileName=None, verbose=False): bam1 = writeBedGraph.openBam(bamFilesList[0]) bam2 = writeBedGraph.openBam(bamFilesList[1]) treatmentMapped = bam1.mapped controlMapped = bam2.mapped treatmentControlRatioMapped = float(treatmentMapped) / controlMapped # 1. Get a table containing number of reads in a sample from the genome. # Only regions for which both samples have more than zero counts are considered scaleFactorsDict = estimateScaleFactor(bamFilesList, binLength, numberOfSamples, defaultFragmentLength, 1, blackListFileName=blackListFileName, numberOfProcessors=numberOfProcessors, verbose=verbose) """ num_reads_per_region = getNumReadsPerBin(bamFilesList, binLength, numberOfSamples, defaultFragmentLength, numberOfProcessors, skipZeros=True, verbose=verbose) if verbose: print "number of non-zero regions sampled: {}".format(num_reads_per_region.shape[0]) # 2. get Mean and std of treatment (col1) and control (col2) treatmentMean, controlMean = np.mean(num_reads_per_region, axis=0) # axis=0: that measn by column treatmentStd, controlStd = np.std(num_reads_per_region, axis=0) treatmentTotal, controlTotal = np.sum(num_reads_per_region, axis=0) # 3. Calculate residual in treatment & control data, at regions for which treatment # signal exceeds mean + std * Nsigmas # (these are expected to be the regions at which the signal > mean-signal, # so the residual signal is positive) overRows = np.where(num_reads_per_region[:,0].copy() >= treatmentMean + treatmentStd*Nsigmas )[0] over_Nsigma_regions = num_reads_per_region[overRows, :] treatmentSigMean, controlSigMean = np.mean(over_Nsigma_regions, axis=0) treatmentExtraSignal = treatmentSigMean - treatmentMean controlExtraSignal = controlSigMean - controlMean treatmentControlRatio = float(treatmentTotal) / controlTotal adjSignalRatio = maxSignalRatio * treatmentControlRatio; treatmentSignalRatio = float(treatmentExtraSignal) / controlExtraSignal if treatmentSignalRatio < adjSignalRatio and treatmentSignalRatio > 0: treatmentSignalRatio = adjSignalRatio if treatmentSignalRatio < 1: raise NameError("estimated signal in control file {} is greater than estimated signal in treatmant file {}. Perhaps the file names are swapped?".format(bamFilesList[0], bamFilesList[1])) else: controlSignalRatio = 1.0/treatmentSignalRatio controlRatio = 1.0 / treatmentControlRatio """ # scaleFactors = scaleFactorsDict['size_factors'] treatmentMean, controlMean = scaleFactorsDict['meanSES'] treatmentControlRatio = scaleFactorsDict['size_factors'][1] / scaleFactorsDict['size_factors'][0] treatmentSignalRatio = treatmentControlRatio controlRatio = controlSignalRatio = 1.0 / treatmentControlRatio treatmentTotal = treatmentMapped controlTotal = controlMapped print("Treatment mean: {:.2f}, Treatment total:{:.2f}".format(treatmentMean, treatmentTotal)) print("Control mean: {:.2f}, Control total:{}".format(controlMean, controlTotal)) print("the ratio of treatment vs. control for enriched regions is: {:.2f}".format(treatmentSignalRatio)) print("the ratio of treatment vs. control ratio: {:.2f} (if based on mapped reads: {:.2f})".format(treatmentControlRatio, treatmentControlRatioMapped)) funcArgs = {'controlMean': controlMean, 'treatmentMean': treatmentMean, 'controlSignalRatio': controlSignalRatio, 'controlRatio': controlRatio, 'treatmentControlRatio': treatmentControlRatio } writeBedGraph.writeBedGraph(bamFilesList, outFileName, defaultFragmentLength, computePvalue, funcArgs, tileSize=binLength, region=region, format=outFileFormat, zerosToNans=False, blackListFileName=blackListFileName, numberOfProcessors=numberOfProcessors, extendPairedEnds=extendPairedEnds) if outFileNameCorr: writeBedGraph.writeBedGraph(bamFilesList, outFileNameCorr, defaultFragmentLength, computeCorrectedReadcounts, funcArgs, tileSize=binLength, region=region, format=outFileFormat, zerosToNans=False, blackListFileName=blackListFileName, numberOfProcessors=numberOfProcessors, extendPairedEnds=extendPairedEnds) def controlLambda(tileCoverage, args): controlLambda = args['controlMean'] + (tileCoverage[0] * args['controlSignalRatio']) return controlLambda deepTools-2.5.0/deeptools/correlation.py0000640000201600010240000004376613067414642017536 0ustar ryanbioinfoimport sys import itertools import numpy as np import scipy.cluster.hierarchy as sch import scipy.stats import matplotlib as mpl mpl.use('Agg') mpl.rcParams['pdf.fonttype'] = 42 mpl.rcParams['svg.fonttype'] = 'none' import matplotlib.pyplot as plt import matplotlib.gridspec as gridspec import matplotlib.ticker import matplotlib.mlab import matplotlib.markers old_settings = np.seterr(all='ignore') class Correlation: """ class to work with matrices having sample data to compute correlations, plot them and make scatter plots """ def __init__(self, matrix_file, corr_method=None, labels=None, remove_outliers=False, skip_zeros=False, log1p=False): self.load_matrix(matrix_file) self.skip_zeros = skip_zeros self.corr_method = corr_method self.corr_matrix = None # correlation matrix self.column_order = None self.rowCenter = False if labels is not None: # test that the length of labels # corresponds to the length of # samples self.labels = labels if self.matrix.shape[1] == 1: # There's nothing that can be done with a single sample sys.exit("\nPlease use a matrix with more than one sample\n") if skip_zeros is True: # remove rows containing only nans or zeros # that could be unmappable regions. self.remove_rows_of_zeros() if remove_outliers is True: # remove outliers, otherwise outliers will produce a very # high pearson correlation. Unnecessary for spearman correlation self.remove_outliers() if log1p is True: self.matrix = np.log1p(self.matrix) if corr_method: self.compute_correlation() def load_matrix(self, matrix_file): """ loads a matrix file saved using the numpy savez method. Two keys are expected: 'matrix' and 'labels'. The matrix should contain one sample per row """ _ma = np.load(matrix_file) # matrix: cols correspond to samples self.matrix = np.asarray(_ma['matrix'].tolist()) if np.any(np.isnan(self.matrix)): num_nam = len(np.flatnonzero(np.isnan(self.matrix.flatten()))) sys.stderr.write("*Warning*. {} NaN values were found. They will be removed along with the " "corresponding bins in other samples for the computation " "and plotting\n".format(num_nam)) self.matrix = np.ma.compress_rows(np.ma.masked_invalid(self.matrix)) self.labels = _ma['labels'] assert len(self.labels) == self.matrix.shape[1], "ERROR, length of labels is not equal " \ "to length of matrix samples" @staticmethod def get_outlier_indices(data, max_deviation=200): """ The method is based on the median absolute deviation. See Boris Iglewicz and David Hoaglin (1993), "Volume 16: How to Detect and Handle Outliers", The ASQC Basic References in Quality Control: Statistical Techniques, Edward F. Mykytka, Ph.D., Editor. returns the list, without the outliers The max_deviation=200 is like selecting a z-score larger than 200, just that it is based on the median and the median absolute deviation instead of the mean and the standard deviation. """ median = np.median(data) b_value = 1.4826 # value set for a normal distribution mad = b_value * np.median(np.abs(data)) outliers = [] if mad > 0: deviation = abs(data - median) / mad """ outliers = data[deviation > max_deviation] print "outliers removed {}".format(len(outliers)) print outliers """ outliers = np.flatnonzero(deviation > max_deviation) return outliers def remove_outliers(self, verbose=True): """ get the outliers *per column* using the median absolute deviation method Returns the filtered matrix """ unfiltered = len(self.matrix) to_remove = None for col in self.matrix.T: outliers = self.get_outlier_indices(col) if to_remove is None: to_remove = set(outliers) else: # only set to remove those bins in which # the outliers are present in all cases (colums) # that's why the intersection is used to_remove = to_remove.intersection(outliers) if len(to_remove): to_keep = [x for x in range(self.matrix.shape[0]) if x not in to_remove] self.matrix = self.matrix[to_keep, :] if verbose: sys.stderr.write( "total/filtered/left: " "{}/{}/{}\n".format(unfiltered, unfiltered - len(to_keep), len(to_keep))) return self.matrix def remove_rows_of_zeros(self): # remove rows containing all zeros or all nans _mat = np.nan_to_num(self.matrix) to_keep = _mat.sum(1) != 0 self.matrix = self.matrix[to_keep, :] def save_corr_matrix(self, file_handle): """ saves the correlation matrix """ if self.column_order: self.corr_matrix = self.corr_matrix[:, self.column_order][self.column_order] self.labels = [self.labels[i] for i in self.column_order] file_handle.write("\t'" + "'\t'".join(self.labels) + "'\n") fmt = "\t".join(np.repeat('%.4f', self.corr_matrix.shape[1])) + "\n" i = 0 for row in self.corr_matrix: file_handle.write( "'%s'\t" % self.labels[i] + fmt % tuple(row)) i += 1 def compute_correlation(self): """ computes spearman or pearson correlation for the samples in the matrix The matrix should contain the values of each sample per column that's why the transpose is used. >>> matrix = np.array([[1, 2, 3, np.nan], ... [1, 2, 3, 4], ... [6, 4, 3, 1]]).T >>> np.savez_compressed("/tmp/test_matrix.npz", matrix=matrix, labels=['a', 'b', 'c']) >>> c = Correlation("/tmp/test_matrix.npz", corr_method='pearson') the results should be as in R >>> c.compute_correlation().filled(np.nan) array([[ 1. , 1. , -0.98198051], [ 1. , 1. , -0.98198051], [-0.98198051, -0.98198051, 1. ]]) >>> c.corr_method = 'spearman' >>> c.corr_matrix = None >>> c.compute_correlation() array([[ 1., 1., -1.], [ 1., 1., -1.], [-1., -1., 1.]]) """ if self.corr_matrix is not None: return self.corr_matrix num_samples = len(self.labels) # initialize correlation matrix if self.corr_method == 'pearson': self.corr_matrix = np.ma.corrcoef(self.matrix.T, allow_masked=True) else: corr_matrix = np.zeros((num_samples, num_samples), dtype='float') # do an all vs all correlation using the # indices of the upper triangle rows, cols = np.triu_indices(num_samples) for index in range(len(rows)): row = rows[index] col = cols[index] corr_matrix[row, col] = scipy.stats.spearmanr(self.matrix[:, row], self.matrix[:, col])[0] # make the matrix symmetric self.corr_matrix = corr_matrix + np.triu(corr_matrix, 1).T return self.corr_matrix def plot_correlation(self, plot_fiilename, plot_title='', vmax=None, vmin=None, colormap='jet', image_format=None, plot_numbers=False): """ plots a correlation using a symmetric heatmap """ num_rows = len(self.labels) corr_matrix = self.compute_correlation() # set a font size according to figure length if num_rows < 6: font_size = 14 elif num_rows > 40: font_size = 5 else: font_size = int(14 - 0.25 * num_rows) mpl.rcParams.update({'font.size': font_size}) # set the minimum and maximum values if vmax is None: vmax = 1 if vmin is None: vmin = 0 if corr_matrix .min() >= 0 else -1 # Compute and plot dendrogram. fig = plt.figure(figsize=(11, 9.5)) plt.suptitle(plot_title) axdendro = fig.add_axes([0.02, 0.12, 0.1, 0.66]) axdendro.set_axis_off() y_var = sch.linkage(corr_matrix, method='complete') z_var = sch.dendrogram(y_var, orientation='left', link_color_func=lambda k: 'darkred') axdendro.set_xticks([]) axdendro.set_yticks([]) cmap = plt.get_cmap(colormap) # this line simply makes a new cmap, based on the original # colormap that goes from 0.0 to 0.9 # This is done to avoid colors that # are too dark at the end of the range that do not offer # a good contrast between the correlation numbers that are # plotted on black. if plot_numbers: cmap = cmap.from_list(colormap + "clipped", cmap(np.linspace(0, 0.9, 10))) cmap.set_under((0., 0., 1.)) # Plot distance matrix. axmatrix = fig.add_axes([0.13, 0.1, 0.6, 0.7]) index = z_var['leaves'] corr_matrix = corr_matrix[index, :] corr_matrix = corr_matrix[:, index] if corr_matrix.shape[0] > 30: # when there are too many rows it is better to remove # the black lines surrounding the boxes in the heatmap edge_color = 'none' else: edge_color = 'black' img_mat = axmatrix.pcolormesh(corr_matrix, edgecolors=edge_color, cmap=cmap, vmax=vmax, vmin=vmin) axmatrix.set_xlim(0, num_rows) axmatrix.set_ylim(0, num_rows) axmatrix.yaxis.tick_right() axmatrix.set_yticks(np.arange(corr_matrix .shape[0]) + 0.5) axmatrix.set_yticklabels(np.array(self.labels).astype('str')[index]) axmatrix.xaxis.set_tick_params(labeltop='on') axmatrix.xaxis.set_tick_params(labelbottom='off') axmatrix.set_xticks(np.arange(corr_matrix .shape[0]) + 0.5) axmatrix.set_xticklabels(np.array(self.labels).astype('str')[index], rotation=45, ha='left') axmatrix.tick_params( axis='x', which='both', bottom='off', top='off') axmatrix.tick_params( axis='y', which='both', left='off', right='off') # Plot colorbar axcolor = fig.add_axes([0.13, 0.065, 0.6, 0.02]) cobar = plt.colorbar(img_mat, cax=axcolor, orientation='horizontal') cobar.solids.set_edgecolor("face") if plot_numbers: for row in range(num_rows): for col in range(num_rows): axmatrix.text(row + 0.5, col + 0.5, "{:.2f}".format(corr_matrix[row, col]), ha='center', va='center') self.column_order = index fig.savefig(plot_fiilename, format=image_format) plt.close() def plot_scatter(self, plot_fiilename, plot_title='', image_format=None, log1p=False): """ Plot the scatter plots of a matrix in which each row is a sample """ num_samples = self.matrix.shape[1] corr_matrix = self.compute_correlation() grids = gridspec.GridSpec(num_samples, num_samples) grids.update(wspace=0, hspace=0) fig = plt.figure(figsize=(2 * num_samples, 2 * num_samples)) plt.rcParams['font.size'] = 8.0 plt.suptitle(plot_title) min_value = self.matrix.min() max_value = self.matrix.max() if (min_value % 2 == 0 and max_value % 2 == 0) or \ (min_value % 1 == 0 and max_value % 2 == 1): # make one value odd and the other even max_value += 1 if log1p: major_locator = matplotlib.ticker.FixedLocator(list(range(min_value, max_value, 2))) minor_locator = matplotlib.ticker.FixedLocator(list(range(min_value, max_value, 1))) rows, cols = np.triu_indices(num_samples) for index in range(len(rows)): row = rows[index] col = cols[index] if row == col: # add titles as # empty plot in the diagonal ax = fig.add_subplot(grids[row, col]) ax.text(0.5, 0.5, self.labels[row], verticalalignment='center', horizontalalignment='center', fontsize=10, fontweight='bold', transform=ax.transAxes) ax.set_axis_off() continue ax = fig.add_subplot(grids[row, col]) if log1p: ax.xaxis.set_major_locator(major_locator) ax.xaxis.set_minor_locator(minor_locator) ax.yaxis.set_major_locator(major_locator) ax.yaxis.set_minor_locator(minor_locator) vector1 = self.matrix[:, row] vector2 = self.matrix[:, col] ax.text(0.2, 0.8, "{}={:.2f}".format(self.corr_method, corr_matrix[row, col]), horizontalalignment='left', transform=ax.transAxes) ax.get_yaxis().set_tick_params( which='both', left='off', right='off', direction='out') ax.get_xaxis().set_tick_params( which='both', top='off', bottom='off', direction='out') for tick in ax.xaxis.get_major_ticks(): tick.label.set_rotation('45') if col != num_samples - 1: ax.set_yticklabels([]) else: ax.yaxis.tick_right() ax.get_yaxis().set_tick_params( which='both', left='off', right='on', direction='out') if col - row == 1: ax.xaxis.tick_bottom() ax.get_xaxis().set_tick_params( which='both', top='off', bottom='on', direction='out') for tick in ax.xaxis.get_major_ticks(): tick.label.set_rotation('45') else: ax.set_xticklabels([]) ax.hist2d(vector1, vector2, bins=200, cmin=0.1) # downsample for plotting # choice_idx = np.random.randint(0, len(vector1),min(len(vector1), 500000)) # ax.plot(vector1[choice_idx], vector2[choice_idx], '.', markersize=1, # alpha=0.3, color='darkblue', # markeredgecolor=None) # ax.set_ylim(min_value, max_value) # ax.set_xlim(min_value,max_value) ax.set_ylim(min_value, ax.get_ylim()[1]) ax.set_xlim(min_value, ax.get_xlim()[1]) plt.savefig(plot_fiilename, format=image_format) plt.close() def plot_pca(self, plot_filename, plot_title='', image_format=None, log1p=False): """ Plot the PCA of a matrix """ fig, (ax1, ax2) = plt.subplots(2, 1, figsize=(5, 10)) # PCA if self.rowCenter: _ = self.matrix.mean(axis=1) self.matrix -= _[:, None] mlab_pca = matplotlib.mlab.PCA(self.matrix) n = len(self.labels) markers = itertools.cycle(matplotlib.markers.MarkerStyle.filled_markers) colors = itertools.cycle(plt.cm.gist_rainbow(np.linspace(0, 1, n))) ax1.axhline(y=0, color="black", linestyle="dotted", zorder=1) ax1.axvline(x=0, color="black", linestyle="dotted", zorder=2) for i in range(n): ax1.scatter(mlab_pca.Wt[0, i], mlab_pca.Wt[1, i], marker=next(markers), color=next(colors), s=150, label=self.labels[i], zorder=i + 3) if plot_title == '': ax1.set_title('PCA') else: ax1.set_title(plot_title) ax1.set_xlabel('PC1') ax1.set_ylabel('PC2') lgd = ax1.legend(scatterpoints=1, loc='center left', borderaxespad=0.5, bbox_to_anchor=(1, 0.5), prop={'size': 12}, markerscale=0.9) # Scree plot eigenvalues = mlab_pca.s cumulative = [] c = 0 for x in mlab_pca.fracs: c += x cumulative.append(c) ind = np.arange(n) # the x locations for the groups width = 0.35 # the width of the bars if mpl.__version__ >= "2.0.0": ax2.bar(2 * width + ind, eigenvalues, width * 2) else: ax2.bar(width + ind, eigenvalues, width * 2) ax2.set_ylabel('Eigenvalue') ax2.set_xlabel('Factors') ax2.set_title('Scree plot') ax2.set_xticks(ind + width * 2) ax2.set_xticklabels(ind + 1) ax3 = ax2.twinx() ax3.axhline(y=1, color="black", linestyle="dotted") ax3.plot(width * 2 + ind, cumulative[0:], "r-") ax3.plot(width * 2 + ind, cumulative[0:], "wo") ax3.set_ylim([0, 1.05]) ax3.set_ylabel('Cumulative variability') plt.subplots_adjust(top=3.85) plt.tight_layout() plt.savefig(plot_filename, format=image_format, bbox_extra_artists=(lgd,), bbox_inches='tight') plt.close() deepTools-2.5.0/deeptools/correlation_heatmap.py0000640000201600010240000000706613006372703021220 0ustar ryanbioinfofrom matplotlib import use as mplt_use mplt_use('Agg') import matplotlib.pyplot as plt import numpy as np import scipy.cluster.hierarchy as sch from matplotlib import rcParams rcParams['pdf.fonttype'] = 42 rcParams['svg.fonttype'] = 'none' old_settings = np.seterr(all='ignore') def plot_correlation(corr_matrix, labels, plotFileName, vmax=None, vmin=None, colormap='jet', image_format=None, plot_numbers=False, plot_title=''): num_rows = corr_matrix.shape[0] # set a font size according to figure length if num_rows < 6: font_size = 14 elif num_rows > 40: font_size = 5 else: font_size = int(14 - 0.25 * num_rows) rcParams.update({'font.size': font_size}) # set the minimum and maximum values if vmax is None: vmax = 1 if vmin is None: vmin = 0 if corr_matrix.min() >= 0 else -1 # Compute and plot dendrogram. fig = plt.figure(figsize=(11, 9.5)) if plot_title: plt.suptitle(plot_title) axdendro = fig.add_axes([0.02, 0.12, 0.1, 0.66]) axdendro.set_axis_off() y_var = sch.linkage(corr_matrix, method='complete') z_var = sch.dendrogram(y_var, orientation='right', link_color_func=lambda k: 'darkred') axdendro.set_xticks([]) axdendro.set_yticks([]) cmap = plt.get_cmap(colormap) # this line simply makes a new cmap, based on the original # colormap that goes from 0.0 to 0.9 # This is done to avoid colors that # are too dark at the end of the range that do not offer # a good contrast between the correlation numbers that are # plotted on black. if plot_numbers: cmap = cmap.from_list(colormap + "clipped", cmap(np.linspace(0, 0.9, 10))) cmap.set_under((0., 0., 1.)) # Plot distance matrix. axmatrix = fig.add_axes([0.13, 0.1, 0.6, 0.7]) index = z_var['leaves'] corr_matrix = corr_matrix[index, :] corr_matrix = corr_matrix[:, index] img_mat = axmatrix.pcolormesh(corr_matrix, edgecolors='black', cmap=cmap, vmax=vmax, vmin=vmin) axmatrix.set_xlim(0, num_rows) axmatrix.set_ylim(0, num_rows) axmatrix.yaxis.tick_right() axmatrix.set_yticks(np.arange(corr_matrix.shape[0]) + 0.5) axmatrix.set_yticklabels(np.array(labels).astype('str')[index]) # axmatrix.xaxis.set_label_position('top') axmatrix.xaxis.set_tick_params(labeltop='on') axmatrix.xaxis.set_tick_params(labelbottom='off') axmatrix.set_xticks(np.arange(corr_matrix.shape[0]) + 0.5) axmatrix.set_xticklabels(np.array(labels).astype('str')[index], rotation=45, ha='left') axmatrix.tick_params( axis='x', which='both', bottom='off', top='off') axmatrix.tick_params( axis='y', which='both', left='off', right='off') # axmatrix.set_xticks([]) # Plot colorbar. axcolor = fig.add_axes([0.13, 0.065, 0.6, 0.02]) cobar = plt.colorbar(img_mat, cax=axcolor, orientation='horizontal') cobar.solids.set_edgecolor("face") if plot_numbers: for row in range(num_rows): for col in range(num_rows): axmatrix.text(row + 0.5, col + 0.5, "{:.2f}".format(corr_matrix[row, col]), ha='center', va='center') fig.savefig(plotFileName, format=image_format) fig.close() deepTools-2.5.0/deeptools/countReadsPerBin.py0000640000201600010240000011243513067414642020412 0ustar ryanbioinfoimport shutil import os import time import sys import multiprocessing import numpy as np # deepTools packages import deeptools.utilities from deeptools import bamHandler from deeptools import mapReduce from deeptoolsintervals import GTF import pyBigWig debug = 0 old_settings = np.seterr(all='ignore') def countReadsInRegions_wrapper(args): """ Passes the arguments to countReadsInRegions_worker. This is a step required given the constrains from the multiprocessing module. The args var, contains as first element the 'self' value from the countReadsPerBin object """ return CountReadsPerBin.count_reads_in_region(*args) class CountReadsPerBin(object): r"""Collects coverage over multiple bam files using multiprocessing This function collects read counts (coverage) from several bam files and returns an numpy array with the results. This class uses multiprocessing to compute the coverage. Parameters ---------- bamFilesList : list List containing the names of indexed bam files. E.g. ['file1.bam', 'file2.bam'] binLength : int Length of the window/bin. This value is overruled by ``bedFile`` if present. numberOfSamples : int Total number of samples. The genome is divided into ``numberOfSamples``, each with a window/bin length equal to ``binLength``. This value is overruled by ``stepSize`` in case such value is present and by ``bedFile`` in which case the number of samples and bins are defined in the bed file numberOfProcessors : int Number of processors to use. Default is 4 verbose : bool Output messages. Default: False region : str Region to limit the computation in the form chrom:start:end. bedFile : file_handle File handle of a bed file containing the regions for which to compute the coverage. This option overrules ``binLength``, ``numberOfSamples`` and ``stepSize``. blackListFileName : str A string containing a BED file with blacklist regions. extendReads : bool, int Whether coverage should be computed for the extended read length (i.e. the region covered by the two mates or the regions expected to be covered by single-reads). If the value is 'int', then then this is interpreted as the fragment length to extend reads that are not paired. For Illumina reads, usual values are around 300. This value can be determined using the peak caller MACS2 or can be approximated by the fragment lengths computed when preparing the library for sequencing. If the value is of the variable is true and not value is given, the fragment size is sampled from the library but only if the library is paired-end. Default: False minMappingQuality : int Reads of a mapping quality less than the give value are not considered. Default: None ignoreDuplicates : bool Whether read duplicates (same start, end position. If paired-end, same start-end for mates) are to be excluded. Default: false chrToSkip: list List with names of chromosomes that do not want to be included in the coverage computation. This is useful to remove unwanted chromosomes (e.g. 'random' or 'Het'). stepSize : int the positions for which the coverage is computed are defined as follows: ``range(start, end, stepSize)``. Thus, a stepSize of 1, will compute the coverage at each base pair. If the stepSize is equal to the binLength then the coverage is computed for consecutive bins. If seepSize is smaller than the binLength, then teh bins will overlap. center_read : bool Determines if reads should be centered with respect to the fragment length. samFlag_include : int Extracts only those reads having the SAM flag. For example, to get only reads that are the first mates a samFlag of 64 could be used. Similarly, the samFlag_include can be used to select only reads mapping on the reverse strand or to get only properly paired reads. samFlag_exclude : int Removes reads that match the SAM flag. For example to get all reads that map to the forward strand a samFlag_exlude 16 should be used. Which translates into exclude all reads that map to the reverse strand. zerosToNans : bool If true, zero values encountered are transformed to Nans. Default false. minFragmentLength : int If greater than 0, fragments below this size are excluded. maxFragmentLength : int If greater than 0, fragments above this size are excluded. out_file_for_raw_data : str File name to save the raw counts computed Returns ------- numpy array Each row correspond to each bin/bed region and each column correspond to each of the bamFiles. Examples -------- The test data contains reads for 200 bp. >>> test = Tester() The transpose function is used to get a nicer looking output. The first line corresponds to the number of reads per bin in bam file 1 >>> c = CountReadsPerBin([test.bamFile1, test.bamFile2], 50, 4) >>> np.transpose(c.run()) array([[ 0., 0., 1., 1.], [ 0., 1., 1., 2.]]) """ def __init__(self, bamFilesList, binLength=50, numberOfSamples=None, numberOfProcessors=1, verbose=False, region=None, bedFile=None, extendReads=False, blackListFileName=None, minMappingQuality=None, ignoreDuplicates=False, chrsToSkip=[], stepSize=None, center_read=False, samFlag_include=None, samFlag_exclude=None, zerosToNans=False, smoothLength=0, minFragmentLength=0, maxFragmentLength=0, out_file_for_raw_data=None): self.bamFilesList = bamFilesList self.binLength = binLength self.numberOfSamples = numberOfSamples self.blackListFileName = blackListFileName if extendReads and len(bamFilesList): from deeptools.getFragmentAndReadSize import get_read_and_fragment_length frag_len_dict, read_len_dict = get_read_and_fragment_length(bamFilesList[0], return_lengths=False, blackListFileName=blackListFileName, numberOfProcessors=numberOfProcessors, verbose=verbose) if extendReads is True: # try to guess fragment length if the bam file contains paired end reads if frag_len_dict: self.defaultFragmentLength = int(frag_len_dict['median']) else: exit("*ERROR*: library is not paired-end. Please provide an extension length.") if verbose: print(("Fragment length based on paired en data " "estimated to be {}".format(frag_len_dict['median']))) elif extendReads < read_len_dict['median']: sys.stderr.write("*WARNING*: read extension is smaller than read length (read length = {}). " "Reads will not be extended.\n".format(int(read_len_dict['median']))) self.defaultFragmentLength = 'read length' elif extendReads > 2000: exit("*ERROR*: read extension must be smaller that 2000. Value give: {} ".format(extendReads)) else: self.defaultFragmentLength = int(extendReads) else: self.defaultFragmentLength = 'read length' self.numberOfProcessors = numberOfProcessors self.verbose = verbose self.region = region self.bedFile = bedFile self.minMappingQuality = minMappingQuality self.ignoreDuplicates = ignoreDuplicates self.chrsToSkip = chrsToSkip self.stepSize = stepSize self.center_read = center_read self.samFlag_include = samFlag_include self.samFlag_exclude = samFlag_exclude self.minFragmentLength = minFragmentLength self.maxFragmentLength = maxFragmentLength self.zerosToNans = zerosToNans self.smoothLength = smoothLength if out_file_for_raw_data: self.save_data = True self.out_file_for_raw_data = out_file_for_raw_data else: self.save_data = False self.out_file_for_raw_data = None # check that wither numberOfSamples or stepSize are set if numberOfSamples is None and stepSize is None and bedFile is None: raise ValueError("either stepSize, numberOfSamples or bedFile have to be set") if self.defaultFragmentLength != 'read length': self.maxPairedFragmentLength = 4 * self.defaultFragmentLength else: self.maxPairedFragmentLength = 1000 if self.maxFragmentLength > 0: self.maxPairedFragmentLength = self.maxFragmentLength def run(self, allArgs=None): # Try to determine an optimal fraction of the genome (chunkSize) that is sent to # workers for analysis. If too short, too much time is spend loading the files # if too long, some processors end up free. # the following values are empirical bamFilesHandlers = [] for x in self.bamFilesList: try: y = bamHandler.openBam(x) except: y = pyBigWig.open(x) bamFilesHandlers.append(y) chromSizes, non_common = deeptools.utilities.getCommonChrNames(bamFilesHandlers, verbose=self.verbose) # skip chromosome in the list. This is usually for the # X chromosome which may have either one copy in a male sample # or a mixture of male/female and is unreliable. # Also the skip may contain heterochromatic regions and # mitochondrial DNA if len(self.chrsToSkip): chromSizes = [x for x in chromSizes if x[0] not in self.chrsToSkip] chrNames, chrLengths = list(zip(*chromSizes)) genomeSize = sum(chrLengths) if self.stepSize is None: if self.region is None: self.stepSize = max(int(float(genomeSize) / self.numberOfSamples), 1) else: # compute the step size, based on the number of samples # and the length of the region studied (chrom, start, end) = mapReduce.getUserRegion(chromSizes, self.region)[:3] self.stepSize = max(int(float(end - start) / self.numberOfSamples), 1) # number of samples is better if large if np.mean(chrLengths) < self.stepSize and self.bedFile is None: min_num_of_samples = int(genomeSize / np.mean(chrLengths)) raise ValueError("numberOfSamples has to be bigger than {} ".format(min_num_of_samples)) max_mapped = [] for x in bamFilesHandlers: try: max_mapped.append(x.mapped) except: # bigWig, use a fixed value max_mapped.append(0) max_mapped = max(max_mapped) # If max_mapped is 0 (i.e., bigWig input), set chunkSize to a multiple of binLength and use every bin if max_mapped == 0: chunkSize = 10000 * self.binLength self.stepSize = self.binLength else: reads_per_bp = float(max_mapped) / genomeSize chunkSize = int(self.stepSize * 1e3 / (reads_per_bp * len(bamFilesHandlers))) [bam_h.close() for bam_h in bamFilesHandlers] # Ensure that chunkSize is always at least self.stepSize if chunkSize < self.stepSize: chunkSize = self.stepSize if self.verbose: print("step size is {}".format(self.stepSize)) if self.region: # in case a region is used, append the tilesize self.region += ":{}".format(self.binLength) # Handle GTF options transcriptID, exonID, transcript_id_designator, keepExons = deeptools.utilities.gtfOptions(allArgs) # use map reduce to call countReadsInRegions_wrapper imap_res = mapReduce.mapReduce([], countReadsInRegions_wrapper, chromSizes, self_=self, genomeChunkLength=chunkSize, bedFile=self.bedFile, blackListFileName=self.blackListFileName, region=self.region, numberOfProcessors=self.numberOfProcessors, transcriptID=transcriptID, exonID=exonID, keepExons=keepExons, transcript_id_designator=transcript_id_designator) if self.out_file_for_raw_data: if len(non_common): sys.stderr.write("*Warning*\nThe resulting bed file does not contain information for " "the chromosomes that were not common between the bigwig files\n") # concatenate intermediary bedgraph files ofile = open(self.out_file_for_raw_data, "w") for _values, tempFileName in imap_res: if tempFileName: # concatenate all intermediate tempfiles into one _foo = open(tempFileName, 'r') shutil.copyfileobj(_foo, ofile) _foo.close() os.remove(tempFileName) ofile.close() try: num_reads_per_bin = np.concatenate([x[0] for x in imap_res], axis=0) return num_reads_per_bin except ValueError: if self.bedFile: sys.exit('\nNo coverage values could be computed.\n\n' 'Please check that the chromosome names in the BED file are found on the bam files.\n\n' 'The valid chromosome names are:\n{}'.format(chrNames)) else: sys.exit('\nNo coverage values could be computed.\n\nCheck that all bam files are valid and ' 'contain mapped reads.') def count_reads_in_region(self, chrom, start, end, bed_regions_list=None): """Counts the reads in each bam file at each 'stepSize' position within the interval (start, end) for a window or bin of size binLength. The stepSize controls the distance between bins. For example, a step size of 20 and a bin size of 20 will create bins next to each other. If the step size is smaller than the bin size the bins will overlap. If a list of bedRegions is given, then the number of reads that overlaps with each region is counted. Parameters ---------- chrom : str Chrom name start : int start coordinate end : int end coordinate bed_regions_list: list List of list of tuples of the form (start, end) corresponding to bed regions to be processed. If not bed file was passed to the object constructor then this list is empty. Returns ------- numpy array The result is a numpy array that as rows each bin and as columns each bam file. Examples -------- Initialize some useful values >>> test = Tester() >>> c = CountReadsPerBin([test.bamFile1, test.bamFile2], 25, 0, stepSize=50) The transpose is used to get better looking numbers. The first line corresponds to the number of reads per bin in the first bamfile. >>> _array, __ = c.count_reads_in_region(test.chrom, 0, 200) >>> _array array([[ 0., 0.], [ 0., 1.], [ 1., 1.], [ 1., 2.]]) """ if start > end: raise NameError("start %d bigger that end %d" % (start, end)) if self.stepSize is None: raise ValueError("stepSize is not set!") # array to keep the read counts for the regions subnum_reads_per_bin = [] start_time = time.time() bam_handlers = [] for fname in self.bamFilesList: try: bam_handlers.append(bamHandler.openBam(fname)) except: bam_handlers.append(pyBigWig.open(fname)) blackList = None if self.blackListFileName is not None: blackList = GTF(self.blackListFileName) # A list of lists of tuples transcriptsToConsider = [] if bed_regions_list is not None: transcriptsToConsider = [x[1] for x in bed_regions_list] else: if self.stepSize == self.binLength: transcriptsToConsider.append([(start, end, self.binLength)]) else: for i in range(start, end, self.stepSize): if i + self.binLength > end: break if blackList is not None and blackList.findOverlaps(chrom, i, i + self.binLength): continue transcriptsToConsider.append([(i, i + self.binLength)]) if self.save_data: _file = open(deeptools.utilities.getTempFileName(suffix='.bed'), 'w+t') _file_name = _file.name else: _file_name = '' for bam in bam_handlers: for trans in transcriptsToConsider: tcov = self.get_coverage_of_region(bam, chrom, trans) if bed_regions_list is not None: subnum_reads_per_bin.append(np.sum(tcov)) else: subnum_reads_per_bin.extend(tcov) subnum_reads_per_bin = np.concatenate([subnum_reads_per_bin]).reshape(-1, len(self.bamFilesList), order='F') if self.save_data: idx = 0 for i, trans in enumerate(transcriptsToConsider): if len(trans[0]) != 3: starts = ",".join([str(x[0]) for x in trans]) ends = ",".join([str(x[1]) for x in trans]) _file.write("\t".join([chrom, starts, ends]) + "\t") _file.write("\t".join(["{}".format(x) for x in subnum_reads_per_bin[i, :]]) + "\n") else: for exon in trans: for startPos in range(exon[0], exon[1], exon[2]): if idx >= subnum_reads_per_bin.shape[0]: # At the end of chromosomes (or due to blacklisted regions), there are bins smaller than the bin size # Counts there are added to the bin before them, but range() will still try to include them. break _file.write("{0}\t{1}\t{2}\t".format(chrom, startPos, startPos + exon[2])) _file.write("\t".join(["{}".format(x) for x in subnum_reads_per_bin[idx, :]]) + "\n") idx += 1 _file.close() if self.verbose: endTime = time.time() rows = subnum_reads_per_bin.shape[0] print("%s countReadsInRegions_worker: processing %d " "(%.1f per sec) @ %s:%s-%s" % (multiprocessing.current_process().name, rows, rows / (endTime - start_time), chrom, start, end)) return subnum_reads_per_bin, _file_name def get_coverage_of_region(self, bamHandle, chrom, regions, fragmentFromRead_func=None): """ Returns a numpy array that corresponds to the number of reads that overlap with each tile. >>> test = Tester() >>> import pysam >>> c = CountReadsPerBin([], stepSize=1, extendReads=300) For this case the reads are length 36. The number of overlapping read fragments is 4 and 5 for the positions tested. >>> c.get_coverage_of_region(pysam.AlignmentFile(test.bamFile_PE), 'chr2', ... [(5000833, 5000834), (5000834, 5000835)]) array([ 4., 5.]) In the following example a paired read is extended to the fragment length which is 100 The first mate starts at 5000000 and the second at 5000064. Each mate is extended to the fragment length *independently* At position 500090-500100 one fragment of length 100 overlap, and after position 5000101 there should be zero reads. >>> c.zerosToNans = True >>> c.get_coverage_of_region(pysam.AlignmentFile(test.bamFile_PE), 'chr2', ... [(5000090, 5000100), (5000100, 5000110)]) array([ 1., nan]) In the following case the reads length is 50. Reads are not extended. >>> c.extendReads=False >>> c.get_coverage_of_region(pysam.AlignmentFile(test.bamFile2), '3R', [(148, 150), (150, 152), (152, 154)]) array([ 1., 2., 2.]) """ if not fragmentFromRead_func: fragmentFromRead_func = self.get_fragment_from_read nbins = len(regions) if len(regions[0]) == 3: nbins = 0 for reg in regions: nbins += (reg[1] - reg[0]) // reg[2] coverages = np.zeros(nbins, dtype='float64') if self.defaultFragmentLength == 'read length': extension = 0 else: extension = self.maxPairedFragmentLength blackList = None if self.blackListFileName is not None: blackList = GTF(self.blackListFileName) vector_start = 0 for idx, reg in enumerate(regions): if len(reg) == 3: tileSize = int(reg[2]) nRegBins = (reg[1] - reg[0]) // tileSize else: nRegBins = 1 tileSize = int(reg[1] - reg[0]) # Blacklisted regions have a coverage of 0 if blackList and blackList.findOverlaps(chrom, reg[0], reg[1]): continue regStart = int(max(0, reg[0] - extension)) regEnd = reg[1] + int(extension) # If alignments are extended and there's a blacklist, ensure that no # reads originating in a blacklist are fetched if blackList and reg[0] > 0 and extension > 0: o = blackList.findOverlaps(chrom, regStart, reg[0]) if o is not None and len(o) > 0: regStart = o[-1][1] o = blackList.findOverlaps(chrom, reg[1], regEnd) if o is not None and len(o) > 0: regEnd = o[0][0] start_time = time.time() # caching seems faster. TODO: profile the function c = 0 if chrom in bamHandle.references: reads = [r for r in bamHandle.fetch(chrom, regStart, regEnd) if r.flag & 4 == 0] else: raise NameError("chromosome {} not found in bam file".format(chrom)) prev_start_pos = None # to store the start positions # of previous processed read pair for read in reads: if self.minMappingQuality and read.mapq < self.minMappingQuality: continue # filter reads based on SAM flag if self.samFlag_include and read.flag & self.samFlag_include != self.samFlag_include: continue if self.samFlag_exclude and read.flag & self.samFlag_exclude != 0: continue # Fragment lengths tLen = deeptools.utilities.getTLen(read) if self.minFragmentLength > 0 and tLen < self.minFragmentLength: continue if self.maxFragmentLength > 0 and tLen > self.maxFragmentLength: continue # get rid of duplicate reads that have same position on each of the # pairs if self.ignoreDuplicates and prev_start_pos \ and prev_start_pos == (read.reference_start, read.pnext, read.is_reverse): continue # since reads can be split (e.g. RNA-seq reads) each part of the # read that maps is called a position block. try: position_blocks = fragmentFromRead_func(read) except TypeError: # the get_fragment_from_read functions returns None in some cases. # Those cases are to be skipped, hence the continue line. continue last_eIdx = None for fragmentStart, fragmentEnd in position_blocks: if fragmentEnd is None or fragmentStart is None: continue fragmentLength = fragmentEnd - fragmentStart if fragmentLength == 0: continue # skip reads that are not in the region being # evaluated. if fragmentEnd <= reg[0] or fragmentStart >= reg[1]: continue if fragmentStart < reg[0]: fragmentStart = reg[0] if fragmentEnd > reg[0] + len(coverages) * tileSize: fragmentEnd = reg[0] + len(coverages) * tileSize sIdx = vector_start + max((fragmentStart - reg[0]) // tileSize, 0) eIdx = vector_start + min(np.ceil(float(fragmentEnd - reg[0]) / tileSize).astype('int'), nRegBins) if last_eIdx is not None: sIdx = max(last_eIdx, sIdx) if sIdx >= eIdx: continue coverages[sIdx:eIdx] += 1 last_eIdx = eIdx prev_start_pos = (read.reference_start, read.pnext, read.is_reverse) c += 1 if self.verbose: endTime = time.time() print("%s, processing %s (%.1f per sec) reads @ %s:%s-%s" % ( multiprocessing.current_process().name, c, c / (endTime - start_time), chrom, reg[0], reg[1])) vector_start += nRegBins # change zeros to NAN if self.zerosToNans: coverages[coverages == 0] = np.nan return coverages def getReadLength(self, read): return len(read) @staticmethod def is_proper_pair(read, maxPairedFragmentLength): """ Checks if a read is proper pair meaning that both mates are facing each other and are in the same chromosome and are not to far away. The sam flag for proper pair can not always be trusted. Note that if the fragment size is > maxPairedFragmentLength (~2kb usually) that False will be returned. :return: bool >>> import pysam >>> import os >>> from deeptools.countReadsPerBin import CountReadsPerBin as cr >>> root = os.path.dirname(os.path.abspath(__file__)) + "/test/test_data/" >>> bam = pysam.AlignmentFile("{}/test_proper_pair_filtering.bam".format(root)) >>> iter = bam.fetch() >>> read = next(iter) >>> cr.is_proper_pair(read, 1000) # "keep" read True >>> cr.is_proper_pair(read, 200) # "keep" read, but maxPairedFragmentLength is too short False >>> read = next(iter) >>> cr.is_proper_pair(read, 1000) # "improper pair" False >>> read = next(iter) >>> cr.is_proper_pair(read, 1000) # "mismatch chr" False >>> read = next(iter) >>> cr.is_proper_pair(read, 1000) # "same orientation1" False >>> read = next(iter) >>> cr.is_proper_pair(read, 1000) # "same orientation2" False >>> read = next(iter) >>> cr.is_proper_pair(read, 1000) # "rev first" False >>> read = next(iter) >>> cr.is_proper_pair(read, 1000) # "rev first OK" True >>> read = next(iter) >>> cr.is_proper_pair(read, 1000) # "for first" False >>> read = next(iter) >>> cr.is_proper_pair(read, 1000) # "for first" True """ if not read.is_proper_pair: return False if read.reference_id != read.next_reference_id: return False if abs(read.template_length) > maxPairedFragmentLength: return False # check that the mates face each other (inward) if read.is_reverse is read.mate_is_reverse: return False if read.is_reverse: if read.reference_start >= read.next_reference_start: return True else: if read.reference_start <= read.next_reference_start: return True return False def get_fragment_from_read(self, read): """Get read start and end position of a read. If given, the reads are extended as follows: If reads are paired end, each read mate is extended to match the fragment length, otherwise, a default fragment length is used. If reads are split (give by the CIGAR string) then the multiple positions of the read are returned. When reads are extended the cigar information is skipped. Parameters ---------- read: pysam object. The following values are defined (for forward reads):: |-- -- read.tlen -- --| |-- read.alen --| -----|===============>------------<==============|---- | | | read.reference_start read.reference_end read.pnext and for reverse reads |-- -- read.tlen -- --| |-- read.alen --| -----|===============>-----------<===============|---- | | | read.pnext read.reference_start read.reference_end this is a sketch of a pair-end reads The function returns the fragment start and end, either using the paired end information (if available) or extending the read in the appropriate direction if this is single-end. Parameters ---------- read : pysam read object Returns ------- list of tuples [(fragment start, fragment end)] >>> test = Tester() >>> c = CountReadsPerBin([], 1, 1, 200, extendReads=True) >>> c.defaultFragmentLength=100 >>> c.get_fragment_from_read(test.getRead("paired-forward")) [(5000000, 5000100)] >>> c.get_fragment_from_read(test.getRead("paired-reverse")) [(5000000, 5000100)] >>> c.defaultFragmentLength = 200 >>> c.get_fragment_from_read(test.getRead("single-forward")) [(5001491, 5001691)] >>> c.get_fragment_from_read(test.getRead("single-reverse")) [(5001536, 5001736)] >>> c.defaultFragmentLength = 'read length' >>> c.get_fragment_from_read(test.getRead("single-forward")) [(5001491, 5001527)] >>> c.defaultFragmentLength = 'read length' >>> c.extendReads = False >>> c.get_fragment_from_read(test.getRead("paired-forward")) [(5000000, 5000036)] Tests for read centering. >>> c = CountReadsPerBin([], 1, 1, 200, extendReads=True, center_read=True) >>> c.defaultFragmentLength = 100 >>> assert(c.get_fragment_from_read(test.getRead("paired-forward")) == [(5000032, 5000068)]) >>> c.defaultFragmentLength = 200 >>> assert(c.get_fragment_from_read(test.getRead("single-reverse")) == [(5001618, 5001654)]) """ # if no extension is needed, use pysam get_blocks # to identify start and end reference positions. # get_blocks return a list of start and end positions # based on the CIGAR if skipped regions are found. # E.g for a cigar of 40M260N22M # get blocks return two elements for the first 40 matches # and the for the last 22 matches. if self.defaultFragmentLength == 'read length': return read.get_blocks() else: if self.is_proper_pair(read, self.maxPairedFragmentLength): if read.is_reverse: fragmentStart = read.next_reference_start fragmentEnd = read.reference_end else: fragmentStart = read.reference_start # the end of the fragment is defined as # the start of the forward read plus the insert length fragmentEnd = read.reference_start + abs(read.template_length) # Extend using the default fragment length else: if read.is_reverse: fragmentStart = read.reference_end - self.defaultFragmentLength fragmentEnd = read.reference_end else: fragmentStart = read.reference_start fragmentEnd = read.reference_start + self.defaultFragmentLength if self.center_read: fragmentCenter = fragmentEnd - (fragmentEnd - fragmentStart) / 2 fragmentStart = int(fragmentCenter - read.infer_query_length(always=False) / 2) fragmentEnd = fragmentStart + read.infer_query_length(always=False) assert fragmentStart < fragmentEnd, "fragment start greater than fragment" \ "end for read {}".format(read.query_name) return [(fragmentStart, fragmentEnd)] def getSmoothRange(self, tileIndex, tileSize, smoothRange, maxPosition): """ Given a tile index position and a tile size (length), return the a new indices over a larger range, called the smoothRange. This region is centered in the tileIndex an spans on both sizes to cover the smoothRange. The smoothRange is trimmed in case it is less than zero or greater than maxPosition :: ---------------|==================|------------------ tileStart |--------------------------------------| | <-- smoothRange --> | | tileStart - (smoothRange-tileSize)/2 Test for a smooth range that spans 3 tiles. Examples -------- >>> c = CountReadsPerBin([], 1, 1, 1, 0) >>> c.getSmoothRange(5, 1, 3, 10) (4, 7) Test smooth range truncated on start. >>> c.getSmoothRange(0, 10, 30, 200) (0, 2) Test smooth range truncated on start. >>> c.getSmoothRange(1, 10, 30, 4) (0, 3) Test smooth range truncated on end. >>> c.getSmoothRange(5, 1, 3, 5) (4, 5) Test smooth range not multiple of tileSize. >>> c.getSmoothRange(5, 10, 24, 10) (4, 6) """ smoothTiles = int(smoothRange / tileSize) if smoothTiles == 1: return (tileIndex, tileIndex + 1) smoothTilesSide = float(smoothTiles - 1) / 2 smoothTilesLeft = int(np.ceil(smoothTilesSide)) smoothTilesRight = int(np.floor(smoothTilesSide)) + 1 indexStart = max(tileIndex - smoothTilesLeft, 0) indexEnd = min(maxPosition, tileIndex + smoothTilesRight) return (indexStart, indexEnd) def remove_row_of_zeros(matrix): # remove rows containing all zeros or all nans _mat = np.nan_to_num(matrix) to_keep = _mat.sum(1) != 0 return matrix[to_keep, :] class Tester(object): def __init__(self): """ The distribution of reads between the two bam files is as follows. They cover 200 bp 0 100 200 |------------------------------------------------------------| A =============== =============== B =============== =============== =============== =============== """ self.root = os.path.dirname(os.path.abspath(__file__)) + "/test/test_data/" # self.root = "./test/test_data/" self.bamFile1 = self.root + "testA.bam" self.bamFile2 = self.root + "testB.bam" self.bamFile_PE = self.root + "test_paired2.bam" self.chrom = '3R' global debug debug = 0 def getRead(self, readType): """ prepare arguments for test """ bam = bamHandler.openBam(self.bamFile_PE) if readType == 'paired-reverse': read = [x for x in bam.fetch('chr2', 5000081, 5000082)][0] elif readType == 'single-forward': read = [x for x in bam.fetch('chr2', 5001491, 5001492)][0] elif readType == 'single-reverse': read = [x for x in bam.fetch('chr2', 5001700, 5001701)][0] else: # by default a forward paired read is returned read = [x for x in bam.fetch('chr2', 5000027, 5000028)][0] return read deepTools-2.5.0/deeptools/deepBlue.py0000640000201600010240000002517113021233660016715 0ustar ryanbioinfo#!/usr/bin/env python try: # python 2 import xmlrpclib except: # python 3 import xmlrpc.client as xmlrpclib import time import tempfile import os.path import sys import pyBigWig from deeptools.utilities import mungeChromosome from deeptoolsintervals import GTF import datetime def isDeepBlue(fname): """ Returns true if the file ends in .wig, .wiggle, or .bedgraph, since these indicate a file on the deepBlue server """ if fname.endswith(".wig"): return True if fname.endswith(".wiggle"): return True if fname.endswith(".bedgraph"): return True if fname.startswith("http") or fname.startswith("ftp"): return False # For ENCODE samples, the "Name" is just the ENCODE sample ID, so as a fallback check for files that aren't there. if not os.path.exists(fname): return True return False def mergeRegions(regions): """ Given a list of [(chrom, start, end), ...], merge all overlapping regions This returns a dict, where values are sorted lists of [start, end]. """ bar = sorted(regions) out = dict() last = [None, None, None] for reg in bar: if reg[0] == last[0] and reg[1] <= last[2]: if reg[2] > last[2]: last[2] = reg[2] continue else: if last[0]: if last[0] not in out: out[last[0]] = list() out[last[0]].append([last[1], last[2]]) last = [reg[0], reg[1], reg[2]] if last[0] not in out: out[last[0]] = list() out[last[0]].append([last[1], last[2]]) return out def makeTiles(db, args): """ Given a deepBlue object, return a list of regions that will be queried """ out = [] for (k, v) in db.chromsTuple: start = 0 while start <= v: end = start + args.binSize if end > v: end = v out.append([k, start, end]) start += end + args.distanceBetweenBins return out def makeChromTiles(db): """ Make a region for each chromosome """ out = [] for (k, v) in db.chromsTuple: out.append([k, 0, v]) return out def makeRegions(BED, args): """ Given a list of BED/GTF files, make a list of regions. These are vaguely extended as appropriate. For simplicity, the maximum of --beforeRegionStartLength and --afterRegionStartLength are tacked on to each end and transcripts are used for GTF files. """ itree = GTF(BED, transcriptID=args.transcriptID, transcript_id_designator=args.transcript_id_designator) o = [] extend = 0 # The before/after stuff is specific to computeMatrix if "beforeRegionsStartLength" in args: extend = max(args.beforeRegionsStartLength, args.afterRegionsStartLength) for chrom in itree.chroms: regs = itree.findOverlaps(chrom, 0, 4294967295) # bigWig files use 32 bit coordinates for reg in regs: o.append([chrom, max(0, reg[0] - extend), reg[1] + extend]) del itree return o def preloadWrapper(foo): """ This is a wrapper around the preload function for multiprocessing """ args = foo[2] regs = foo[3] res = deepBlue(foo[0], url=args.deepBlueURL, userKey=args.userKey) return res.preload(regs, tmpDir=args.deepBlueTempDir) class deepBlue(object): def __init__(self, sample, url="http://deepblue.mpi-inf.mpg.de/xmlrpc", userKey="anonymous_key"): """ Connect to the requested deepblue server with the given user key and request the specifed sample from it. >>> sample = "S002R5H1.ERX300721.H3K4me3.bwa.GRCh38.20150528.bedgraph" >>> db = deepBlue(sample) >>> assert(db.chroms("chr1") == 248956422) """ self.sample = sample self.url = url self.userKey = userKey self.server = xmlrpclib.Server(url, allow_none=True) self.info = None self.experimentID = None self.genome = None self.chromsDict = None self.chromsTuple = None # Set self.experimentID experimentID = self.getEID() if not experimentID: raise RuntimeError("The requested sample({}) has no associated experiment! If you did not intend to use samples on deepBlue, then it appears either you misspelled a file name or one of your BAM files is lacking a valid index.".format(sample)) # Set self.info (status, resp) = self.server.info(self.experimentID, userKey) if status != "okay": raise RuntimeError("Received the following error while fetching information about '{}': {}".format(resp, sample)) self.info = resp[0] # Set self.genome genome = self.getGenome() if not genome: raise RuntimeError("Unable to determine an appropriate genome for '{}'".format(sample)) # Set self.chroms chroms = self.getChroms() if not chroms: raise RuntimeError("Unable to determine chromosome names/sizes for '{}'".format(sample)) def getEID(self): """ Given a sample name, return its associated experiment ID (or None on error). self.experimentID is then the internal ID (e.g., e52525) """ (status, resps) = self.server.search(self.sample, "experiments", self.userKey) if status != "okay": raise RuntimeError("Received an error ({}) while searching for the experiment associated with '{}'".format(resps, self.sample)) for resp in resps: if resp[1] == self.sample: self.experimentID = resp[0] return resp[0] return None def getGenome(self): """ Determines and sets the genome assigned to a given sample. On error, this raises a runtime exception. self.genome is then the internal genome ID. """ if "genome" in self.info.keys(): self.genome = self.info["genome"] return self.genome def getChroms(self): """ Determines and sets the chromosome names/sizes for a given sample. On error, this raises a runtime exception. self.chroms is then a dictionary of chromosome:length pairs """ (status, resp) = self.server.chromosomes(self.genome, self.userKey) if status != "okay": raise RuntimeError("Received an error while fetching chromosome information for '{}': {}".format(self.sample, resp)) self.chromsDict = {k: v for k, v in resp} self.chromsTuple = [(k, v) for k, v in resp] return resp def chroms(self, chrom=None): """ Like the chroms() function in pyBigWig, returns either chromsDict (chrom is None) or the length of a given chromosome """ if chrom is None: return self.chromsDict elif chrom in self.chromsDict: return self.chromsDict[chrom] return None def close(self): pass def preload(self, regions, tmpDir=None): """ Given a sample and a set of regions, write a bigWig file containing the underlying signal. This function returns the file name, which needs to be deleted by the calling function at some point. This sends queries one chromosome at a time, due to memory limits on deepBlue """ startTime = datetime.datetime.now() regions2 = mergeRegions(regions) # Make a temporary file f = tempfile.NamedTemporaryFile(delete=False, dir=tmpDir) fname = f.name f.close() # Start with the bigWig file bw = pyBigWig.open(fname, "w") bw.addHeader(self.chromsTuple, maxZooms=0) # This won't work in IGV! # Make a string out of everything in a resonable order for k, v in self.chromsTuple: # Munge chromosome names as appropriate chrom = mungeChromosome(k, regions2.keys()) if not chrom: continue if chrom not in regions2 or len(regions2) == 0: continue regionsStr = "\n".join(["{}\t{}\t{}".format(k, reg[0], reg[1]) for reg in regions2[chrom]]) regionsStr += "\n" # Send the regions (status, regionsID) = self.server.input_regions(self.genome, regionsStr, self.userKey) if status != "okay": raise RuntimeError("Received the following error while sending regions for '{}': {}".format(regionsID, self.sample)) # Get the experiment information (status, queryID) = self.server.select_experiments(self.sample, k, None, None, self.userKey) if status != "okay": raise RuntimeError("Received the following error while running select_experiments on file '{}': {}".format(self.sample, queryID)) if not queryID: raise RuntimeError("Somehow, we received None as a query ID (file '{}')".format(self.sample)) # Intersect (status, intersectID) = self.server.intersection(queryID, regionsID, self.userKey) if status != "okay": raise RuntimeError("Received the following error while running intersection on file '{}': {}".format(self.sample, intersectID)) if not intersectID: raise RuntimeError("Somehow, we received None as an intersect ID (file '{}')".format(self.sample)) # Query the regions (status, reqID) = self.server.get_regions(intersectID, "START,END,VALUE", self.userKey) if status != "okay": raise RuntimeError("Received the following error while fetching regions in file '{}': {}".format(self.sample, reqID)) # Wait for the server to process the data (status, info) = self.server.info(reqID, self.userKey) request_status = info[0]["state"] while request_status != "done" and request_status != "failed": time.sleep(0.1) (status, info) = self.server.info(reqID, self.userKey) request_status = info[0]["state"] # Get the actual data (status, resp) = self.server.get_request_data(reqID, self.userKey) if status != "okay": raise RuntimeError("Received the following error while fetching data in file '{}': {}".format(self.sample, resp)) for intervals in resp.split("\n"): interval = intervals.split("\t") if interval[0] == '': continue bw.addEntries([k], [int(interval[0])], ends=[int(interval[1])], values=[float(interval[2])]) bw.close() sys.stderr.write("{} done (took {})\n".format(self.sample, datetime.datetime.now() - startTime)) sys.stderr.flush() return fname deepTools-2.5.0/deeptools/deeptools_list_tools.py0000640000201600010240000000566013067414642021455 0ustar ryanbioinfo#!/usr/bin/env python # -*- coding: utf-8 -*- import argparse import sys from deeptools._version import __version__ def parse_arguments(args=None): parser = argparse.ArgumentParser( formatter_class=argparse.RawDescriptionHelpFormatter, description=""" deepTools is a suite of python tools particularly developed for the efficient analysis of high-throughput sequencing data, such as ChIP-seq, RNA-seq or MNase-seq. Each tool should be called by its own name as in the following example: $ bamCoverage -b reads.bam -o coverage.bw If you find deepTools useful for your research please cite as: Ramírez, Fidel, Devon P. Ryan, Björn Grüning, Vivek Bhardwaj, Fabian Kilpert, Andreas S. Richter, Steffen Heyne, Friederike Dündar, and Thomas Manke. 2016. "deepTools2: A next Generation Web Server for Deep-Sequencing Data Analysis." Nucleic Acids Research, April. doi:10.1093/nar/gkw257. [ Tools for BAM and bigWig file processing ] multiBamSummary compute read coverages over bam files. Output used for plotCorrelation or plotPCA multiBigwigSummary extract scores from bigwig files. Output used for plotCorrelation or plotPCA correctGCBias corrects GC bias from bam file. Don't use it with ChIP data bamCoverage computes read coverage per bins or regions bamCompare computes log2 ratio and other operations of read coverage of two samples per bins or regions bigwigCompare computes log2 ratio and other operations from bigwig scores of two samples per bins or regions computeMatrix prepares the data from bigwig scores for plotting with plotHeatmap or plotProfile [ Tools for QC ] plotCorrelation plots heatmaps or scatterplots of data correlation plotPCA plots PCA plotFingerprint plots the distribution of enriched regions bamPEFragmentSize returns the read length and paired-end distance from a bam file computeGCBias computes and plots the GC bias of a sample plotCoverage plots a histogram of read coverage [Heatmaps and summary plots] plotHeatmap plots one or multiple heatmaps of user selected regions over different genomic scores plotProfile plots the average profile of user selected regions over different genomic scores plotEnrichment plots the read/fragment coverage of one or more sets of regions [Miscellaneous] computeMatrixOperations Modifies the output of computeMatrix in a variety of ways. For more information visit: http://deeptools.readthedocs.org """) parser.add_argument('--version', action='version', version='%(prog)s {}'.format(__version__)) return parser def process_args(args=None): args = parse_arguments().parse_args(args) return args def main(args=None): if args is None and len(sys.argv) == 1: args = ["--help"] process_args(args) deepTools-2.5.0/deeptools/getFragmentAndReadSize.py0000640000201600010240000001116112757050135021510 0ustar ryanbioinfoimport numpy as np # own tools from deeptools import bamHandler from deeptools import mapReduce old_settings = np.seterr(all='ignore') def getFragmentLength_wrapper(args): return getFragmentLength_worker(*args) def getFragmentLength_worker(chrom, start, end, bamFile, distanceBetweenBins): """ Queries the reads at the given region for the distance between reads and the read length Parameters ---------- chrom : str chromosome name start : int region start end : int region end bamFile : str BAM file name distanceBetweenBins : int the number of bases at the end of each bin to ignore Returns ------- np.array an np.array, where first column is fragment length, the second is for read length """ bam = bamHandler.openBam(bamFile) end = max(start + 1, end - distanceBetweenBins) if chrom in bam.references: reads = np.array([(abs(r.template_length), r.infer_query_length(always=False)) for r in bam.fetch(chrom, start, end) if r.is_proper_pair and r.is_read1]) if not len(reads): # if the previous operation produces an empty list # it could be that the data is not paired, then # we try with out filtering reads = np.array([(abs(r.template_length), r.infer_query_length(always=False)) for r in bam.fetch(chrom, start, end)]) else: raise NameError("chromosome {} not found in bam file".format(chrom)) if not len(reads): reads = np.array([]).reshape(0, 2) return reads def get_read_and_fragment_length(bamFile, return_lengths=False, blackListFileName=None, binSize=50000, distanceBetweenBins=1000000, numberOfProcessors=None, verbose=False): """ Estimates the fragment length and read length through sampling Parameters ---------- bamFile : str BAM file name return_lengths : bool numberOfProcessors : int verbose : bool binSize : int distanceBetweenBins : int Returns ------- d : dict tuple of two dictionaries, one for the fragment length and the other for the read length. The dictionaries summarise the mean, median etc. values """ bam_handle = bamHandler.openBam(bamFile) chrom_sizes = list(zip(bam_handle.references, bam_handle.lengths)) distanceBetweenBins *= 2 fl = [] while len(fl) < 1000 and distanceBetweenBins > 1: distanceBetweenBins /= 2 stepsize = binSize + distanceBetweenBins imap_res = mapReduce.mapReduce((bam_handle.filename, distanceBetweenBins), getFragmentLength_wrapper, chrom_sizes, genomeChunkLength=stepsize, blackListFileName=blackListFileName, numberOfProcessors=numberOfProcessors, verbose=verbose) fl = np.concatenate(imap_res) if len(fl): fragment_length = fl[:, 0] read_length = fl[:, 1] if fragment_length.mean() > 0: fragment_len_dict = {'sample_size': len(fragment_length), 'min': fragment_length.min(), 'qtile25': np.percentile(fragment_length, 25), 'mean': np.mean(fragment_length), 'median': np.median(fragment_length), 'qtile75': np.percentile(fragment_length, 75), 'max': fragment_length.max(), 'std': np.std(fragment_length)} else: fragment_len_dict = None if return_lengths and fragment_len_dict is not None: fragment_len_dict['lengths'] = fragment_length read_len_dict = {'sample_size': len(read_length), 'min': read_length.min(), 'qtile25': np.percentile(read_length, 25), 'mean': np.mean(read_length), 'median': np.median(read_length), 'qtile75': np.percentile(read_length, 75), 'max': read_length.max(), 'std': np.std(read_length)} if return_lengths: read_len_dict['lengths'] = read_length else: fragment_len_dict = None read_len_dict = None return fragment_len_dict, read_len_dict deepTools-2.5.0/deeptools/getRatio.py0000640000201600010240000000440613036110117016741 0ustar ryanbioinfoimport numpy as np old_settings = np.seterr(all='ignore') def compute_ratio(value1, value2, args): value1 = value1 + args['pseudocount'] value2 = value2 + args['pseudocount'] ratio = float(value1) / value2 if args['valueType'] == 'log2': ratio = np.log2(ratio) elif args['valueType'] == 'reciprocal_ratio': # the reciprocal ratio of a/b # is a/b if a/b > 1 else -1* b/a ratio = ratio if ratio >= 1 else -1.0 / ratio return ratio def getRatio(tileCoverage, args): r""" The mapreduce method calls this function for each tile. The parameters (args) are fixed in the main method. >>> funcArgs= {'valueType': 'ratio', 'scaleFactors': (1,1), 'pseudocount': 1} >>> getRatio([9, 19], funcArgs) 0.5 >>> getRatio([0, 0], funcArgs) 1.0 >>> getRatio([np.nan, np.nan], funcArgs) nan >>> getRatio([np.nan, 1.0], funcArgs) nan >>> funcArgs['valueType'] ='subtract' >>> getRatio([20, 10], funcArgs) 10 >>> funcArgs['scaleFactors'] = (1, 0.5) >>> getRatio([10, 20], funcArgs) 0.0 The reciprocal ratio is of a and b is: is a/b if a/b > 1 else -1* b/a >>> funcArgs['valueType'] ='reciprocal_ratio' >>> funcArgs['scaleFactors'] = (1, 1) >>> funcArgs['pseudocount'] = 0 >>> getRatio([2, 1], funcArgs) 2.0 >>> getRatio([1, 2], funcArgs) -2.0 >>> getRatio([1, 1], funcArgs) 1.0 """ value1 = args['scaleFactors'][0] * tileCoverage[0] value2 = args['scaleFactors'][1] * tileCoverage[1] # if any of the two values to compare # is nan, return nan if np.isnan(value1) or np.isnan(value2): return np.nan # ratio case if args['valueType'] in ['ratio', 'log2', 'reciprocal_ratio']: bin_value = compute_ratio(value1, value2, args) # non ratio case (diff, sum etc) else: if args['valueType'] == 'subtract': bin_value = value1 - value2 elif args['valueType'] == 'add': bin_value = value1 + value2 elif args['valueType'] == 'first': bin_value = value1 elif args['valueType'] == 'second': bin_value = value2 elif args['valueType'] == 'mean': bin_value = (value1 + value2) / 2.0 return bin_value deepTools-2.5.0/deeptools/getScaleFactor.py0000640000201600010240000002310313067414642020062 0ustar ryanbioinfo#!/usr/bin/env python # -*- coding: utf-8 -*- import numpy as np import deeptools.mapReduce as mapReduce from deeptools import bamHandler from deeptools import utilities import sys debug = 0 def getFractionKept_wrapper(args): return getFractionKept_worker(*args) def getFractionKept_worker(chrom, start, end, bamFile, args): """ Queries the BAM file and counts the number of alignments kept/found in the first 50000 bases. """ bam = bamHandler.openBam(bamFile) end = min(end, start + 50000) tot = 0 filtered = 0 prev_start_pos = None # to store the start positions if chrom in bam.references: for read in bam.fetch(chrom, start, end): tot += 1 if args.minMappingQuality and read.mapq < args.minMappingQuality: filtered += 1 continue # filter reads based on SAM flag if args.samFlagInclude and read.flag & args.samFlagInclude != args.samFlagInclude: filtered += 1 continue if args.samFlagExclude and read.flag & args.samFlagExclude != 0: filtered += 1 continue # fragment length filtering tLen = utilities.getTLen(read) if args.minFragmentLength > 0 and tLen < args.minFragmentLength: filtered += 1 continue if args.maxFragmentLength > 0 and tLen > args.maxFragmentLength: filtered += 1 continue # get rid of duplicate reads that have same position on each of the # pairs if args.ignoreDuplicates and prev_start_pos \ and prev_start_pos == (read.reference_start, read.pnext, read.is_reverse): filtered += 1 continue prev_start_pos = (read.reference_start, read.pnext, read.is_reverse) # If filterRNAstrand is in args, then filter accordingly # This is very similar to what's used in the get_fragment_from_read function in the filterRnaStrand class if hasattr(args, "filterRNAstrand"): if read.is_paired: if args.filterRNAstrand == 'forward': if not ((read.flag & 128 == 128 and read.flag & 16 == 0) or (read.flag & 64 == 64 and read.flag & 32 == 0)): filtered += 1 continue elif args.filterRNAstrand == 'reverse': if not (read.flag & 144 == 144 or read.flag & 96 == 96): filtered += 1 continue else: if args.filterRNAstrand == 'forward' and read.flag & 16 == 0: filtered += 1 continue elif args.filterRNAstrand == 'reverse' and read.flag & 16 == 16: filtered += 1 continue return (filtered, tot) def fraction_kept(args): """ Count the following: (A) The total number of alignments sampled (B) The total number of alignments ignored due to any of the following: --samFlagInclude --samFlagExclude --minMappingQuality --ignoreDuplicates --minFragmentLength --maxFragmentLength Black list regions are already accounted for. This works by sampling the genome (by default, we'll iterate until we sample 1% or 100,000 alignments, whichever is smaller (unless there are fewer than 100,000 alignments, in which case sample everything). The sampling works by dividing the genome into bins and only looking at the first 50000 bases. If this doesn't yield sufficient alignments then the bin size is halved. """ filtered = 0 total = 0 distanceBetweenBins = 2000000 bam_handle = bamHandler.openBam(args.bam) bam_mapped = utilities.bam_total_reads(bam_handle, args.ignoreForNormalization) num_needed_to_sample = max(bam_mapped if bam_mapped <= 100000 else 0, min(100000, 0.01 * bam_mapped)) if args.ignoreForNormalization: chrom_sizes = [(chrom_name, bam_handle.lengths[idx]) for idx, chrom_name in enumerate(bam_handle.references) if chrom_name not in args.ignoreForNormalization] else: chrom_sizes = list(zip(bam_handle.references, bam_handle.lengths)) while total < num_needed_to_sample and distanceBetweenBins > 50000: # If we've iterated, then halve distanceBetweenBins distanceBetweenBins /= 2 if distanceBetweenBins < 50000: distanceBetweenBins = 50000 res = mapReduce.mapReduce((bam_handle.filename, args), getFractionKept_wrapper, chrom_sizes, genomeChunkLength=distanceBetweenBins, blackListFileName=args.blackListFileName, numberOfProcessors=args.numberOfProcessors, verbose=args.verbose) if len(res): filtered, total = np.sum(res, axis=0) if total == 0: # This should never happen total = 1 return 1.0 - float(filtered) / float(total) def get_num_kept_reads(args): """ Substracts from the total number of mapped reads in a bamfile the proportion of reads that fall into blacklisted regions or that are filtered :return: integer """ bam_handle = bamHandler.openBam(args.bam) bam_mapped_total = utilities.bam_total_reads(bam_handle, args.ignoreForNormalization) if args.blackListFileName: blacklisted = utilities.bam_blacklisted_reads(bam_handle, args.ignoreForNormalization, args.blackListFileName, args.numberOfProcessors) print("There are {0} alignments, of which {1} are completely " "within a blacklist region.".format(bam_mapped_total, blacklisted)) num_kept_reads = bam_mapped_total - blacklisted else: num_kept_reads = bam_mapped_total ftk = fraction_kept(args) if ftk < 1: num_kept_reads *= ftk print("Due to filtering, {0}% of the aforementioned alignments " "will be used {1}".format(100 * ftk, num_kept_reads)) return num_kept_reads, bam_mapped_total def get_scale_factor(args): scale_factor = args.scaleFactor bam_mapped, bam_mapped_total = get_num_kept_reads(args) if args.normalizeTo1x: # Print output, since normalzation stuff isn't printed to stderr otherwise sys.stderr.write("normalization: 1x\n") # try to guess fragment length if the bam file contains paired end reads from deeptools.getFragmentAndReadSize import get_read_and_fragment_length frag_len_dict, read_len_dict = get_read_and_fragment_length(args.bam, return_lengths=False, blackListFileName=args.blackListFileName, numberOfProcessors=args.numberOfProcessors, verbose=args.verbose) if args.extendReads: if args.extendReads is True: # try to guess fragment length if the bam file contains paired end reads if frag_len_dict: fragment_length = frag_len_dict['median'] else: exit("*ERROR*: library is not paired-end. Please provide an extension length.") if args.verbose: print(("Fragment length based on paired en data " "estimated to be {}".format(frag_len_dict['median']))) elif args.extendReads < 1: exit("*ERROR*: read extension must be bigger than one. Value give: {} ".format(args.extendReads)) elif args.extendReads > 2000: exit("*ERROR*: read extension must be smaller that 2000. Value give: {} ".format(args.extendReads)) else: fragment_length = args.extendReads else: # set as fragment length the read length fragment_length = int(read_len_dict['median']) if args.verbose: print("Estimated read length is {}".format(int(read_len_dict['median']))) current_coverage = \ float(bam_mapped * fragment_length) / args.normalizeTo1x # the scaling sets the coverage to match 1x scale_factor *= 1.0 / current_coverage if debug: print("Estimated current coverage {}".format(current_coverage)) print("Scaling factor {}".format(args.scaleFactor)) elif args.normalizeUsingRPKM: # Print output, since normalzation stuff isn't printed to stderr otherwise sys.stderr.write("normalization: RPKM\n") # the RPKM is the # reads per tile / \ # ( total reads (in millions) * tile length in Kb) million_reads_mapped = float(bam_mapped) / 1e6 tile_len_in_kb = float(args.binSize) / 1000 scale_factor *= 1.0 / (million_reads_mapped * tile_len_in_kb) if debug: print("scale factor using RPKM is {0}".format(args.scaleFactor)) else: # Print output, since normalzation stuff isn't printed to stderr otherwise sys.stderr.write("normalization: depth\n") scale_factor *= bam_mapped / float(bam_mapped_total) if args.verbose: print("Final scaling factor: {}".format(scale_factor)) return scale_factor deepTools-2.5.0/deeptools/getScorePerBigWigBin.py0000640000201600010240000002751613006372703021146 0ustar ryanbioinfoimport pyBigWig import numpy as np import os import sys import shutil import warnings # deepTools packages import deeptools.mapReduce as mapReduce import deeptools.utilities # debug = 0 old_settings = np.seterr(all='ignore') def countReadsInRegions_wrapper(args): # Using arguments unpacking! return countFragmentsInRegions_worker(*args) def countFragmentsInRegions_worker(chrom, start, end, bigWigFiles, stepSize, binLength, save_data, bedRegions=None ): """ returns the average score in each bigwig file at each 'stepSize' position within the interval start, end for a 'binLength' window. Because the idea is to get counts for window positions at different positions for sampling the bins are equally spaced and *not adjacent*. If a list of bedRegions is given, then the number of reads that overlaps with each region is counted. Test dataset with two samples covering 200 bp. >>> test = Tester() Fragment coverage. >>> np.transpose(countFragmentsInRegions_worker(test.chrom, 0, 200, [test.bwFile1, test.bwFile2], 50, 25, False)[0]) array([[ 1., 1., 2., 2.], [ 1., 1., 1., 3.]]) >>> np.transpose(countFragmentsInRegions_worker(test.chrom, 0, 200, [test.bwFile1, test.bwFile2], 200, 200, False)[0]) array([[ 1.5], [ 1.5]]) BED regions: >>> bedRegions = [[test.chrom, [(45, 55)]], [test.chrom, [(95, 105)]], [test.chrom, [(145, 155)]]] >>> np.transpose(countFragmentsInRegions_worker(test.chrom, 0, 200,[test.bwFile1, test.bwFile2], 200, 200, False, ... bedRegions=bedRegions)[0]) array([[ 1. , 1.5, 2. ], [ 1. , 1. , 2. ]]) """ assert start < end, "start {} bigger that end {}".format(start, end) # array to keep the scores for the regions sub_score_per_bin = [] rows = 0 bigwig_handlers = [] for foo in bigWigFiles: bigwig_handlers.append(pyBigWig.open(foo)) regions_to_consider = [] if bedRegions: for reg in bedRegions: regs = [] for exon in reg[1]: regs.append((exon[0], exon[1])) regions_to_consider.append(regs) else: for i in range(start, end, stepSize): if (i + binLength) > end: regions_to_consider.append([(i, end)]) # last bin (may be smaller) else: regions_to_consider.append([(i, i + binLength)]) if save_data: _file = open(deeptools.utilities.getTempFileName(suffix='.bed'), 'w+t') _file_name = _file.name else: _file_name = '' warnings.simplefilter("default") i = 0 for reg in regions_to_consider: avgReadsArray = [] i += 1 for idx, bwh in enumerate(bigwig_handlers): if chrom not in bwh.chroms(): unmod_name = chrom if chrom.startswith('chr'): # remove the chr part from chromosome name chrom = chrom[3:] else: # prefix with 'chr' the chromosome name chrom = 'chr' + chrom if chrom not in bwh.chroms(): exit('Chromosome name {} not found in bigwig file\n {}\n'.format(unmod_name, bigWigFiles[idx])) weights = [] scores = [] for exon in reg: weights.append(exon[1] - exon[0]) score = bwh.stats(chrom, exon[0], exon[1]) if score is None or score == [None] or np.isnan(score[0]): score = [np.nan] scores.extend(score) avgReadsArray.append(np.average(scores, weights=weights)) # mean of fragment coverage for region sub_score_per_bin.extend(avgReadsArray) rows += 1 if save_data: starts = [] ends = [] for exon in reg: starts.append(str(exon[0])) ends.append(str(exon[1])) starts = ",".join(starts) ends = ",".join(ends) _file.write("\t".join(map(str, [chrom, starts, ends])) + "\t") _file.write("\t".join(["{}".format(x) for x in avgReadsArray]) + "\n") if save_data: _file.close() warnings.resetwarnings() # the output is a matrix having as many rows as the variable 'row' # and as many columns as bigwig files. The rows correspond to # each of the regions processed by the worker. # np.array([[score1_1, score1_2], # [score2_1, score2_2]] return np.array(sub_score_per_bin).reshape(rows, len(bigWigFiles)), _file_name def getChromSizes(bigwigFilesList): """ Get chromosome sizes from bigWig file with pyBigWig Test dataset with two samples covering 200 bp. >>> test = Tester() Chromosome name(s) and size(s). >>> assert(getChromSizes([test.bwFile1, test.bwFile2]) == ([('3R', 200)], set([]))) """ # check that the path to USCS bedGraphToBigWig as set in the config # is installed and is executable. def print_chr_names_and_size(chr_set): sys.stderr.write("chromosome\tlength\n") for name, size in chr_set: sys.stderr.write("{0:>15}\t{1:>10}\n".format(name, size)) bigwigFilesList = bigwigFilesList[:] common_chr = set() for fname in bigwigFilesList: fh = pyBigWig.open(fname) common_chr = common_chr.union(set(fh.chroms().items())) fh.close() non_common_chr = set() for bw in bigwigFilesList: _names_and_size = set(pyBigWig.open(bw).chroms().items()) if len(common_chr & _names_and_size) == 0: # try to add remove 'chr' from the chromosme name _corr_names_size = set() for chrom_name, size in _names_and_size: if chrom_name.startswith('chr'): _corr_names_size.add((chrom_name[3:], size)) else: _corr_names_size.add(('chr' + chrom_name, size)) if len(common_chr & _corr_names_size) == 0: message = "No common chromosomes found. Are the bigwig files " \ "from the same species and same assemblies?\n" sys.stderr.write(message) print_chr_names_and_size(common_chr) sys.stderr.write("\nand the following is the list of the unmatched chromosome and chromosome\n" "lengths from file\n{}\n".format(bw)) print_chr_names_and_size(_names_and_size) exit(1) else: _names_and_size = _corr_names_size non_common_chr |= common_chr ^ _names_and_size common_chr = common_chr & _names_and_size if len(non_common_chr) > 0: sys.stderr.write("\nThe following chromosome names did not match between the the bigwig files\n") print_chr_names_and_size(non_common_chr) # get the list of common chromosome names and sizes return sorted(common_chr), non_common_chr def getScorePerBin(bigWigFiles, binLength, numberOfProcessors=1, verbose=False, region=None, bedFile=None, blackListFileName=None, stepSize=None, chrsToSkip=[], out_file_for_raw_data=None, allArgs=None): """ This function returns a matrix containing scores (median) for the coverage of fragments within a region. Each row corresponds to a sampled region. Likewise, each column corresponds to a bigwig file. Test dataset with two samples covering 200 bp. >>> test = Tester() >>> np.transpose(getScorePerBin([test.bwFile1, test.bwFile2], 50, 3)) array([[ 1., 1., 2., 2.], [ 1., 1., 1., 3.]]) """ # Try to determine an optimal fraction of the genome (chunkSize) # that is sent to workers for analysis. If too short, too much time # is spent loading the files # if too long, some processors end up free. # the following is a heuristic # get list of common chromosome names and sizes chrom_sizes, non_common = getChromSizes(bigWigFiles) # skip chromosome in the list. This is usually for the # X chromosome which may have either one copy in a male sample # or a mixture of male/female and is unreliable. # Also the skip may contain heterochromatic regions and # mitochondrial DNA if chrsToSkip and len(chrsToSkip): chrom_sizes = [x for x in chrom_sizes if x[0] not in chrsToSkip] chrnames, chrlengths = list(zip(*chrom_sizes)) if stepSize is None: stepSize = binLength # for adjacent bins # set chunksize based on number of processors used chunkSize = max(sum(chrlengths) / numberOfProcessors, int(1e6)) # make chunkSize multiple of binLength chunkSize -= chunkSize % binLength if verbose: print("step size is {}".format(stepSize)) if region: # in case a region is used, append the tilesize region += ":{}".format(binLength) # mapReduce( (staticArgs), func, chromSize, etc. ) if out_file_for_raw_data: save_file = True else: save_file = False # Handle GTF options transcriptID, exonID, transcript_id_designator, keepExons = deeptools.utilities.gtfOptions(allArgs) imap_res = mapReduce.mapReduce((bigWigFiles, stepSize, binLength, save_file), countReadsInRegions_wrapper, chrom_sizes, genomeChunkLength=chunkSize, bedFile=bedFile, blackListFileName=blackListFileName, region=region, numberOfProcessors=numberOfProcessors, transcriptID=transcriptID, exonID=exonID, keepExons=keepExons, transcript_id_designator=transcript_id_designator) if out_file_for_raw_data: if len(non_common): sys.stderr.write("*Warning*\nThe resulting bed file does not contain information for " "the chromosomes that were not common between the bigwig files\n") # concatenate intermediary bedgraph files ofile = open(out_file_for_raw_data, "w") for _values, tempFileName in imap_res: if tempFileName: # concatenate all intermediate tempfiles into one f = open(tempFileName, 'r') shutil.copyfileobj(f, ofile) f.close() os.remove(tempFileName) ofile.close() # the matrix scores are in the first element of each of the entries in imap_res score_per_bin = np.concatenate([x[0] for x in imap_res], axis=0) return score_per_bin class Tester(object): def __init__(self): """ The the two bigWig files are as follows: $ cat /tmp/testA.bg 3R 0 100 1 3R 100 200 2 $ cat /tmp/testB.bg 3R 0 150 1 3R 150 200 3 They cover 200 bp: 0 50 100 150 200 |------------------------------------------------------------| A 111111111111111111111111111111122222222222222222222222222222 B 111111111111111111111111111111111111111111111333333333333333 """ self.root = os.path.dirname(os.path.abspath(__file__)) + "/test/test_data/" self.bwFile1 = self.root + "testA.bw" self.bwFile2 = self.root + "testB.bw" self.bwFile_PE = self.root + "test_paired2.bw" self.chrom = '3R' # global debug # debug = 0 deepTools-2.5.0/deeptools/heatmapper.py0000640000201600010240000015043213067414642017330 0ustar ryanbioinfoimport sys from os.path import splitext, basename import gzip from collections import OrderedDict import numpy as np from copy import deepcopy import pyBigWig from deeptools import getScorePerBigWigBin from deeptools import mapReduce from deeptools.utilities import toString, toBytes old_settings = np.seterr(all='ignore') def chopRegions(exonsInput, left=0, right=0): """ exons is a list of (start, end) tuples. The goal is to chop these into separate lists of tuples, to take care or unscaled regions. "left" and "right" denote regions of a given size to exclude from the normal binning process (unscaled regions). This outputs three lists of (start, end) tuples: leftBins: 5' unscaled regions bodyBins: body bins for scaling rightBins: 3' unscaled regions In addition are two integers padLeft: Number of bases of padding on the left (due to not being able to fulfill "left") padRight: As above, but on the right side """ leftBins = [] rightBins = [] padLeft = 0 padRight = 0 exons = deepcopy(exonsInput) while len(exons) > 0 and left > 0: width = exons[0][1] - exons[0][0] if width <= left: leftBins.append(exons[0]) del exons[0] left -= width else: leftBins.append((exons[0][0], exons[0][0] + left)) exons[0] = (exons[0][0] + left, exons[0][1]) left = 0 if left > 0: padLeft = left while len(exons) > 0 and right > 0: width = exons[-1][1] - exons[-1][0] if width <= right: rightBins.append(exons[-1]) del exons[-1] right -= width else: rightBins.append((exons[-1][1] - right, exons[-1][1])) exons[-1] = (exons[-1][0], exons[-1][1] - right) right = 0 if right > 0: padRight = right return leftBins, exons, rightBins[::-1], padLeft, padRight def chopRegionsFromMiddle(exonsInput, left=0, right=0): """ Like chopRegions(), above, but returns two lists of tuples on each side of the center point of the exons. The steps are as follow: 1) Find the center point of the set of exons (e.g., [(0, 200), (300, 400), (800, 900)] would be centered at 200) * If a given exon spans the center point then the exon is split 2) The given number of bases at the end of the left-of-center list are extracted * If the set of exons don't contain enough bases, then padLeft is incremented accordingly 3) As above but for the right-of-center list 4) A tuple of (#2, #3, pading on the left, and padding on the right) is returned """ leftBins = [] rightBins = [] size = sum([x[1] - x[0] for x in exonsInput]) middle = size // 2 cumulativeSum = 0 padLeft = 0 padRight = 0 exons = deepcopy(exonsInput) # Split exons in half for exon in exons: size = exon[1] - exon[0] if cumulativeSum >= middle: rightBins.append(exon) elif cumulativeSum + size < middle: leftBins.append(exon) else: # Don't add 0-width exonic bins! if exon[0] < exon[1] - cumulativeSum - size + middle: leftBins.append((exon[0], exon[1] - cumulativeSum - size + middle)) if exon[1] - cumulativeSum - size + middle < exon[1]: rightBins.append((exon[1] - cumulativeSum - size + middle, exon[1])) cumulativeSum += size # Trim leftBins/adjust padLeft lSum = sum([x[1] - x[0] for x in leftBins]) if lSum > left: lSum = 0 for i, exon in enumerate(leftBins[::-1]): size = exon[1] - exon[0] if lSum + size > left: leftBins[-i - 1] = (exon[1] + lSum - left, exon[1]) break lSum += size if lSum == left: break i += 1 if i < len(leftBins): leftBins = leftBins[-i:] elif lSum < left: padLeft = left - lSum # Trim rightBins/adjust padRight rSum = sum([x[1] - x[0] for x in rightBins]) if rSum > right: rSum = 0 for i, exon in enumerate(rightBins): size = exon[1] - exon[0] if rSum + size > right: rightBins[i] = (exon[0], exon[1] - rSum - size + right) break rSum += size if rSum == right: break rightBins = rightBins[:i + 1] elif rSum < right: padRight = right - rSum return leftBins, rightBins, padLeft, padRight def trimZones(zones, maxLength, binSize, padRight): """ Given a (variable length) list of lists of (start, end) tuples, trim/remove and tuple that extends past maxLength (e.g., the end of a chromosome) Returns the trimmed zones and padding """ output = [] for zone, nbins in zones: outZone = [] changed = False for reg in zone: if reg[0] >= maxLength: changed = True padRight += reg[1] - reg[0] continue if reg[1] > maxLength: changed = True padRight += reg[1] - maxLength reg = (reg[0], maxLength) if reg[1] > reg[0]: outZone.append(reg) if changed: nBins = sum(x[1] - x[0] for x in outZone) // binSize else: nBins = nbins output.append((outZone, nBins)) return output, padRight def compute_sub_matrix_wrapper(args): return heatmapper.compute_sub_matrix_worker(*args) class heatmapper(object): """ Class to handle the reading and plotting of matrices. """ def __init__(self): self.parameters = None self.lengthDict = None self.matrix = None self.regions = None self.blackList = None def computeMatrix(self, score_file_list, regions_file, parameters, blackListFileName=None, verbose=False, allArgs=None): """ Splits into multiple cores the computation of the scores per bin for each region (defined by a hash '#' in the regions (BED/GFF) file. """ if parameters['body'] > 0 and \ parameters['body'] % parameters['bin size'] > 0: exit("The --regionBodyLength has to be " "a multiple of --binSize.\nCurrently the " "values are {} {} for\nregionsBodyLength and " "binSize respectively\n".format(parameters['body'], parameters['bin size'])) # the beforeRegionStartLength is extended such that # length is a multiple of binSize if parameters['downstream'] % parameters['bin size'] > 0: exit("Length of region after the body has to be " "a multiple of --binSize.\nCurrent value " "is {}\n".format(parameters['downstream'])) if parameters['upstream'] % parameters['bin size'] > 0: exit("Length of region before the body has to be a multiple of " "--binSize\nCurrent value is {}\n".format(parameters['upstream'])) if parameters['unscaled 5 prime'] % parameters['bin size'] > 0: exit("Length of the unscaled 5 prime region has to be a multiple of " "--binSize\nCurrent value is {}\n".format(parameters['unscaled 5 prime'])) if parameters['unscaled 3 prime'] % parameters['bin size'] > 0: exit("Length of the unscaled 5 prime region has to be a multiple of " "--binSize\nCurrent value is {}\n".format(parameters['unscaled 3 prime'])) # Take care of GTF options transcriptID = "transcript" exonID = "exon" transcript_id_designator = "transcript_id" keepExons = False if allArgs is not None: allArgs = vars(allArgs) transcriptID = allArgs.get("transcriptID", transcriptID) exonID = allArgs.get("exonID", exonID) transcript_id_designator = allArgs.get("transcript_id_designator", transcript_id_designator) keepExons = allArgs.get("keepExons", keepExons) chromSizes, _ = getScorePerBigWigBin.getChromSizes(score_file_list) res, labels = mapReduce.mapReduce([score_file_list, parameters], compute_sub_matrix_wrapper, chromSizes, self_=self, bedFile=regions_file, blackListFileName=blackListFileName, numberOfProcessors=parameters['proc number'], includeLabels=True, transcriptID=transcriptID, exonID=exonID, transcript_id_designator=transcript_id_designator, keepExons=keepExons) # each worker in the pool returns a tuple containing # the submatrix data, the regions that correspond to the # submatrix, and the number of regions lacking scores # Since this is largely unsorted, we need to sort by group # merge all the submatrices into matrix matrix = np.concatenate([r[0] for r in res], axis=0) regions = [] regions_no_score = 0 for idx in range(len(res)): if len(res[idx][1]): regions.extend(res[idx][1]) regions_no_score += res[idx][2] groups = [x[3] for x in regions] foo = sorted(zip(groups, list(range(len(regions))), regions)) sortIdx = [x[1] for x in foo] regions = [x[2] for x in foo] matrix = matrix[sortIdx] # mask invalid (nan) values matrix = np.ma.masked_invalid(matrix) assert matrix.shape[0] == len(regions), \ "matrix length does not match regions length" if len(regions) == 0: sys.stderr.write( "\nERROR: BED file does not contain any valid regions. " "Please check\n") exit(1) if regions_no_score == len(regions): exit("\nERROR: None of the BED regions could be found in the bigWig" "file.\nPlease check that the bigwig file is valid and " "that the chromosome names between the BED file and " "the bigWig file correspond to each other\n") if regions_no_score > len(regions) * 0.75: file_type = 'bigwig' if score_file_list[0].endswith(".bw") else "BAM" prcnt = 100 * float(regions_no_score) / len(regions) sys.stderr.write( "\n\nWarning: {0:.2f}% of regions are *not* associated\n" "to any score in the given {1} file. Check that the\n" "chromosome names from the BED file are consistent with\n" "the chromosome names in the given {2} file and that both\n" "files refer to the same species\n\n".format(prcnt, file_type, file_type)) self.parameters = parameters numcols = matrix.shape[1] num_ind_cols = self.get_num_individual_matrix_cols() sample_boundaries = list(range(0, numcols + num_ind_cols, num_ind_cols)) sample_labels = [splitext(basename(x))[0] for x in score_file_list] # Determine the group boundaries group_boundaries = [] group_labels_filtered = [] last_idx = -1 for x in range(len(regions)): if regions[x][3] != last_idx: last_idx = regions[x][3] group_boundaries.append(x) group_labels_filtered.append(labels[last_idx]) group_boundaries.append(len(regions)) # check if a given group is too small. Groups that # are too small can't be plotted and an exception is thrown. group_len = np.diff(group_boundaries) if len(group_len) > 1: sum_len = sum(group_len) group_frac = [float(x) / sum_len for x in group_len] if min(group_frac) <= 0.002: sys.stderr.write( "One of the groups defined in the bed file is " "too small.\nGroups that are too small can't be plotted. " "\n") self.matrix = _matrix(regions, matrix, group_boundaries, sample_boundaries, group_labels_filtered, sample_labels) if parameters['skip zeros']: self.matrix.removeempty() @staticmethod def compute_sub_matrix_worker(self, chrom, start, end, score_file_list, parameters, regions): """ Returns ------- numpy matrix A numpy matrix that contains per each row the values found per each of the regions given """ # read BAM or scores file score_file_handlers = [] for sc_file in score_file_list: score_file_handlers.append(pyBigWig.open(sc_file)) # determine the number of matrix columns based on the lengths # given by the user, times the number of score files matrix_cols = len(score_file_list) * \ ((parameters['downstream'] + parameters['unscaled 5 prime'] + parameters['unscaled 3 prime'] + parameters['upstream'] + parameters['body']) // parameters['bin size']) # create an empty matrix to store the values sub_matrix = np.zeros((len(regions), matrix_cols)) sub_matrix[:] = np.NAN j = 0 sub_regions = [] regions_no_score = 0 for transcript in regions: feature_chrom = transcript[0] exons = transcript[1] feature_start = exons[0][0] feature_end = exons[-1][1] feature_name = transcript[2] feature_strand = transcript[4] padLeft = 0 padRight = 0 padLeftNaN = 0 padRightNaN = 0 upstream = [] downstream = [] # get the body length body_length = np.sum([x[1] - x[0] for x in exons]) - parameters['unscaled 5 prime'] - parameters['unscaled 3 prime'] # print some information if parameters['body'] > 0 and \ body_length < parameters['bin size']: if parameters['verbose']: sys.stderr.write("A region that is shorter than the bin size (possibly only after accounting for unscaled regions) was found: " "({0}) {1} {2}:{3}:{4}. Skipping...\n".format((body_length - parameters['unscaled 5 prime'] - parameters['unscaled 3 prime']), feature_name, feature_chrom, feature_start, feature_end)) coverage = np.zeros(matrix_cols) if not parameters['missing data as zero']: coverage[:] = np.nan else: if feature_strand == '-': if parameters['downstream'] > 0: upstream = [(feature_start - parameters['downstream'], feature_start)] if parameters['upstream'] > 0: downstream = [(feature_end, feature_end + parameters['upstream'])] unscaled5prime, body, unscaled3prime, padLeft, padRight = chopRegions(exons, left=parameters['unscaled 3 prime'], right=parameters['unscaled 5 prime']) # bins per zone a = parameters['downstream'] // parameters['bin size'] b = parameters['unscaled 3 prime'] // parameters['bin size'] d = parameters['unscaled 5 prime'] // parameters['bin size'] e = parameters['upstream'] // parameters['bin size'] else: if parameters['upstream'] > 0: upstream = [(feature_start - parameters['upstream'], feature_start)] if parameters['downstream'] > 0: downstream = [(feature_end, feature_end + parameters['downstream'])] unscaled5prime, body, unscaled3prime, padLeft, padRight = chopRegions(exons, left=parameters['unscaled 5 prime'], right=parameters['unscaled 3 prime']) a = parameters['upstream'] // parameters['bin size'] b = parameters['unscaled 5 prime'] // parameters['bin size'] d = parameters['unscaled 3 prime'] // parameters['bin size'] e = parameters['downstream'] // parameters['bin size'] c = parameters['body'] // parameters['bin size'] # build zones (each is a list of tuples) # zone0: region before the region start, # zone1: unscaled 5 prime region # zone2: the body of the region # zone3: unscaled 3 prime region # zone4: the region from the end of the region downstream # the format for each zone is: [(start, end), ...], number of bins # Note that for "reference-point", upstream/downstream will go # through the exons (if requested) and then possibly continue # on the other side (unless parameters['nan after end'] is true) if parameters['body'] > 0: zones = [(upstream, a), (unscaled5prime, b), (body, c), (unscaled3prime, d), (downstream, e)] elif parameters['ref point'] == 'TES': # around TES if feature_strand == '-': downstream, body, unscaled3prime, padRight, _ = chopRegions(exons, left=parameters['upstream']) if padRight > 0 and parameters['nan after end'] is True: padRightNaN += padRight elif padRight > 0: downstream.append((downstream[-1][1], downstream[-1][1] + padRight)) padRight = 0 else: unscale5prime, body, upstream, _, padLeft = chopRegions(exons, right=parameters['upstream']) if padLeft > 0 and parameters['nan after end'] is True: padLeftNaN += padLeft elif padLeft > 0: upstream.insert(0, (upstream[0][0] - padLeft, upstream[0][0])) padLeft = 0 e = np.sum([x[1] - x[0] for x in downstream]) // parameters['bin size'] a = np.sum([x[1] - x[0] for x in upstream]) // parameters['bin size'] zones = [(upstream, a), (downstream, e)] elif parameters['ref point'] == 'center': # at the region center if feature_strand == '-': upstream, downstream, padLeft, padRight = chopRegionsFromMiddle(exons, left=parameters['downstream'], right=parameters['upstream']) else: upstream, downstream, padLeft, padRight = chopRegionsFromMiddle(exons, left=parameters['upstream'], right=parameters['downstream']) if padLeft > 0 and parameters['nan after end'] is True: padLeftNaN += padLeft elif padLeft > 0: if len(upstream) > 0: upstream.insert(0, (upstream[0][0] - padLeft, upstream[0][0])) else: upstream = [(downstream[0][0] - padLeft, downstream[0][0])] padLeft = 0 if padRight > 0 and parameters['nan after end'] is True: padRightNaN += padRight elif padRight > 0: downstream.append((downstream[-1][1], downstream[-1][1] + padRight)) padRight = 0 a = np.sum([x[1] - x[0] for x in upstream]) // parameters['bin size'] e = np.sum([x[1] - x[0] for x in downstream]) // parameters['bin size'] # It's possible for a/e to be floats or 0 yet upstream/downstream isn't empty if a < 1: upstream = [] a = 0 if e < 1: downstream = [] e = 0 zones = [(upstream, a), (downstream, e)] else: # around TSS if feature_strand == '-': unscale5prime, body, upstream, _, padLeft = chopRegions(exons, right=parameters['downstream']) if padLeft > 0 and parameters['nan after end'] is True: padLeftNaN += padLeft elif padLeft > 0: upstream.insert(0, (upstream[0][0] - padLeft, upstream[0][0])) padLeft = 0 else: downstream, body, unscaled3prime, padRight, _ = chopRegions(exons, left=parameters['downstream']) if padRight > 0 and parameters['nan after end'] is True: padRightNaN += padRight elif padRight > 0: downstream.append((downstream[-1][1], downstream[-1][1] + padRight)) padRight = 0 a = np.sum([x[1] - x[0] for x in upstream]) // parameters['bin size'] e = np.sum([x[1] - x[0] for x in downstream]) // parameters['bin size'] zones = [(upstream, a), (downstream, e)] foo = parameters['upstream'] bar = parameters['downstream'] if feature_strand == '-': foo, bar = bar, foo if padLeftNaN > 0: expected = foo // parameters['bin size'] padLeftNaN = int(round(float(padLeftNaN) / parameters['bin size'])) if expected - padLeftNaN - a > 0: padLeftNaN += 1 if padRightNaN > 0: expected = bar // parameters['bin size'] padRightNaN = int(round(float(padRightNaN) / parameters['bin size'])) if expected - padRightNaN - e > 0: padRightNaN += 1 coverage = [] # compute the values for each of the files being processed. # "cov" is a numpy array of bins for sc_handler in score_file_handlers: # We're only supporting bigWig files at this point cov = heatmapper.coverage_from_big_wig( sc_handler, feature_chrom, zones, parameters['bin size'], parameters['bin avg type'], parameters['missing data as zero'], parameters['verbose']) if padLeftNaN > 0: cov = np.concatenate([[np.nan] * padLeftNaN, cov]) if padRightNaN > 0: cov = np.concatenate([cov, [np.nan] * padRightNaN]) if feature_strand == "-": cov = cov[::-1] coverage = np.hstack([coverage, cov]) if coverage is None: regions_no_score += 1 if parameters['verbose']: sys.stderr.write( "No data was found for region " "{0} {1}:{2}-{3}. Skipping...\n".format( feature_name, feature_chrom, feature_start, feature_end)) coverage = np.zeros(matrix_cols) if not parameters['missing data as zero']: coverage[:] = np.nan try: temp = coverage.copy() temp[np.isnan(temp)] = 0 except: if parameters['verbose']: sys.stderr.write( "No scores defined for region " "{0} {1}:{2}-{3}. Skipping...\n".format(feature_name, feature_chrom, feature_start, feature_end)) coverage = np.zeros(matrix_cols) if not parameters['missing data as zero']: coverage[:] = np.nan if parameters['min threshold'] and coverage.min() <= parameters['min threshold']: continue if parameters['max threshold'] and coverage.max() >= parameters['max threshold']: continue if parameters['scale'] != 1: coverage = parameters['scale'] * coverage sub_matrix[j, :] = coverage sub_regions.append(transcript) j += 1 # remove empty rows sub_matrix = sub_matrix[0:j, :] if len(sub_regions) != len(sub_matrix[:, 0]): sys.stderr.write("regions lengths do not match\n") return sub_matrix, sub_regions, regions_no_score @staticmethod def coverage_from_array(valuesArray, zones, binSize, avgType): try: valuesArray[0] except (IndexError, TypeError) as detail: sys.stderr.write("{0}\nvalues array value: {1}, zones {2}\n".format(detail, valuesArray, zones)) cvglist = [] zoneEnd = 0 valStart = 0 valEnd = 0 for zone, nBins in zones: if nBins: # linspace is used to more or less evenly partition the data points into the given number of bins zoneEnd += nBins valStart = valEnd valEnd += np.sum([x[1] - x[0] for x in zone]) counts_list = [] # Partition the space into bins if nBins == 1: pos_array = np.array([valStart]) else: pos_array = np.linspace(valStart, valEnd, nBins, endpoint=False, dtype=int) pos_array = np.append(pos_array, valEnd) idx = 0 while idx < nBins: idxStart = int(pos_array[idx]) idxEnd = max(int(pos_array[idx + 1]), idxStart + 1) try: counts_list.append(heatmapper.my_average(valuesArray[idxStart:idxEnd], avgType)) except Exception as detail: sys.stderr.write("Exception found: {0}\n".format(detail)) idx += 1 cvglist.append(np.array(counts_list)) return np.concatenate(cvglist) @staticmethod def change_chrom_names(chrom): """ Changes UCSC chromosome names to ensembl chromosome names and vice versa. """ if chrom.startswith('chr'): # remove the chr part from chromosome name chrom = chrom[3:] if chrom == "M": chrom = "MT" else: # prefix with 'chr' the chromosome name chrom = 'chr' + chrom if chrom == "chrMT": chrom = "chrM" return chrom @staticmethod def coverage_from_big_wig(bigwig, chrom, zones, binSize, avgType, nansAsZeros=False, verbose=True): """ uses pyBigWig to query a region define by chrom and zones. The output is an array that contains the bigwig value per base pair. The summary over bins is done in a later step when coverage_from_array is called. This method is more reliable than querying the bins directly from the bigwig, which should be more efficient. By default, any region, even if no chromosome match is found on the bigwig file, produces a result. In other words no regions are skipped. zones: array as follows zone0: region before the region start, zone1: 5' unscaled region (if present) zone2: the body of the region (not always present) zone3: 3' unscaled region (if present) zone4: the region from the end of the region downstream each zone is a tuple containing start, end, and number of bins This is useful if several matrices wants to be merged or if the sorted BED output of one computeMatrix operation needs to be used for other cases """ nVals = 0 for zone, _ in zones: for region in zone: nVals += region[1] - region[0] values_array = np.zeros(nVals) if not nansAsZeros: values_array[:] = np.nan if chrom not in list(bigwig.chroms().keys()): unmod_name = chrom chrom = heatmapper.change_chrom_names(chrom) if chrom not in list(bigwig.chroms().keys()): if verbose: sys.stderr.write("Warning: Your chromosome names do not match.\nPlease check that the " "chromosome names in your BED file\ncorrespond to the names in your " "bigWig file.\nAn empty line will be added to your heatmap.\nThe problematic " "chromosome name is {0}\n\n".format(unmod_name)) # return empty nan array return heatmapper.coverage_from_array(values_array, zones, binSize, avgType) maxLen = bigwig.chroms(chrom) startIdx = 0 endIdx = 0 for zone, _ in zones: for region in zone: startIdx = endIdx if region[0] < 0: endIdx += abs(region[0]) values_array[startIdx:endIdx] = np.nan startIdx = endIdx start = max(0, region[0]) end = min(maxLen, region[1]) endIdx += end - start if start < end: # This won't be the case if we extend off the front of a chromosome, such as (-100, 0) values_array[startIdx:endIdx] = bigwig.values(chrom, start, end) if end < region[1]: startIdx = endIdx endIdx += region[1] - end values_array[startIdx:endIdx] = np.nan # replaces nans for zeros if nansAsZeros: values_array[np.isnan(values_array)] = 0 return heatmapper.coverage_from_array(values_array, zones, binSize, avgType) @staticmethod def my_average(valuesArray, avgType='mean'): """ computes the mean, median, etc but only for those values that are not Nan """ valuesArray = np.ma.masked_invalid(valuesArray) avg = np.ma.__getattribute__(avgType)(valuesArray) if isinstance(avg, np.ma.core.MaskedConstant): return np.nan else: return avg def matrix_from_dict(self, matrixDict, regionsDict, parameters): self.regionsDict = regionsDict self.matrixDict = matrixDict self.parameters = parameters self.lengthDict = OrderedDict() self.matrixAvgsDict = OrderedDict() def read_matrix_file(self, matrix_file): # reads a bed file containing the position # of genomic intervals # In case a hash sign '#' is found in the # file, this is considered as a delimiter # to split the heatmap into groups import json regions = [] matrix_rows = [] current_group_index = 0 max_group_bound = None fh = gzip.open(matrix_file) for line in fh: line = toString(line).strip() # read the header file containing the parameters # used if line.startswith("@"): # the parameters used are saved using # json self.parameters = json.loads(line[1:].strip()) max_group_bound = self.parameters['group_boundaries'][1] continue # split the line into bed interval and matrix values region = line.split('\t') chrom, start, end, name, score, strand = region[0:6] matrix_row = np.ma.masked_invalid(np.fromiter(region[6:], np.float)) matrix_rows.append(matrix_row) starts = start.split(",") ends = end.split(",") regs = [(int(x), int(y)) for x, y in zip(starts, ends)] # get the group index if len(regions) >= max_group_bound: current_group_index += 1 max_group_bound = self.parameters['group_boundaries'][current_group_index + 1] regions.append([chrom, regs, name, max_group_bound, strand, score]) matrix = np.vstack(matrix_rows) self.matrix = _matrix(regions, matrix, self.parameters['group_boundaries'], self.parameters['sample_boundaries'], group_labels=self.parameters['group_labels'], sample_labels=self.parameters['sample_labels']) if 'sort regions' in self.parameters: self.matrix.set_sorting_method(self.parameters['sort regions'], self.parameters['sort using']) return def save_matrix(self, file_name): """ saves the data required to reconstruct the matrix the format is: A header containing the parameters used to create the matrix encoded as: @key:value\tkey2:value2 etc... The rest of the file has the same first 5 columns of a BED file: chromosome name, start, end, name, score and strand, all separated by tabs. After the fifth column the matrix values are appended separated by tabs. Groups are separated by adding a line starting with a hash (#) and followed by the group name. The file is gzipped. """ import json self.parameters['sample_labels'] = self.matrix.sample_labels self.parameters['group_labels'] = self.matrix.group_labels self.parameters['sample_boundaries'] = self.matrix.sample_boundaries self.parameters['group_boundaries'] = self.matrix.group_boundaries fh = gzip.open(file_name, 'wb') params_str = json.dumps(self.parameters, separators=(',', ':')) fh.write(toBytes("@" + params_str + "\n")) score_list = np.ma.masked_invalid(np.mean(self.matrix.matrix, axis=1)) for idx, region in enumerate(self.matrix.regions): # join np_array values # keeping nans while converting them to strings if not np.ma.is_masked(score_list[idx]): np.float(score_list[idx]) matrix_values = "\t".join( np.char.mod('%f', self.matrix.matrix[idx, :])) starts = ["{0}".format(x[0]) for x in region[1]] ends = ["{0}".format(x[1]) for x in region[1]] starts = ",".join(starts) ends = ",".join(ends) # BEDish format (we don't currently store the score) fh.write( toBytes('{0}\t{1}\t{2}\t{3}\t{4}\t{5}\t{6}\n'.format( region[0], starts, ends, region[2], region[5], region[4], matrix_values))) fh.close() def save_tabulated_values(self, file_handle, reference_point_label='TSS', start_label='TSS', end_label='TES', averagetype='mean'): """ Saves the values averaged by col using the avg_type given Args: file_handle: file name to save the file reference_point_label: Name of the reference point label start_label: Name of the star label end_label: Name of the end label averagetype: average type (e.g. mean, median, std) """ # get X labels w = self.parameters['bin size'] b = self.parameters['upstream'] a = self.parameters['downstream'] c = self.parameters.get('unscaled 5 prime', 0) d = self.parameters.get('unscaled 3 prime', 0) m = self.parameters['body'] if b < 1e5: quotient = 1000 symbol = 'Kb' else: quotient = 1e6 symbol = 'Mb' if m == 0: xticks = [(k / w) for k in [w, b, b + a]] xtickslabel = ['{0:.1f}{1}'.format(-(float(b) / quotient), symbol), reference_point_label, '{0:.1f}{1}'.format(float(a) / quotient, symbol)] else: xticks_values = [w] xtickslabel = [] # only if upstream region is set, add a x tick if b > 0: xticks_values.append(b) xtickslabel.append('{0:.1f}{1}'.format(-(float(b) / quotient), symbol)) xtickslabel.append(start_label) if c > 0: xticks_values.append(b + c) xtickslabel.append("") if d > 0: xticks_values.append(b + c + m) xtickslabel.append("") xticks_values.append(b + c + m + d) xtickslabel.append(end_label) if a > 0: xticks_values.append(b + c + m + d + a) xtickslabel.append('{0:.1f}{1}'.format(float(a) / quotient, symbol)) xticks = [(k / w) for k in xticks_values] x_axis = np.arange(xticks[-1]) + 1 labs = [] for x_value in x_axis: if x_value in xticks: labs.append(xtickslabel[xticks.index(x_value)]) else: labs.append("") with open(file_handle, 'w') as fh: # write labels fh.write("bin labels\t\t{}\n".format("\t".join(labs))) fh.write('bins\t\t{}\n'.format("\t".join([str(x) for x in x_axis]))) for sample_idx in range(self.matrix.get_num_samples()): for group_idx in range(self.matrix.get_num_groups()): sub_matrix = self.matrix.get_matrix(group_idx, sample_idx) values = [str(x) for x in np.ma.__getattribute__(averagetype)(sub_matrix['matrix'], axis=0)] fh.write("{}\t{}\t{}\n".format(sub_matrix['sample'], sub_matrix['group'], "\t".join(values))) def save_matrix_values(self, file_name): # print a header telling the group names and their length fh = open(file_name, 'wb') info = [] groups_len = np.diff(self.matrix.group_boundaries) for i in range(len(self.matrix.group_labels)): info.append("{}:{}".format(self.matrix.group_labels[i], groups_len[i])) fh.write(toBytes("#{}\n".format("\t".join(info)))) # add to header the x axis values fh.write(toBytes("#downstream:{}\tupstream:{}\tbody:{}\tbin size:{}\tunscaled 5 prime:{}\tunscaled 3 prime:{}\n".format( self.parameters['downstream'], self.parameters['upstream'], self.parameters['body'], self.parameters['bin size'], self.parameters.get('unscaled 5 prime', 0), self.parameters.get('unscaled 3 prime', 0)))) sample_len = np.diff(self.matrix.sample_boundaries) for i in range(len(self.matrix.sample_labels)): info.extend([self.matrix.sample_labels[i]] * sample_len[i]) fh.write(toBytes("{}\n".format("\t".join(info)))) fh.close() # reopen again using append mode fh = open(file_name, 'ab') np.savetxt(fh, self.matrix.matrix, fmt="%.4g", delimiter="\t") fh.close() def save_BED(self, file_handle): boundaries = np.array(self.matrix.group_boundaries) # Add a header file_handle.write("#chrom\tstart\tend\tname\tscore\tstrand\tthickStart\tthickEnd\titemRGB\tblockCount\tblockSizes\tblockStart\tdeepTools_group\n") for idx, region in enumerate(self.matrix.regions): # the label id corresponds to the last boundary # that is smaller than the region index. # for example for a boundary array = [0, 10, 20] # and labels ['a', 'b', 'c'], # for index 5, the label is 'a', for # index 10, the label is 'b' etc label_idx = np.flatnonzero(boundaries <= idx)[-1] starts = ["{0}".format(x[0]) for x in region[1]] ends = ["{0}".format(x[1]) for x in region[1]] starts = ",".join(starts) ends = ",".join(ends) file_handle.write( '{0}\t{1}\t{2}\t{3}\t{4}\t{5}\t{1}\t{2}\t0'.format( region[0], region[1][0][0], region[1][-1][1], region[2], region[5], region[4])) file_handle.write( '\t{0}\t{1}\t{2}\t{3}\n'.format( len(region[1]), ",".join([str(int(y) - int(x)) for x, y in region[1]]), ",".join([str(int(x) - int(starts[0])) for x, y in region[1]]), self.matrix.group_labels[label_idx])) file_handle.close() @staticmethod def matrix_avg(matrix, avgType='mean'): matrix = np.ma.masked_invalid(matrix) return np.ma.__getattribute__(avgType)(matrix, axis=0) def get_individual_matrices(self, matrix): """In case multiple matrices are saved one after the other this method splits them appart. Returns a list containing the matrices """ num_cols = matrix.shape[1] num_ind_cols = self.get_num_individual_matrix_cols() matrices_list = [] for i in range(0, num_cols, num_ind_cols): if i + num_ind_cols > num_cols: break matrices_list.append(matrix[:, i:i + num_ind_cols]) return matrices_list def get_num_individual_matrix_cols(self): """ returns the number of columns that each matrix should have. This is done because the final matrix that is plotted can be composed of smaller matrices that are merged one after the other. """ matrixCols = ((self.parameters['downstream'] + self.parameters['upstream'] + self.parameters['body'] + self.parameters['unscaled 5 prime'] + self.parameters['unscaled 3 prime']) // self.parameters['bin size']) return matrixCols class _matrix(object): """ class to hold heatmapper matrices The base data is a large matrix with definition to know the boundaries for row and col divisions. Col divisions represent groups within a subset, e.g. Active and inactive from PolII bigwig data. Row division represent different samples, for example PolII in males vs. PolII in females. This is an internal class of the heatmapper class """ def __init__(self, regions, matrix, group_boundaries, sample_boundaries, group_labels=None, sample_labels=None): # simple checks assert matrix.shape[0] == group_boundaries[-1], \ "row max do not match matrix shape" assert matrix.shape[1] == sample_boundaries[-1], \ "col max do not match matrix shape" self.regions = regions self.matrix = matrix self.group_boundaries = group_boundaries self.sample_boundaries = sample_boundaries self.sort_method = None self.sort_using = None if group_labels is None: self.group_labels = ['group {}'.format(x) for x in range(len(group_boundaries) - 1)] else: assert len(group_labels) == len(group_boundaries) - 1, \ "number of group labels does not match number of groups" self.group_labels = group_labels if sample_labels is None: self.sample_labels = ['sample {}'.format(x) for x in range(len(sample_boundaries) - 1)] else: assert len(sample_labels) == len(sample_boundaries) - 1, \ "number of sample labels does not match number of samples" self.sample_labels = sample_labels def get_matrix(self, group, sample): """ Returns a sub matrix from the large matrix. Group and sample are ids, thus, row = 0, col=0 get the first group of the first sample. Returns ------- dictionary containing the matrix, the group label and the sample label """ group_start = self.group_boundaries[group] group_end = self.group_boundaries[group + 1] sample_start = self.sample_boundaries[sample] sample_end = self.sample_boundaries[sample + 1] return {'matrix': np.ma.masked_invalid(self.matrix[group_start:group_end, :][:, sample_start:sample_end]), 'group': self.group_labels[group], 'sample': self.sample_labels[sample]} def get_num_samples(self): return len(self.sample_labels) def get_num_groups(self): return len(self.group_labels) def set_group_labels(self, new_labels): """ sets new labels for groups """ if len(new_labels) != len(self.group_labels): raise ValueError("length new labels != length original labels") self.group_labels = new_labels def set_sample_labels(self, new_labels): """ sets new labels for groups """ if len(new_labels) != len(self.sample_labels): raise ValueError("length new labels != length original labels") self.sample_labels = new_labels def set_sorting_method(self, sort_method, sort_using): self.sort_method = sort_method self.sort_using = sort_using def get_regions(self): """Returns the regions per group Returns ------ list Each element of the list is itself a list of dictionaries containing the regions info: chrom, start, end, strand, name etc. Each element of the list corresponds to each of the groups """ regions = [] for idx in range(len(self.group_labels)): start = self.group_boundaries[idx] end = self.group_boundaries[idx + 1] regions.append(self.regions[start:end]) return regions def sort_groups(self, sort_using='mean', sort_method='no', sample_list=None): """ Sorts and rearranges the submatrices according to the sorting method given. """ if sort_method == 'no': return if (sample_list is not None) and (len(sample_list) > 0): # get the ids that correspond to the selected sample list idx_to_keep = [] for sample_idx in sample_list: idx_to_keep += range(self.sample_boundaries[sample_idx], self.sample_boundaries[sample_idx + 1]) matrix = self.matrix[:, idx_to_keep] else: matrix = self.matrix # compute the row average: if sort_using == 'region_length': matrix_avgs = list() for x in self.regions: matrix_avgs.append(np.sum([bar[1] - bar[0] for bar in x[1]])) matrix_avgs = np.array(matrix_avgs) elif sort_using == 'mean': matrix_avgs = np.nanmean(matrix, axis=1) elif sort_using == 'mean': matrix_avgs = np.nanmean(matrix, axis=1) elif sort_using == 'median': matrix_avgs = np.nanmedian(matrix, axis=1) elif sort_using == 'max': matrix_avgs = np.nanmax(matrix, axis=1) elif sort_using == 'min': matrix_avgs = np.nanmin(matrix, axis=1) elif sort_using == 'sum': matrix_avgs = np.nansum(matrix, axis=1) else: sys.exit("{} is an unsupported sorting method".format(sort_using)) # order per group _sorted_regions = [] _sorted_matrix = [] for idx in range(len(self.group_labels)): start = self.group_boundaries[idx] end = self.group_boundaries[idx + 1] order = matrix_avgs[start:end].argsort() if sort_method == 'descend': order = order[::-1] _sorted_matrix.append(self.matrix[start:end, :][order, :]) # sort the regions _reg = self.regions[start:end] for idx in order: _sorted_regions.append(_reg[idx]) self.matrix = np.vstack(_sorted_matrix) self.regions = _sorted_regions self.set_sorting_method(sort_method, sort_using) def hmcluster(self, k, method='kmeans'): matrix = np.asarray(self.matrix) if np.any(np.isnan(matrix)): # replace nans for 0 otherwise kmeans produces a weird behaviour sys.stderr.write("*Warning* For clustering nan values have to be replaced by zeros \n") matrix[np.isnan(matrix)] = 0 if method == 'kmeans': from scipy.cluster.vq import vq, kmeans centroids, _ = kmeans(matrix, k) # order the centroids in an attempt to # get the same cluster order cluster_labels, _ = vq(matrix, centroids) if method == 'hierarchical': # normally too slow for large data sets from scipy.cluster.hierarchy import fcluster, linkage Z = linkage(matrix, method='ward', metric='euclidean') cluster_labels = fcluster(Z, k, criterion='maxclust') # hierarchical clustering labels from 1 .. k # while k-means labels 0 .. k -1 # Thus, for consistency, we subtract 1 cluster_labels -= 1 # sort clusters _clustered_mean = [] _cluster_ids_list = [] for cluster in range(k): cluster_ids = np.flatnonzero(cluster_labels == cluster) _cluster_ids_list.append(cluster_ids) _clustered_mean.append(self.matrix[cluster_ids, :].mean()) # reorder clusters based on mean cluster_order = np.argsort(_clustered_mean)[::-1] # create groups using the clustering self.group_labels = [] self.group_boundaries = [0] _clustered_regions = [] _clustered_matrix = [] cluster_number = 1 for cluster in cluster_order: self.group_labels.append("cluster_{}".format(cluster_number)) cluster_number += 1 cluster_ids = _cluster_ids_list[cluster] self.group_boundaries.append(self.group_boundaries[-1] + len(cluster_ids)) _clustered_matrix.append(self.matrix[cluster_ids, :]) for idx in cluster_ids: _clustered_regions.append(self.regions[idx]) self.regions = _clustered_regions self.matrix = np.vstack(_clustered_matrix) return idx def removeempty(self): """ removes matrix rows containing only zeros or nans """ to_keep = [] score_list = np.ma.masked_invalid(np.mean(self.matrix, axis=1)) for idx, region in enumerate(self.regions): if np.ma.is_masked(score_list[idx]) or np.float(score_list[idx]) == 0: continue else: to_keep.append(idx) self.regions = [self.regions[x] for x in to_keep] self.matrix = self.matrix[to_keep, :] # adjust sample boundaries to_keep = np.array(to_keep) self.group_boundaries = [len(to_keep[to_keep < x]) for x in self.group_boundaries] def flatten(self): """ flatten and remove nans from matrix. Useful to get max and mins from matrix. :return flattened matrix """ matrix_flatten = np.asarray(self.matrix.flatten()) # nans are removed from the flattened array matrix_flatten = matrix_flatten[~np.isnan(matrix_flatten)] if len(matrix_flatten) == 0: num_nan = len(np.flatnonzero(np.isnan(self.matrix.flatten()))) raise ValueError("matrix only contains nans " "(total nans: {})".format(num_nan)) return matrix_flatten deepTools-2.5.0/deeptools/heatmapper_utilities.py0000640000201600010240000001150413036110101021372 0ustar ryanbioinfoimport numpy as np import matplotlib matplotlib.use('Agg') matplotlib.rcParams['pdf.fonttype'] = 42 matplotlib.rcParams['svg.fonttype'] = 'none' import matplotlib.colors as pltcolors old_settings = np.seterr(all='ignore') def plot_single(ax, ma, average_type, color, label, plot_type='simple'): """ Adds a line to the plot in the given ax using the specified method Parameters ---------- ax : matplotlib axis matplotlib axis ma : numpy array numpy array The data on this matrix is summarized according to the `average_type` argument. average_type : str string values are sum mean median min max std color : str a valid color: either a html color name, hex (e.g #002233), RGB + alpha tuple or list or RGB tuple or list label : str label plot_type: str type of plot. Either 'se' for standard error, 'std' for standard deviation, 'overlapped_lines' to plot each line of the matrix, fill to plot the area between the x axis and the value or None, just to plot the average line. Returns ------- ax matplotlib axis Examples -------- >>> import matplotlib.pyplot as plt >>> import os >>> fig = plt.figure() >>> ax = fig.add_subplot(111) >>> matrix = np.array([[1,2,3], ... [4,5,6], ... [7,8,9]]) >>> ax = plot_single(ax, matrix -2, 'mean', color=[0.6, 0.8, 0.9], label='fill light blue', plot_type='fill') >>> ax = plot_single(ax, matrix, 'mean', color='blue', label='red') >>> ax = plot_single(ax, matrix + 5, 'mean', color='red', label='red', plot_type='std') >>> ax = plot_single(ax, matrix + 10, 'mean', color='#cccccc', label='gray se', plot_type='se') >>> ax = plot_single(ax, matrix + 20, 'mean', color=(0.9, 0.5, 0.9), label='violet', plot_type='std') >>> ax = plot_single(ax, matrix + 30, 'mean', color=(0.9, 0.5, 0.9, 0.5), label='violet with alpha', plot_type='std') >>> leg = ax.legend() >>> plt.savefig("/tmp/test.pdf") >>> plt.close() >>> fig = plt.figure() >>> os.remove("/tmp/test.pdf") """ summary = np.ma.__getattribute__(average_type)(ma, axis=0) # only plot the average profiles without error regions x = np.arange(len(summary)) ax.plot(x, summary, color=color, label=label, alpha=0.9) if plot_type == 'fill': pass ax.fill_between(x, summary, facecolor=color, alpha=0.6, edgecolor='none') if plot_type in ['se', 'std']: if plot_type == 'se': # standard error std = np.std(ma, axis=0) / np.sqrt(ma.shape[0]) else: std = np.std(ma, axis=0) alpha = 0.2 # an alpha channel has to be added to the color to fill the area # between the mean (or median etc.) and the std or se f_color = pltcolors.colorConverter.to_rgba(color, alpha) ax.fill_between(x, summary, summary + std, facecolor=f_color, edgecolor='none') ax.fill_between(x, summary, summary - std, facecolor=f_color, edgecolor='none') ax.set_xlim(0, max(x)) return ax def getProfileTicks(hm, referencePointLabel, startLabel, endLabel): """ returns the position and labelling of the xticks that correspond to the heatmap """ w = hm.parameters['bin size'] b = hm.parameters['upstream'] a = hm.parameters['downstream'] try: c = hm.parameters['unscaled 5 prime'] except: c = 0 try: d = hm.parameters['unscaled 3 prime'] except: d = 0 m = hm.parameters['body'] tickPlotAdj = 0.5 if b < 1e5: quotient = 1000 symbol = 'Kb' else: quotient = 1e6 symbol = 'Mb' if m == 0: xticks = [(k / w) - tickPlotAdj for k in [0, b, b + a]] xtickslabel = ['{0:.1f}'.format(-(float(b) / quotient)), referencePointLabel, '{0:.1f}{1}'.format(float(a) / quotient, symbol)] else: xticks_values = [0] xtickslabel = [] # only if upstream region is set, add a x tick if b > 0: xticks_values.append(b) xtickslabel.append('{0:.1f}'.format(-(float(b) / quotient))) xtickslabel.append(startLabel) # set the x tick for the body parameter, regardless if # upstream is 0 (not set) if c > 0: xticks_values.append(b + c) xtickslabel.append("") if d > 0: xticks_values.append(b + c + m) xtickslabel.append("") xticks_values.append(b + c + m + d) xtickslabel.append(endLabel) if a > 0: xticks_values.append(b + c + m + d + a) xtickslabel.append('{0:.1f}{1}'.format(float(a) / quotient, symbol)) xticks = [(k / w) - tickPlotAdj for k in xticks_values] return xticks, xtickslabel deepTools-2.5.0/deeptools/mapReduce.py0000640000201600010240000002302113061740003017063 0ustar ryanbioinfoimport multiprocessing from deeptoolsintervals import GTF import random debug = 0 def mapReduce(staticArgs, func, chromSize, genomeChunkLength=None, region=None, bedFile=None, blackListFileName=None, numberOfProcessors=4, verbose=False, includeLabels=False, keepExons=False, transcriptID="transcriptID", exonID="exonID", transcript_id_designator="transcript_id", self_=None): """ Split the genome into parts that are sent to workers using a defined number of procesors. Results are collected and returned. For each genomic region the given 'func' is called using the following parameters: chrom, start, end, staticArgs The *arg* are static, *pickable* variables that need to be sent to workers. The genome chunk length corresponds to a fraction of the genome, in bp, that is send to each of the workers for processing. Depending on the type of process a larger or shorter regions may be preferred :param chromSize: A list of duples containing the chromosome name and its length :param region: The format is chr:start:end:tileSize (see function getUserRegion) :param staticArgs: tuple of arguments that are sent to the given 'func' :param func: function to call. The function is called using the following parameters (chrom, start, end, staticArgs) :param bedFile: Is a bed file is given, the args to the func to be called are extended to include a list of bed defined regions. :param blackListFileName: A list of regions to exclude from all computations. Note that this has genomeChunkLength resolution... :param self_: In case mapreduce should make a call to an object the self variable has to be passed. :param includeLabels: Pass group and transcript labels into the calling function. These are added to the static args (groupLabel and transcriptName). If "includeLabels" is true, a tuple of (results, labels) is returned """ if not genomeChunkLength: genomeChunkLength = 1e5 genomeChunkLength = int(genomeChunkLength) if verbose: print("genome partition size for multiprocessing: {0}".format( genomeChunkLength)) region_start = 0 region_end = None # if a region is set, that means that the task should only cover # the given genomic position if region: chromSize, region_start, region_end, genomeChunkLength = getUserRegion(chromSize, region) if verbose: print("chrom size: {0}, region start: {1}, region end: {2}, " "genome chunk length sent to each procesor: {3}".format(chromSize, region_start, region_end, genomeChunkLength)) if bedFile: defaultGroup = None if len(bedFile) == 1: defaultGroup = "genes" bed_interval_tree = GTF(bedFile, defaultGroup=defaultGroup, transcriptID=transcriptID, exonID=exonID, transcript_id_designator=transcript_id_designator, keepExons=keepExons) if blackListFileName: blackList = GTF(blackListFileName) TASKS = [] # iterate over all chromosomes for chrom, size in chromSize: # the start is zero unless a specific region is defined start = 0 if region_start == 0 else region_start for startPos in range(start, size, genomeChunkLength): endPos = min(size, startPos + genomeChunkLength) # Reject a chunk if it overlaps if blackListFileName: regions = blSubtract(blackList, chrom, [startPos, endPos]) else: regions = [[startPos, endPos]] for reg in regions: if self_ is not None: argsList = [self_] else: argsList = [] argsList.extend([chrom, reg[0], reg[1]]) # add to argument list the static list received the the function argsList.extend(staticArgs) # if a bed file is given, append to the TASK list, # a list of bed regions that overlap with the # current genomeChunk. if bedFile: # This effectively creates batches of intervals, which is # generally more performant due to the added overhead of # initializing additional workers. # TODO, there's no point in including the chromosome if includeLabels: bed_regions_list = [[chrom, x[4], x[2], x[3], x[5], x[6]] for x in bed_interval_tree.findOverlaps(chrom, reg[0], reg[1], trimOverlap=True, numericGroups=True, includeStrand=True)] else: bed_regions_list = [[chrom, x[4], x[5], x[6]] for x in bed_interval_tree.findOverlaps(chrom, reg[0], reg[1], trimOverlap=True, includeStrand=True)] if len(bed_regions_list) == 0: continue # add to argument list, the position of the bed regions to use argsList.append(bed_regions_list) TASKS.append(tuple(argsList)) if len(TASKS) > 1 and numberOfProcessors > 1: if verbose: print(("using {} processors for {} " "number of tasks".format(numberOfProcessors, len(TASKS)))) random.shuffle(TASKS) pool = multiprocessing.Pool(numberOfProcessors) res = pool.map_async(func, TASKS).get(9999999) else: res = list(map(func, TASKS)) if includeLabels: if bedFile: return res, bed_interval_tree.labels else: return res, None return res def getUserRegion(chrom_sizes, region_string, max_chunk_size=1e6): r""" Verifies if a given region argument, given by the user is valid. The format of the region_string is chrom:start:end:tileSize where start, end and tileSize are optional. :param chrom_sizes: dictionary of chromosome/scaffold size. Key=chromosome name :param region_string: a string of the form chr:start:end :param max_chunk_size: upper limit for the chunk size :return: tuple chrom_size for the region start, region end, chunk size #>>> data = getUserRegion({'chr2': 1000}, "chr1:10:10") #Traceback (most recent call last): # ... #NameError: Unknown chromosome: chr1 #Known chromosomes are: ['chr2'] If the region end is biger than the chromosome size, this value is used instead >>> getUserRegion({'chr2': 1000}, "chr2:10:1001") ([('chr2', 1000)], 10, 1000, 990) Test chunk and regions size reduction to match tile size >>> getUserRegion({'chr2': 200000}, "chr2:10:123344:3") ([('chr2', 123344)], 9, 123345, 123336) Test chromosome name mismatch >>> getUserRegion({'2': 200000}, "chr2:10:123344:3") ([('2', 123344)], 9, 123345, 123336) >>> getUserRegion({'chrM': 200000}, "MT:10:123344:3") ([('chrM', 123344)], 9, 123345, 123336) """ region = region_string.split(":") chrom = region[0] chrom_sizes = dict(chrom_sizes) if chrom not in list(chrom_sizes.keys()): if chrom == "MT": chromUse = "chrM" elif chrom == "chrM": chromUse = "MT" elif chrom[0:3] == "chr": chromUse = chrom[3:] else: chromUse = "chr" + chrom if chromUse not in list(chrom_sizes.keys()): raise NameError("Unknown chromosome: %s\nKnown " "chromosomes are: %s " % (chrom, list(chrom_sizes.keys()))) chrom = chromUse try: region_start = int(region[1]) except IndexError: region_start = 0 try: region_end = int(region[2]) if int(region[2]) <= chrom_sizes[chrom] \ else chrom_sizes[chrom] except IndexError: region_end = chrom_sizes[chrom] if region_start > region_end or region_start < 0: raise NameError("{} not valid. The format is chrom:start:end. " "Without comas, dashes or dots. ".format(region_string)) try: tilesize = int(region[3]) except IndexError: tilesize = None chrom_sizes = [(chrom, region_end)] # if tilesize is given, make region_start and region_end # multiple of tileSize if tilesize: region_start -= region_start % tilesize region_end += tilesize - (region_end % tilesize) chunk_size = int(region_end - region_start) if chunk_size > max_chunk_size: chunk_size = max_chunk_size if tilesize and tilesize < chunk_size: chunk_size -= chunk_size % tilesize return chrom_sizes, region_start, region_end, int(chunk_size) def blSubtract(t, chrom, chunk): """ If a genomic region overlaps with a blacklisted region, then subtract that region out returns a list of lists """ if t is None: return [chunk] overlaps = t.findOverlaps(chrom, chunk[0], chunk[1]) if overlaps is not None and len(overlaps) > 0: output = [] for o in overlaps: if chunk[1] <= chunk[0]: break if chunk[0] < o[0]: output.append([chunk[0], o[0]]) chunk[0] = o[1] if chunk[0] < chunk[1]: output.append([chunk[0], chunk[1]]) else: output = [chunk] return output deepTools-2.5.0/deeptools/multiBamSummary.py0000640000201600010240000002307113003652723020322 0ustar ryanbioinfo#!/usr/bin/env python # -*- coding: utf-8 -*- import os import sys import argparse import numpy as np import deeptools.countReadsPerBin as countR from deeptools import parserCommon from deeptools._version import __version__ old_settings = np.seterr(all='ignore') def parse_arguments(args=None): parser = \ argparse.ArgumentParser( formatter_class=argparse.RawDescriptionHelpFormatter, description=""" ``multiBamSummary`` computes the read coverages for genomic regions for typically two or more BAM files. The analysis can be performed for the entire genome by running the program in 'bins' mode. If you want to count the read coverage for specific regions only, use the ``BED-file`` mode instead. The standard output of ``multiBamSummary`` is a compressed numpy array (``.npz``). It can be directly used to calculate and visualize pairwise correlation values between the read coverages using the tool 'plotCorrelation'. Similarly, ``plotPCA`` can be used for principal component analysis of the read coverages using the .npz file. Note that using a single bigWig file is only recommended if you want to produce a bedGraph file (i.e., with the ``--outRawCounts`` option; the default output file cannot be used by ANY deepTools program if only a single file was supplied!). A detailed sub-commands help is available by typing: multiBamSummary bins -h multiBamSummary BED-file -h """, epilog='example usages:\n' 'multiBamSummary bins --bamfiles file1.bam file2.bam -out results.npz \n\n' 'multiBamSummary BED-file --BED selection.bed --bamfiles file1.bam file2.bam \n' '-out results.npz' ' \n\n', conflict_handler='resolve') parser.add_argument('--version', action='version', version='%(prog)s {}'.format(__version__)) subparsers = parser.add_subparsers( title="commands", dest='command', description='subcommands', help='subcommands', metavar='') parent_parser = parserCommon.getParentArgParse(binSize=False) read_options_parser = parserCommon.read_options() # bins mode options subparsers.add_parser( 'bins', formatter_class=argparse.ArgumentDefaultsHelpFormatter, parents=[bamcorrelate_args(case='bins'), parent_parser, read_options_parser, parserCommon.gtf_options(suppress=True) ], help="The coverage calculation is done for consecutive bins of equal " "size (10 kilobases by default). This mode is useful to assess the " "genome-wide similarity of BAM files. The bin size and " "distance between bins can be adjusted.", add_help=False, usage='%(prog)s ' '--bamfiles file1.bam file2.bam ' '-out results.npz \n') # BED file arguments subparsers.add_parser( 'BED-file', formatter_class=argparse.ArgumentDefaultsHelpFormatter, parents=[bamcorrelate_args(case='BED-file'), parent_parser, read_options_parser, parserCommon.gtf_options() ], help="The user provides a BED file that contains all regions " "that should be considered for the coverage analysis. A " "common use is to compare ChIP-seq coverages between two " "different samples for a set of peak regions.", usage='%(prog)s --BED selection.bed --bamfiles file1.bam file2.bam -out results.npz\n', add_help=False) return parser def bamcorrelate_args(case='bins'): parser = argparse.ArgumentParser(add_help=False) required = parser.add_argument_group('Required arguments') # define the arguments required.add_argument('--bamfiles', '-b', metavar='FILE1 FILE2', help='List of indexed bam files separated by spaces.', nargs='+', required=True) required.add_argument('--outFileName', '-out', help='File name to save the coverage matrix. This matrix ' 'can be subsequently plotted using plotCorrelation or ' 'or plotPCA.', required=True) optional = parser.add_argument_group('Optional arguments') optional.add_argument("--help", "-h", action="help", help="show this help message and exit") optional.add_argument('--labels', '-l', metavar='sample1 sample2', help='User defined labels instead of default labels from ' 'file names. ' 'Multiple labels have to be separated by a space, e.g. ' '--labels sample1 sample2 sample3', nargs='+') if case == 'bins': optional.add_argument('--binSize', '-bs', metavar='INT', help='Length in bases of the window used ' 'to sample the genome.', default=10000, type=int) optional.add_argument('--distanceBetweenBins', '-n', metavar='INT', help='By default, multiBamSummary considers consecutive ' 'bins of the specified --binSize. However, to ' 'reduce the computation time, a larger distance ' 'between bins can by given. Larger distances ' 'result in fewer bins considered.', default=0, type=int) required.add_argument('--BED', help=argparse.SUPPRESS, default=None) else: optional.add_argument('--binSize', '-bs', help=argparse.SUPPRESS, default=10000, type=int) optional.add_argument('--distanceBetweenBins', '-n', help=argparse.SUPPRESS, metavar='INT', default=0, type=int) required.add_argument('--BED', help='Limits the coverage analysis to ' 'the regions specified in these files.', metavar='FILE1.bed FILE2.bed', nargs='+', required=True) group = parser.add_argument_group('Output optional options') group.add_argument('--outRawCounts', help='Save the counts per region to a tab-delimited file.', metavar='FILE') return parser def process_args(args=None): args = parse_arguments().parse_args(args) if args.labels and len(args.bamfiles) != len(args.labels): print("The number of does not match the number of bam files.") exit(0) if not args.labels: args.labels = [os.path.basename(x) for x in args.bamfiles] return args def main(args=None): """ 1. get read counts at different positions either all of same length or from genomic regions from the BED file 2. save data for further plotting """ args = process_args(args) if 'BED' in args: bed_regions = args.BED else: bed_regions = None if len(args.bamfiles) == 1 and not args.outRawCounts: sys.stderr.write("You've input a single BAM file and not specified " "--outRawCounts. The resulting output will NOT be " "useful with any deepTools program!\n") stepsize = args.binSize + args.distanceBetweenBins c = countR.CountReadsPerBin( args.bamfiles, args.binSize, numberOfSamples=None, numberOfProcessors=args.numberOfProcessors, verbose=args.verbose, region=args.region, bedFile=bed_regions, blackListFileName=args.blackListFileName, extendReads=args.extendReads, minMappingQuality=args.minMappingQuality, ignoreDuplicates=args.ignoreDuplicates, center_read=args.centerReads, samFlag_include=args.samFlagInclude, samFlag_exclude=args.samFlagExclude, minFragmentLength=args.minFragmentLength, maxFragmentLength=args.maxFragmentLength, stepSize=stepsize, zerosToNans=False, out_file_for_raw_data=args.outRawCounts) num_reads_per_bin = c.run(allArgs=args) sys.stderr.write("Number of bins " "found: {}\n".format(num_reads_per_bin.shape[0])) if num_reads_per_bin.shape[0] < 2: exit("ERROR: too few non zero bins found.\n" "If using --region please check that this " "region is covered by reads.\n") # numpy will append .npz to the file name if we don't do this... f = open(args.outFileName, "wb") np.savez_compressed(f, matrix=num_reads_per_bin, labels=args.labels) f.close() if args.outRawCounts: # append to the generated file the # labels header = "#'chr'\t'start'\t'end'\t" header += "'" + "'\t'".join(args.labels) + "'\n" f = open(args.outRawCounts, 'r+') content = f.read() f.seek(0, 0) f.write(header + content) f.close() if __name__ == "__main__": main() deepTools-2.5.0/deeptools/multiBigwigSummary.py0000640000201600010240000002743613006372703021044 0ustar ryanbioinfo#!/usr/bin/env python # -*- coding: utf-8 -*- import sys import argparse import os.path import numpy as np import multiprocessing from deeptools import parserCommon from deeptools._version import __version__ import deeptools.getScorePerBigWigBin as score_bw import deeptools.deepBlue as db old_settings = np.seterr(all='ignore') def parse_arguments(args=None): parser = \ argparse.ArgumentParser( formatter_class=argparse.RawDescriptionHelpFormatter, description=""" Given typically two or more bigWig files, ``multiBigwigSummary`` computes the average scores for each of the files in every genomic region. This analysis is performed for the entire genome by running the program in ``bins`` mode, or for certain user selected regions in ``BED-file`` mode. Most commonly, the default output of ``multiBigwigSummary`` (a compressed numpy array, .npz) is used by other tools such as ``plotCorrelation`` or ``plotPCA`` for visualization and diagnostic purposes. Note that using a single bigWig file is only recommended if you want to produce a bedGraph file (i.e., with the ``--outRawCounts`` option; the default output file cannot be used by ANY deepTools program if only a single file was supplied!). A detailed sub-commands help is available by typing: multiBigwigSummary bins -h multiBigwigSummary BED-file -h """, epilog='example usage:\n multiBigwigSummary bins ' '-b file1.bw file2.bw -out results.npz\n\n' 'multiBigwigSummary BED-file -b file1.bw file2.bw -out results.npz\n' '--BED selection.bed' ' \n\n', conflict_handler='resolve') parser.add_argument('--version', action='version', version='multiBigwigSummary {}'.format(__version__)) subparsers = parser.add_subparsers( title="commands", dest='command', metavar='') parent_parser = parserCommon.getParentArgParse(binSize=False) dbParser = parserCommon.deepBlueOptionalArgs() # bins mode options subparsers.add_parser( 'bins', formatter_class=argparse.ArgumentDefaultsHelpFormatter, parents=[multiBigwigSummaryArgs(case='bins'), parent_parser, parserCommon.gtf_options(suppress=True), dbParser ], help="The average score is based on equally sized bins " "(10 kilobases by default), which consecutively cover the " "entire genome. The only exception is the last bin of a chromosome, which " "is often smaller. The output of this mode is commonly used to assess the " "overall similarity of different bigWig files.", add_help=False, usage='multiBigwigSummary ' '-b file1.bw file2.bw ' '-out results.npz\n') # BED file arguments subparsers.add_parser( 'BED-file', formatter_class=argparse.ArgumentDefaultsHelpFormatter, parents=[multiBigwigSummaryArgs(case='BED-file'), parent_parser, parserCommon.gtf_options(), dbParser ], help="The user provides a BED file that contains all regions " "that should be considered for the analysis. A " "common use is to compare scores (e.g. ChIP-seq scores) between " "different samples over a set of pre-defined peak regions.", usage='multiBigwigSummary ' '-b file1.bw file2.bw ' '-out results.npz --BED selection.bed\n', add_help=False) return parser def process_args(args=None): args = parse_arguments().parse_args(args) if args.labels and len(args.bwfiles) != len(args.labels): print("The number of labels does not match the number of bigWig files.") exit(0) if not args.labels: args.labels = [] for f in args.bwfiles: if f.startswith("http://") or f.startswith("https://") or f.startswith("ftp://"): args.labels.append(f.split("/")[-1]) else: args.labels.append(os.path.basename(f)) return args def multiBigwigSummaryArgs(case='bins'): parser = argparse.ArgumentParser(add_help=False) required = parser.add_argument_group('Required arguments') # define the arguments required.add_argument('--bwfiles', '-b', metavar='FILE1 FILE2', help='List of bigWig files, separated by spaces.', nargs='+', required=True) required.add_argument('--outFileName', '-out', help='File name to save the compressed matrix file (npz format)' 'needed by the "plotHeatmap" and "plotProfile" tools.', required=True) optional = parser.add_argument_group('Optional arguments') optional.add_argument("--help", "-h", action="help", help="show this help message and exit") optional.add_argument('--labels', '-l', metavar='sample1 sample2', help='User defined labels instead of default labels from ' 'file names. ' 'Multiple labels have to be separated by spaces, e.g., ' '--labels sample1 sample2 sample3', nargs='+') optional.add_argument('--chromosomesToSkip', metavar='chr1 chr2', help='List of chromosomes that you do not want to be included. ' ' Useful to remove "random" or "extra" chr.', nargs='+') if case == 'bins': optional.add_argument('--binSize', '-bs', metavar='INT', help='Size (in bases) of the windows sampled ' 'from the genome.', default=10000, type=int) optional.add_argument('--distanceBetweenBins', '-n', metavar='INT', help='By default, multiBigwigSummary considers adjacent ' 'bins of the specified --binSize. However, to ' 'reduce the computation time, a larger distance ' 'between bins can be given. Larger distances ' 'results in fewer considered bins.', default=0, type=int) required.add_argument('--BED', help=argparse.SUPPRESS, default=None) else: optional.add_argument('--binSize', '-bs', help=argparse.SUPPRESS, default=10000, type=int) optional.add_argument('--distanceBetweenBins', '-n', help=argparse.SUPPRESS, metavar='INT', default=0, type=int) required.add_argument('--BED', help='Limits the analysis to ' 'the regions specified in this file.', metavar='file1.bed file2.bed', nargs='+', required=True) group = parser.add_argument_group('Output optional options') group.add_argument('--outRawCounts', help='Save average scores per region for each bigWig file to a single tab-delimited file.', metavar='FILE') return parser def main(args=None): """ 1. get read counts at different positions either all of same length or from genomic regions from the BED file 2. compute the scores """ args = process_args(args) if 'BED' in args: bed_regions = args.BED else: bed_regions = None if len(args.bwfiles) == 1 and not args.outRawCounts: sys.stderr.write("You've input a single bigWig file and not specified " "--outRawCounts. The resulting output will NOT be " "useful with any deepTools program!\n") # Preload deepBlue files, which need to then be deleted deepBlueFiles = [] for idx, fname in enumerate(args.bwfiles): if db.isDeepBlue(fname): deepBlueFiles.append([fname, idx]) if len(deepBlueFiles) > 0: sys.stderr.write("Preloading the following deepBlue files: {}\n".format(",".join([x[0] for x in deepBlueFiles]))) if 'BED' in args: regs = db.makeRegions(args.BED, args) else: foo = db.deepBlue(deepBlueFiles[0][0], url=args.deepBlueURL, userKey=args.userKey) regs = db.makeTiles(foo, args) del foo for x in deepBlueFiles: x.extend([args, regs]) if len(deepBlueFiles) > 1 and args.numberOfProcessors > 1: pool = multiprocessing.Pool(args.numberOfProcessors) res = pool.map_async(db.preloadWrapper, deepBlueFiles).get(9999999) else: res = list(map(db.preloadWrapper, deepBlueFiles)) # substitute the file names with the temp files for (ftuple, r) in zip(deepBlueFiles, res): args.bwfiles[ftuple[1]] = r deepBlueFiles = [[x[0], x[1]] for x in deepBlueFiles] del regs num_reads_per_bin = score_bw.getScorePerBin( args.bwfiles, args.binSize, blackListFileName=args.blackListFileName, numberOfProcessors=args.numberOfProcessors, stepSize=args.binSize + args.distanceBetweenBins, verbose=args.verbose, region=args.region, bedFile=bed_regions, chrsToSkip=args.chromosomesToSkip, out_file_for_raw_data=args.outRawCounts, allArgs=args) sys.stderr.write("Number of bins " "found: {}\n".format(num_reads_per_bin.shape[0])) if num_reads_per_bin.shape[0] < 2: exit("ERROR: too few non zero bins found.\n" "If using --region please check that this " "region is covered by reads.\n") f = open(args.outFileName, "wb") np.savez_compressed(f, matrix=num_reads_per_bin, labels=args.labels) f.close() if args.outRawCounts: # append to the generated file the # labels header = "#'chr'\t'start'\t'end'\t" header += "'" + "'\t'".join(args.labels) + "'\n" f = open(args.outRawCounts, "r+") content = f.read() f.seek(0, 0) f.write(header + content) """ if bed_regions: bed_regions.seek(0) reg_list = bed_regions.readlines() args.outRawCounts.write("#'chr'\t'start'\t'end'\t") args.outRawCounts.write("'" + "'\t'".join(args.labels) + "'\n") fmt = "\t".join(np.repeat('%s', num_reads_per_bin.shape[1])) + "\n" for idx, row in enumerate(num_reads_per_bin): args.outRawCounts.write("{}\t{}\t{}\t".format(*reg_list[idx].strip().split("\t")[0:3])) args.outRawCounts.write(fmt % tuple(row)) else: args.outRawCounts.write("'" + "'\t'".join(args.labels) + "'\n") fmt = "\t".join(np.repeat('{}', num_reads_per_bin.shape[1])) + "\n" for row in num_reads_per_bin: args.outRawCounts.write(fmt.format(*tuple(row))) """ f.close() # Clean up temporary bigWig files, if applicable if not args.deepBlueKeepTemp: for k, v in deepBlueFiles: os.remove(args.bwfiles[v]) else: for k, v in deepBlueFiles: print("{} is stored in {}".format(k, args.bwfiles[v])) deepTools-2.5.0/deeptools/parserCommon.py0000640000201600010240000011401113067414642017640 0ustar ryanbioinfoimport argparse import deeptools.config as cfg import os from deeptools._version import __version__ def check_float_0_1(value): v = float(value) if v < 0.0 or v > 1.0: raise argparse.ArgumentTypeError("%s is an invalid floating point value. It must be between 0.0 and 1.0" % value) return v def check_list_of_comma_values(value): if value is None: return None for foo in value: foo = value.split(",") if len(foo) < 2: raise argparse.ArgumentTypeError("%s is an invalid element of a list of comma separated values. Only argument elements of the following form are accepted: 'foo,bar'" % foo) return value def output(args=None): parser = argparse.ArgumentParser(add_help=False) group = parser.add_argument_group('Output') group.add_argument('--outFileName', '-o', help='Output file name.', metavar='FILENAME', type=writableFile, required=True) group.add_argument('--outFileFormat', '-of', help='Output file type. Either "bigwig" or "bedgraph".', choices=['bigwig', 'bedgraph'], default='bigwig') return parser def read_options(): """Common arguments related to BAM files and the interpretation of the read coverage """ parser = argparse.ArgumentParser(add_help=False) group = parser.add_argument_group('Read processing options') group.add_argument('--extendReads', '-e', help='This parameter allows the extension of reads to ' 'fragment size. If set, each read is ' 'extended, without exception.\n' '*NOTE*: This feature is generally NOT recommended for ' 'spliced-read data, such as RNA-seq, as it would ' 'extend reads over skipped regions.\n' '*Single-end*: Requires a user specified value for the ' 'final fragment length. Reads that already exceed this ' 'fragment length will not be extended.\n' '*Paired-end*: Reads with mates are always extended to ' 'match the fragment size defined by the two read mates. ' 'Unmated reads, mate reads that map too far apart ' '(>4x fragment length) or even map to different ' 'chromosomes are treated like single-end reads. The input ' 'of a fragment length value is optional. If ' 'no value is specified, it is estimated from the ' 'data (mean of the fragment size of all mate reads).\n', type=int, nargs='?', const=True, default=False, metavar="INT bp") group.add_argument('--ignoreDuplicates', help='If set, reads that have the same orientation ' 'and start position will be considered only ' 'once. If reads are paired, the mate\'s position ' 'also has to coincide to ignore a read.', action='store_true' ) group.add_argument('--minMappingQuality', metavar='INT', help='If set, only reads that have a mapping ' 'quality score of at least this are ' 'considered.', type=int, ) group.add_argument('--centerReads', help='By adding this option, reads are centered with ' 'respect to the fragment length. For paired-end data, ' 'the read is centered at the fragment length defined ' 'by the two ends of the fragment. For single-end data, the ' 'given fragment length is used. This option is ' 'useful to get a sharper signal around enriched ' 'regions.', action='store_true') group.add_argument('--samFlagInclude', help='Include reads based on the SAM flag. For example, ' 'to get only reads that are the first mate, use a flag of 64. ' 'This is useful to count properly paired reads only once, ' 'as otherwise the second mate will be also considered for the ' 'coverage.', metavar='INT', default=None, type=int, required=False) group.add_argument('--samFlagExclude', help='Exclude reads based on the SAM flag. For example, ' 'to get only reads that map to the forward strand, use ' '--samFlagExclude 16, where 16 is the SAM flag for reads ' 'that map to the reverse strand.', metavar='INT', default=None, type=int, required=False) group.add_argument('--minFragmentLength', help='The minimum fragment length needed for read/pair ' 'inclusion. This option is primarily useful ' 'in ATACseq experiments, for filtering mono- or ' 'di-nucleosome fragments.', metavar='INT', default=0, type=int, required=False) group.add_argument('--maxFragmentLength', help='The maximum fragment length needed for read/pair ' 'inclusion.', metavar='INT', default=0, type=int, required=False) return parser def gtf_options(suppress=False): """ Arguments present whenever a BED/GTF file can be used """ if suppress: parser = argparse.ArgumentParser(add_help=False) group = parser else: parser = argparse.ArgumentParser(add_help=False) group = parser.add_argument_group('GTF/BED12 options') if suppress: help = argparse.SUPPRESS else: help = 'When either a BED12 or GTF file are used to provide \ regions, perform the computation on the merged exons, \ rather than using the genomic interval defined by the \ 5-prime and 3-prime most transcript bound (i.e., columns \ 2 and 3 of a BED file). If a BED3 or BED6 file is used \ as input, then columns 2 and 3 are used as an exon.' group.add_argument('--metagene', help=help, action='store_true', dest='keepExons') if suppress is False: help = 'When a GTF file is used to provide regions, only \ entries with this value as their feature (column 2) \ will be processed as transcripts.' group.add_argument('--transcriptID', help=help, default='transcript') if suppress is False: help = 'When a GTF file is used to provide regions, only \ entries with this value as their feature (column 2) \ will be processed as exons. CDS would be another common \ value for this.' group.add_argument('--exonID', help=help, default='exon') if suppress is False: help = 'Each region has an ID (e.g., ACTB) assigned to it, \ which for BED files is either column 4 (if it exists) \ or the interval bounds. For GTF files this is instead \ stored in the last column as a key:value pair (e.g., as \ \'transcript_id "ACTB"\', for a key of transcript_id \ and a value of ACTB). In some cases it can be \ convenient to use a different identifier. To do so, set \ this to the desired key.' group.add_argument('--transcript_id_designator', help=help, default='transcript_id') return parser def normalization_options(): """Common arguments related to read coverage normalization """ parser = argparse.ArgumentParser(add_help=False) group = parser.add_argument_group('Read coverage normalization options') group.add_argument('--normalizeTo1x', help='Report read coverage normalized to 1x ' 'sequencing depth (also known as Reads Per Genomic ' 'Content (RPGC)). Sequencing depth is defined as: ' '(total number of mapped reads * fragment length) / ' 'effective genome size.\nThe scaling factor used ' 'is the inverse of the sequencing depth computed ' 'for the sample to match the 1x coverage. ' 'To use this option, the ' 'effective genome size has to be indicated after the ' 'option. The effective genome size is the portion ' 'of the genome that is mappable. Large fractions of ' 'the genome are stretches of NNNN that should be ' 'discarded. Also, if repetitive regions were not ' 'included in the mapping of reads, the effective ' 'genome size needs to be adjusted accordingly. ' 'Common values are: mm9: 2,150,570,000; ' 'hg19:2,451,960,000; dm3:121,400,000 and ce10:93,260,000. ' 'See Table 2 of http://www.plosone.org/article/info:doi/10.1371/journal.pone.0030377 ' 'or http://www.nature.com/nbt/journal/v27/n1/fig_tab/nbt.1518_T1.html ' 'for several effective genome sizes.', metavar='EFFECTIVE GENOME SIZE LENGTH', default=None, type=int, required=False) group.add_argument('--normalizeUsingRPKM', help='Use Reads Per Kilobase per Million reads to ' 'normalize the number of reads per bin. The formula ' 'is: RPKM (per bin) = number of reads per bin / ' '( number of mapped reads (in millions) * bin ' 'length (kb) ). Each read is considered independently,' 'if you want to only count either of the mate pairs in' 'paired-end data, use the --samFlag option.', action='store_true', required=False) group.add_argument('--ignoreForNormalization', '-ignore', help='A list of space-delimited chromosome names ' 'containing those chromosomes that should be excluded ' 'for computing the normalization. This is useful when considering ' 'samples with unequal coverage across chromosomes, like male ' 'samples. An usage examples is --ignoreForNormalization chrX chrM.', nargs='+') group.add_argument('--skipNonCoveredRegions', '--skipNAs', help='This parameter determines if non-covered regions ' '(regions without overlapping reads) in a BAM file should ' 'be skipped. The default is to treat those regions as having a value of zero. ' 'The decision to skip non-covered regions ' 'depends on the interpretation of the data. Non-covered regions ' 'may represent, for example, repetitive regions that should be skipped.', action='store_true') group.add_argument('--smoothLength', metavar="INT bp", help='The smooth length defines a window, larger than ' 'the binSize, to average the number of reads. For ' 'example, if the --binSize is set to 20 and the ' '--smoothLength is set to 60, then, for each ' 'bin, the average of the bin and its left and right ' 'neighbors is considered. Any value smaller than ' '--binSize will be ignored and no smoothing will be ' 'applied.', type=int) return parser def getParentArgParse(args=None, binSize=True, blackList=True): """ Typical arguments for several tools """ parser = argparse.ArgumentParser(add_help=False) optional = parser.add_argument_group('Optional arguments') optional.add_argument('--version', action='version', version='%(prog)s {}'.format(__version__)) if binSize: optional.add_argument('--binSize', '-bs', help='Size of the bins, in bases, for the output ' 'of the bigwig/bedgraph file.', metavar="INT bp", type=int, default=50) optional.add_argument('--region', '-r', help='Region of the genome to limit the operation ' 'to - this is useful when testing parameters to ' 'reduce the computing time. The format is ' 'chr:start:end, for example --region chr10 or ' '--region chr10:456700:891000.', metavar="CHR:START:END", required=False, type=genomicRegion) if blackList: optional.add_argument('--blackListFileName', '-bl', help="A BED or GTF file containing regions that should be excluded from all analyses. Currently this works by rejecting genomic chunks that happen to overlap an entry. Consequently, for BAM files, if a read partially overlaps a blacklisted region or a fragment spans over it, then the read/fragment might still be considered. Please note that you should adjust the effective genome size, if relevant.", metavar="BED file", nargs="+", required=False) optional.add_argument('--numberOfProcessors', '-p', help='Number of processors to use. Type "max/2" to ' 'use half the maximum number of processors or "max" ' 'to use all available processors.', metavar="INT", type=numberOfProcessors, default=cfg.config.get('general', 'default_proc_number'), required=False) optional.add_argument('--verbose', '-v', help='Set to see processing messages.', action='store_true') return parser def numberOfProcessors(string): import multiprocessing availProc = multiprocessing.cpu_count() if string == "max/2": # default case # by default half of the available processors are used numberOfProcessors = int(availProc * 0.5) elif string == "max": # use all available processors numberOfProcessors = availProc else: try: numberOfProcessors = int(string) except ValueError: raise argparse.ArgumentTypeError( "{} is not a valid number of processors".format(string)) except Exception as e: raise argparse.ArgumentTypeError("the value given is not valid. " "Error message: {}\nThe number of " "available processors in your " "computer is {}.".format(string, e, availProc)) if numberOfProcessors > availProc: numberOfProcessors = availProc return numberOfProcessors def genomicRegion(string): # remove whitespaces using split,join trick region = ''.join(string.split()) if region == '': return None # remove undesired characters that may be present and # replace - by : # N.B., the syntax for translate() differs between python 2 and 3 try: region = region.translate(None, ",;|!{}()").replace("-", ":") except: region = region.translate({ord(i): None for i in ",;|!{}()"}) if len(region) == 0: print("oh no!") raise argparse.ArgumentTypeError( "{} is not a valid region".format(string)) return region def writableFile(string): """ Simple function that tests if a given path is writable """ try: open(string, 'w').close() os.remove(string) except: msg = "{} file can't be opened for writing".format(string) raise argparse.ArgumentTypeError(msg) return string """ Arguments used by heatmapper and profiler """ def heatmapperMatrixArgs(args=None): parser = argparse.ArgumentParser(add_help=False) required = parser.add_argument_group('Required arguments') required.add_argument('--matrixFile', '-m', help='Matrix file from the computeMatrix tool.', type=argparse.FileType('r'), ) required.add_argument('--outFileName', '-out', help='File name to save the image to. The file ' 'ending will be used to determine the image ' 'format. The available options are: "png", ' '"eps", "pdf" and "svg", e.g., MyHeatmap.png.', type=writableFile, required=True) return parser def heatmapperOutputArgs(args=None, mode=['heatmap', 'profile'][0]): parser = argparse.ArgumentParser(add_help=False) output = parser.add_argument_group('Output options') output.add_argument( '--outFileSortedRegions', help='File name into which the regions are saved ' 'after skipping zeros or min/max threshold values. The ' 'order of the regions in the file follows the sorting ' 'order selected. This is useful, for example, to ' 'generate other heatmaps while keeping the sorting of the ' 'first heatmap. Example: Heatmap1sortedRegions.bed', metavar='FILE', type=argparse.FileType('w')) if mode == 'heatmap': output.add_argument('--outFileNameMatrix', help='If this option is given, then the matrix ' 'of values underlying the heatmap will be saved ' 'using this name, e.g. MyMatrix.tab.', metavar='FILE', type=writableFile) elif mode == 'profile': output.add_argument('--outFileNameData', help='File name to save the data ' 'underlying data for the average profile, e.g. ' 'myProfile.tab.', type=writableFile) output.add_argument( '--dpi', help='Set the DPI to save the figure.', type=int, default=200) return parser def heatmapperOptionalArgs(mode=['heatmap', 'profile'][0]): parser = argparse.ArgumentParser(add_help=False) cluster = parser.add_argument_group('Clustering arguments') cluster.add_argument( '--kmeans', help='Number of clusters to compute. When this ' 'option is set, the matrix is split into clusters ' 'using the k-means algorithm. Only works for data that ' 'is not grouped, otherwise only the first group will ' 'be clustered. If more specific clustering methods ' 'are required, then save the underlying matrix ' 'and run the clustering using other software. The plotting ' 'of the clustering may fail with an error if a ' 'cluster has very few members compared to the total number ' 'or regions.', type=int) cluster.add_argument( '--hclust', help='Number of clusters to compute. When this ' 'option is set, then the matrix is split into clusters ' 'using the hierarchical clustering algorithm, using "ward linkage". ' 'Only works for data that is not grouped, otherwise only the first ' 'group will be clustered. --hclust could be very slow if you have ' '>1000 regions. In those cases, you might prefer --kmeans or if more ' 'clustering methods are required you can save the underlying matrix and run ' 'the clustering using other software. The plotting of the clustering may ' 'fail with an error if a cluster has very few members compared to the ' 'total number of regions.', type=int) optional = parser.add_argument_group('Optional arguments') optional.add_argument("--help", "-h", action="help", help="show this help message and exit") optional.add_argument('--version', action='version', version='%(prog)s {}'.format(__version__)) if mode == 'profile': optional.add_argument( '--averageType', default='mean', choices=["mean", "median", "min", "max", "std", "sum"], help='The type of statistic that should be used for the ' 'profile. The options are: "mean", "median", "min", "max", ' '"sum" and "std".') optional.add_argument('--plotHeight', help='Plot height in cm.', type=float, default=7) optional.add_argument('--plotWidth', help='Plot width in cm. The minimum value is 1 cm.', type=float, default=11) optional.add_argument( '--plotType', help='"lines" will plot the profile line based ' 'on the average type selected. "fill" ' 'fills the region between zero and the profile ' 'curve. The fill in color is semi transparent to ' 'distinguish different profiles. "se" and "std" ' 'color the region between the profile and the ' 'standard error or standard deviation of the data. ' 'As in the case of ' 'fill, a semi-transparent color is used. ' '"overlapped_lines" plots each region\'s value, one on ' 'top of the other. "heatmap" plots a ' 'summary heatmap.', choices=['lines', 'fill', 'se', 'std', 'overlapped_lines', 'heatmap'], default='lines') optional.add_argument('--colors', help='List of colors to use ' 'for the plotted lines (N.B., not applicable to \'--plotType overlapped_lines\'). Color names ' 'and html hex strings (e.g., #eeff22) ' 'are accepted. The color names should ' 'be space separated. For example, ' '--colors red blue green ', nargs='+') optional.add_argument('--numPlotsPerRow', help='Number of plots per row', type=int, default=8) elif mode == 'heatmap': optional.add_argument('--sortRegions', help='Whether the heatmap should present ' 'the regions sorted. The default is ' 'to sort in descending order based on ' 'the mean value per region.', choices=["descend", "ascend", "no"], default='descend') optional.add_argument('--sortUsing', help='Indicate which method should be used for ' 'sorting. For each row the ' 'method is computed.', choices=["mean", "median", "max", "min", "sum", "region_length"], default='mean') optional.add_argument('--sortUsingSamples', help='List of sample numbers (order as in matrix), ' 'that are used for sorting by --sortUsing, ' 'no value uses all samples, ' 'example: --sortUsingSamples 1 3', type=int, nargs='+') optional.add_argument( '--averageTypeSummaryPlot', default='mean', choices=["mean", "median", "min", "max", "std", "sum"], help='Define the type of statistic that should be plotted in the ' 'summary image above the heatmap. The options are: "mean", ' '"median", "min", "max", "sum" and "std".') optional.add_argument( '--missingDataColor', default='black', help='If --missingDataAsZero is not set, such cases ' 'will be colored in black by default. Using this ' 'parameter, a different color can be set. A value ' 'between 0 and 1 will be used for a gray scale ' '(black is 0). For a list of possible color ' 'names see: http://packages.python.org/ete2/' 'reference/reference_svgcolors.html. ' 'Other colors can be specified using the #rrggbb ' 'notation.') from matplotlib import cm color_options = "', '".join([m for m in cm.datad if not m.endswith('_r')]) optional.add_argument( '--colorMap', help='Color map to use for the heatmap. If more than one heatmap is being plotted the color ' 'of each heatmap can be enter individually (e.g. `--colorMap Reds Blues`). Color maps ' 'are recycled if the number of color maps is smaller than the number of heatmaps being ' 'plotted. Available values can be seen here: http://matplotlib.org/users/colormaps.html ' 'The available options are: \'' + color_options + '\'', default=['RdYlBu'], nargs='+') optional.add_argument( '--alpha', default=1.0, type=check_float_0_1, help='The alpha channel (transparency) to use for the heatmaps. The default is 1.0 and values ' 'must be between 0 and 1.') optional.add_argument( '--colorList', help='List of colors to use to create a colormap. For example, if `--colorList black,yellow,blue` ' 'is set (colors separated by comas) then a color map that starts with black, continues to ' 'yellow and finishes in blue is created. If this option is selected, it overrides the --colorMap ' 'chosen. The list of valid color names can be seen here: ' 'http://matplotlib.org/examples/color/named_colors.html ' 'Hex colors are valid (e.g #34a2b1). If individual colors for different heatmaps ' 'need to be specified they need to be separated by space as for example: ' '`--colorList "white,#cccccc" "white,darkred"` ' 'As for --colorMap, the color lists are recycled if their number is smaller thatn the number of' 'plotted heatmaps. ' 'The number of transitions is defined by the --colorNumber option.', type=check_list_of_comma_values, nargs='+') optional.add_argument( '--colorNumber', help='N.B., --colorList is required for an effect. This controls the ' 'number of transitions from one color to the other. If --colorNumber is ' 'the number of colors in --colorList then there will be no transitions ' 'between the colors.', type=int, default=256) optional.add_argument('--zMin', '-min', default=None, help='Minimum value for the heatmap intensities. Multiple values, separated by ' 'spaces can be set for each heatmap. If the number of zMin values is smaller than' 'the number of heatmaps the values are recycled.', type=float, nargs='+') optional.add_argument('--zMax', '-max', default=None, help='Maximum value for the heatmap intensities. Multiple values, separated by ' 'spaces can be set for each heatmap. If the number of zMax values is smaller than' 'the number of heatmaps the values are recycled.', type=float, nargs='+') optional.add_argument('--heatmapHeight', help='Plot height in cm. The default for the heatmap ' 'height is 28. The minimum value is ' '3 and the maximum is 100.', type=float, default=28) optional.add_argument('--heatmapWidth', help='Plot width in cm. The default value is 4 ' 'The minimum value is 1 and the ' 'maximum is 100.', type=float, default=4) optional.add_argument( '--whatToShow', help='The default is to include a summary or profile plot on top ' 'of the heatmap and a heatmap colorbar. Other options are: ' '"plot and heatmap", "heatmap only", "heatmap and ' 'colorbar", and the default "plot, heatmap and ' 'colorbar".', choices=["plot, heatmap and colorbar", "plot and heatmap", "heatmap only", "heatmap and colorbar"], default='plot, heatmap and colorbar') optional.add_argument( '--boxAroundHeatmaps', help='By default black boxes are plot around heatmaps. This can be turned off ' 'by setting --boxAroundHeatmaps no', default='yes') optional.add_argument('--xAxisLabel', '-x', default='gene distance (bp)', help='Description for the x-axis label.') # end elif optional.add_argument('--startLabel', default='TSS', help='[only for scale-regions mode] Label shown ' 'in the plot for the start of ' 'the region. Default is TSS (transcription ' 'start site), but could be changed to anything, ' 'e.g. "peak start". ' 'Same for the --endLabel option. See below.') optional.add_argument('--endLabel', default='TES', help='[only for scale-regions mode] Label ' 'shown in the plot for the region ' 'end. Default is TES (transcription end site).') optional.add_argument('--refPointLabel', help='[only for reference-point mode] Label ' 'shown in the plot for the ' 'reference-point. Default ' 'is the same as the reference point selected ' '(e.g. TSS), but could be anything, e.g. ' '"peak start".', default='TSS') optional.add_argument('--nanAfterEnd', help=argparse.SUPPRESS, default=False) optional.add_argument('--regionsLabel', '-z', help='Labels for the regions plotted in the ' 'heatmap. If more than one region is being ' 'plotted, a list of labels separated by spaces is required. ' 'If a label itself contains a space, then quotes are ' 'needed. For example, --regionsLabel label_1, "label 2". ', nargs='+') optional.add_argument('--samplesLabel', help='Labels for the samples plotted. The ' 'default is to use the file name of the ' 'sample. The sample labels should be separated ' 'by spaces and quoted if a label itself' 'contains a space E.g. --samplesLabel label-1 "label 2" ', nargs='+') optional.add_argument('--plotTitle', '-T', help='Title of the plot, to be printed on top of ' 'the generated image. Leave blank for no title.', default='') optional.add_argument('--yAxisLabel', '-y', default='', help='Y-axis label for the top panel.') optional.add_argument('--yMin', default=None, nargs='+', help='Minimum value for the Y-axis. Multiple values, separated by ' 'spaces can be set for each profile. If the number of yMin values is smaller than' 'the number of plots, the values are recycled.') optional.add_argument('--yMax', default=None, nargs='+', help='Maximum value for the Y-axis. Multiple values, separated by ' 'spaces can be set for each profile. If the number of yMin values is smaller than' 'the number of plots, the values are recycled.') optional.add_argument('--legendLocation', default='best', choices=['best', 'upper-right', 'upper-left', 'upper-center', 'lower-left', 'lower-right', 'lower-center', 'center', 'center-left', 'center-right', 'none' ], help='Location for the legend in the summary plot. ' 'Note that "none" does not work for the profiler.') optional.add_argument('--perGroup', help='The default is to plot all groups of regions by ' 'sample. Using this option instead plots all samples by ' 'group of regions. Note that this is only useful if you ' 'have multiple groups of regions. by sample rather than ' 'group.', action='store_true') optional.add_argument('--plotFileFormat', metavar='', help='Image format type. If given, this ' 'option overrides the ' 'image format based on the plotFile ending. ' 'The available options are: "png", ' '"eps", "pdf" and "svg"', choices=['png', 'pdf', 'svg', 'eps']) optional.add_argument('--verbose', help='If set, warning messages and ' 'additional information are given.', action='store_true') return parser def deepBlueOptionalArgs(): parser = argparse.ArgumentParser(add_help=False) dbo = parser.add_argument_group('deepBlue arguments', 'Options used only for remote bedgraph/wig files hosted on deepBlue') dbo.add_argument( '--deepBlueURL', help='For remote files bedgraph/wiggle files hosted on deepBlue, this ' 'specifies the server URL. The default is ' '"http://deepblue.mpi-inf.mpg.de/xmlrpc", which should not be ' 'changed without good reason.', default='http://deepblue.mpi-inf.mpg.de/xmlrpc') dbo.add_argument( '--userKey', help='For remote files bedgraph/wiggle files hosted on deepBlue, this ' 'specifies the user key to use for access. The default is ' '"anonymous_key", which suffices for public datasets. If you need ' 'access to a restricted access/private dataset, then request a ' 'key from deepBlue and specify it here.', default='anonymous_key') dbo.add_argument( '--deepBlueTempDir', help='If specified, temporary files from preloading datasets from ' 'deepBlue will be written here (note, this directory must exist). ' 'If not specified, where ever temporary files would normally be written ' 'on your system is used.', default=None) dbo.add_argument( '--deepBlueKeepTemp', action='store_true', help='If specified, temporary bigWig files from preloading deepBlue ' 'datasets are not deleted. A message will be printed noting where these ' 'files are and what sample they correspond to. These can then be used ' 'if you wish to analyse the same sample with the same regions again.') return parser deepTools-2.5.0/deeptools/plotCorrelation.py0000640000201600010240000002106613006372703020354 0ustar ryanbioinfo#!/usr/bin/env python # -*- coding: utf-8 -*- import sys import argparse import numpy as np import matplotlib matplotlib.use('Agg') matplotlib.rcParams['pdf.fonttype'] = 42 matplotlib.rcParams['svg.fonttype'] = 'none' import matplotlib.pyplot as plt from deeptools.correlation import Correlation from deeptools._version import __version__ old_settings = np.seterr(all='ignore') def parse_arguments(args=None): basic_args = plot_correlation_args() heatmap_parser = heatmap_options() parser = argparse.ArgumentParser( formatter_class=argparse.RawDescriptionHelpFormatter, description=""" Tool for the analysis and visualization of sample correlations based on the output of multiBamSummary or multiBigwigSummary. Pearson or Spearman methods are available to compute correlation coefficients. Results can be saved as multiple scatter plots depicting the pairwise correlations or as a clustered heatmap, where the colors represent the correlation coefficients and the clusters are joined using the Nearest Point Algorithm (also known as "single"). Optionally, the values can be saved as tables, too. detailed help: plotCorrelation -h """, epilog='example usages:\n' 'plotCorrelation -in results_file --whatToPlot heatmap --corMethod pearson -o heatmap.png\n\n' ' \n\n', parents=[basic_args, heatmap_parser]) return parser def plot_correlation_args(): parser = argparse.ArgumentParser(add_help=False) required = parser.add_argument_group('Required arguments') # define the arguments required.add_argument('--corData', '-in', metavar='FILE', help='Compressed matrix of values generated by multiBigwigSummary or multiBamSummary', required=True) required.add_argument('--plotFile', '-o', help='File to save the heatmap to. The file extension determines the format, ' 'so heatmap.pdf will save the heatmap in PDF format. ' 'The available formats are: .png, ' '.eps, .pdf and .svg.', type=argparse.FileType('w'), metavar='FILE', required=True) required.add_argument('--corMethod', '-c', help="Correlation method.", choices=['spearman', 'pearson'], required=True) required.add_argument('--whatToPlot', '-p', help="Choose between a heatmap or pairwise scatter plots", choices=['heatmap', 'scatterplot'], required=True) optional = parser.add_argument_group('Optional arguments') optional.add_argument('--skipZeros', help='By setting this option, genomic regions ' 'that have zero or missing (nan) values in all samples ' 'are excluded.', action='store_true', required=False) optional.add_argument('--labels', '-l', metavar='sample1 sample2', help='User defined labels instead of default labels from ' 'file names. ' 'Multiple labels have to be separated by spaces, e.g. ' '--labels sample1 sample2 sample3', nargs='+') optional.add_argument('--plotTitle', '-T', help='Title of the plot, to be printed on top of ' 'the generated image. Leave blank for no title.', default='') optional.add_argument('--plotFileFormat', metavar='FILETYPE', help='Image format type. If given, this option ' 'overrides the image format based on the plotFile ' 'ending. The available options are: png, ' 'eps, pdf and svg.', choices=['png', 'pdf', 'svg', 'eps']) optional.add_argument( '--removeOutliers', help='If set, bins with very large counts are removed. ' 'Bins with abnormally high reads counts artificially increase ' 'pearson correlation; that\'s why, multiBamSummary tries ' 'to remove outliers using the median absolute deviation (MAD) ' 'method applying a threshold of 200 to only consider extremely ' 'large deviations from the median. The ENCODE blacklist page ' '(https://sites.google.com/site/anshulkundaje/projects/blacklists) ' 'contains useful information about regions with unusually high counts' 'that may be worth removing.', action='store_true') optional.add_argument('--version', action='version', version='%(prog)s {}'.format(__version__)) group = parser.add_argument_group('Output optional options') group.add_argument('--outFileCorMatrix', help='Save matrix with pairwise correlation values to a tab-separated file.', metavar='FILE', type=argparse.FileType('w')) return parser def heatmap_options(): """ Options for generating the correlation heat map """ parser = argparse.ArgumentParser(add_help=False) heatmap = parser.add_argument_group('Heatmap options') heatmap.add_argument('--zMin', '-min', default=None, help='Minimum value for the heatmap intensities. ' 'If not specified, the value is set automatically', type=float) heatmap.add_argument('--zMax', '-max', default=None, help='Maximum value for the heatmap intensities.' 'If not specified, the value is set automatically', type=float) heatmap.add_argument( '--colorMap', default='jet', metavar='', help='Color map to use for the heatmap. Available values can be ' 'seen here: ' 'http://matplotlib.org/examples/color/colormaps_reference.html') heatmap.add_argument('--plotNumbers', help='If set, then the correlation number is plotted ' 'on top of the heatmap. This option is only valid when plotting a heatmap.', action='store_true', required=False) return parser def main(args=None): args = parse_arguments().parse_args(args) corr = Correlation(args.corData, args.corMethod, labels=args.labels, remove_outliers=args.removeOutliers, log1p=None, skip_zeros=args.skipZeros) if args.corMethod == 'pearson': # test if there are outliers and write a message recommending the removal if len(corr.get_outlier_indices(np.asarray(corr.matrix).flatten())) > 0: if args.removeOutliers: sys.stderr.write("\nOutliers were detected in the data. They " "will be removed to avoid bias " "in the pearson correlation.\n") else: sys.stderr.write("\nOutliers were detected in the data. Consider " "using the --removeOutliers parameter to avoid a bias " "in the pearson correlation.\n") if args.colorMap: try: plt.get_cmap(args.colorMap) except ValueError as error: sys.stderr.write( "A problem was found. Message: {}\n".format(error)) exit() args.plotFile.close() if args.whatToPlot == 'scatterplot': corr.plot_scatter(args.plotFile.name, plot_title=args.plotTitle, image_format=args.plotFileFormat) else: corr.plot_correlation(args.plotFile.name, vmax=args.zMax, vmin=args.zMin, colormap=args.colorMap, plot_title=args.plotTitle, image_format=args.plotFileFormat, plot_numbers=args.plotNumbers) if args.outFileCorMatrix: corr.save_corr_matrix(args.outFileCorMatrix) deepTools-2.5.0/deeptools/plotCoverage.py0000640000201600010240000002371613061773504017637 0ustar ryanbioinfo#!/usr/bin/env python # -*- coding: utf-8 -*- import os import sys import argparse import numpy as np import matplotlib matplotlib.use('Agg') matplotlib.rcParams['pdf.fonttype'] = 42 matplotlib.rcParams['svg.fonttype'] = 'none' import matplotlib.pyplot as plt import deeptools.countReadsPerBin as countR from deeptools import parserCommon from deeptools._version import __version__ old_settings = np.seterr(all='ignore') def parse_arguments(args=None): parent_parser = parserCommon.getParentArgParse(binSize=False) read_options_parser = parserCommon.read_options() parser = \ argparse.ArgumentParser( parents=[required_args(), parent_parser, read_options_parser], formatter_class=argparse.RawDescriptionHelpFormatter, add_help=False, description=""" This tool is useful to assess the sequencing depth of a given sample. It samples 1 million bp, counts the number of overlapping reads and can report a histogram that tells you how many bases are covered how many times. Multiple BAM files are accepted, but they all should correspond to the same genome assembly. detailed usage help: $ plotCoverage -h """, epilog='example usages:\nplotCoverage ' '--bamfiles file1.bam file2.bam -out results.png\n\n' ' \n\n', conflict_handler='resolve') parser.add_argument('--version', action='version', version='plotCoverage {}'.format(__version__)) return parser def process_args(args=None): args = parse_arguments().parse_args(args) if args.labels and len(args.bamfiles) != len(args.labels): print("The number of labels does not match the number of BAM files.") exit(0) if not args.labels: args.labels = [os.path.basename(x) for x in args.bamfiles] return args def required_args(): parser = argparse.ArgumentParser(add_help=False) required = parser.add_argument_group('Required arguments') required.add_argument('--bamfiles', '-b', metavar='FILE1 FILE2', help='List of indexed BAM files separated by spaces.', nargs='+', required=True) required.add_argument('--plotFile', '-o', help='File name to save the plot to.', required=True) optional = parser.add_argument_group('Optional arguments') optional.add_argument("--help", "-h", action="help", help="show this help message and exit") optional.add_argument('--labels', '-l', metavar='sample1 sample2', help='User defined labels instead of default labels from ' 'file names. ' 'Multiple labels have to be separated by spaces, e.g. ' '--labels sample1 sample2 sample3', nargs='+') optional.add_argument('--plotTitle', '-T', help='Title of the plot, to be printed on top of ' 'the generated image. Leave blank for no title.', default='') optional.add_argument('--skipZeros', help='By setting this option, genomic regions ' 'that have zero or nan values in _all_ samples ' 'are excluded.', action='store_true', required=False) optional.add_argument('--numberOfSamples', '-n', help='Number of 1 bp regions to sample. Default 1 million.', required=False, type=int, default=1000000) optional.add_argument('--outRawCounts', help='Save raw counts (coverages) to file.', metavar='FILE') optional.add_argument('--plotFileFormat', metavar='FILETYPE', help='Image format type. If given, this option ' 'overrides the image format based on the plotFile ' 'ending. The available options are: png, ' 'eps, pdf and svg.', default=None, choices=['png', 'pdf', 'svg', 'eps']) return parser def main(args=None): args = process_args(args) cr = countR.CountReadsPerBin(args.bamfiles, binLength=1, numberOfSamples=args.numberOfSamples, numberOfProcessors=args.numberOfProcessors, verbose=args.verbose, region=args.region, blackListFileName=args.blackListFileName, extendReads=args.extendReads, minMappingQuality=args.minMappingQuality, ignoreDuplicates=args.ignoreDuplicates, center_read=args.centerReads, samFlag_include=args.samFlagInclude, samFlag_exclude=args.samFlagExclude, minFragmentLength=args.minFragmentLength, maxFragmentLength=args.maxFragmentLength, out_file_for_raw_data=args.outRawCounts) num_reads_per_bin = cr.run() sys.stderr.write("Number of non zero bins " "used: {}\n".format(num_reads_per_bin.shape[0])) if args.outRawCounts: # append to the generated file the # labels header = "#'chr'\t'start'\t'end'\t" header += "'" + "'\t'".join(args.labels) + "'\n" f = open(args.outRawCounts, 'r+') content = f.read() f.seek(0, 0) f.write(header + content) f.close() if num_reads_per_bin.shape[0] < 2: exit("ERROR: too few non-zero bins found.\n" "If using --region please check that this " "region is covered by reads.\n") if args.skipZeros: num_reads_per_bin = countR.remove_row_of_zeros(num_reads_per_bin) fig, axs = plt.subplots(1, 2, figsize=(15, 5)) plt.suptitle(args.plotTitle) # plot up to two std from mean num_reads_per_bin = num_reads_per_bin.astype(int) sample_mean = num_reads_per_bin.mean(axis=0) sample_std = num_reads_per_bin.std(axis=0) sample_max = num_reads_per_bin.max(axis=0) sample_min = num_reads_per_bin.min(axis=0) sample_25 = np.percentile(num_reads_per_bin, 25, axis=0) sample_50 = np.percentile(num_reads_per_bin, 50, axis=0) sample_75 = np.percentile(num_reads_per_bin, 75, axis=0) # use the largest 99th percentile from all samples to set the x_max value x_max = np.max(np.percentile(num_reads_per_bin, 99, axis=0)) # plot coverage # print headers for text output print("sample\tmean\tstd\tmin\t25%\t50%\t75%\tmax") # the determination of a sensible value for y_max of the first plot (fraction of bases sampled vs. # coverage) is important because, depending on the data, # it becomes very difficult to see the lines in the plot. For example, if the coverage of a sample # is a nice gaussian curve with a large mean of 50. Then a sensible range for the y axis (fraction of # reads having coverage=x) is (0, 0.02) which nicely shows the coverage curve. If instead the coverage is # very por and centers close to 1 then a good y axis range is (0,1). # the current implementation aims to find the y_value for which 50% of the reads >= x (coverage) and # sets that as the x_axis range. y_max = [] for idx, col in enumerate(num_reads_per_bin.T): frac_reads_per_coverage = np.bincount(col.astype(int)).astype(float) / num_reads_per_bin.shape[0] axs[0].plot(frac_reads_per_coverage, label="{}, mean={:.1f}".format(args.labels[idx], sample_mean[idx])) csum = np.bincount(col.astype(int))[::-1].cumsum() csum_frac = csum.astype(float)[::-1] / csum.max() axs[1].plot(csum_frac, label=args.labels[idx]) # find the indexes (i.e. the x values) for which the cumulative distribution 'fraction of bases # sampled >= coverage' where fraction of bases sampled = 50%: `np.flatnonzero(csum_frac>0.5)` # then find the fraction of bases sampled that that have the largest x y_max.append(frac_reads_per_coverage[max(np.flatnonzero(csum_frac > 0.5))]) print("{}\t{:0.2f}\t{:0.2f}\t{}\t{}\t{}\t{}\t{}\t".format(args.labels[idx], sample_mean[idx], sample_std[idx], sample_min[idx], sample_25[idx], sample_50[idx], sample_75[idx], sample_max[idx], )) # The 'good' x-axis is computed for each sample. The lower value is favored in which # distributions with a wider x-range can better be seen. y_max = min(y_max) axs[0].set_ylim(0, min(1, y_max + (y_max * 0.10))) axs[0].set_xlim(0, x_max) axs[0].set_xlabel('coverage (#reads per bp)') axs[0].legend(fancybox=True, framealpha=0.5) axs[0].set_ylabel('fraction of bases sampled') # plot cumulative coverage axs[1].set_xlim(0, x_max) axs[1].set_xlabel('coverage (#reads per bp)') axs[1].set_ylabel('fraction of bases sampled >= coverage') axs[1].legend(fancybox=True, framealpha=0.5) plt.savefig(args.plotFile, format=args.plotFileFormat) plt.close() if __name__ == "__main__": main() deepTools-2.5.0/deeptools/plotEnrichment.py0000640000201600010240000005075613067414642020205 0ustar ryanbioinfo#!/usr/bin/env python # -*- coding: utf-8 -*- import sys import argparse import numpy as np import matplotlib matplotlib.use('Agg') matplotlib.rcParams['pdf.fonttype'] = 42 matplotlib.rcParams['svg.fonttype'] = 'none' import matplotlib.pyplot as plt import matplotlib.gridspec as gridspec from deeptools.mapReduce import mapReduce, getUserRegion, blSubtract from deeptools.getFragmentAndReadSize import get_read_and_fragment_length from deeptools.utilities import getCommonChrNames, mungeChromosome, getTLen from deeptools.bamHandler import openBam from deeptoolsintervals import Enrichment, GTF from deeptools.countReadsPerBin import CountReadsPerBin as cr from deeptools import parserCommon old_settings = np.seterr(all='ignore') def parse_arguments(args=None): basic_args = plot_enrichment_args() # --region, --blackListFileName, -p and -v parent_parser = parserCommon.getParentArgParse(binSize=False) # --extend reads and such read_options = parserCommon.read_options() parser = argparse.ArgumentParser( formatter_class=argparse.RawDescriptionHelpFormatter, description=""" Tool for calculating and plotting the signal enrichment in either regions in BED format or feature types (column 3) in GTF format. The underlying datapoints can also be output. Metrics are plotted as a fraction of total reads. Regions in a BED file are assigned to the 'peak' feature. detailed help: plotEnrichment -h """, epilog='example usages:\n' 'plotEnrichment -b file1.bam file2.bam --BED peaks.bed -o enrichment.png\n\n' ' \n\n', parents=[basic_args, parent_parser, read_options]) return parser def plot_enrichment_args(): parser = argparse.ArgumentParser(add_help=False) required = parser.add_argument_group('Required arguments') # define the arguments required.add_argument('--bamfiles', '-b', metavar='file1.bam file2.bam', help='List of indexed bam files separated by spaces.', nargs='+', required=True) required.add_argument('--BED', help='Limits the enrichment analysis to ' 'the regions specified in these BED/GTF files. Enrichment ' 'is calculated as the number of reads overlapping each ' 'feature type. The feature type is column 3 in a GTF file ' 'and "peak" for BED files.', metavar='FILE1.bed FILE2.bed', nargs='+', required=True) required.add_argument('--plotFile', '-o', help='File to save the plot to. The file extension determines the format, ' 'so heatmap.pdf will save the heatmap in PDF format. ' 'The available formats are: .png, ' '.eps, .pdf and .svg.', metavar='FILE', required=True) optional = parser.add_argument_group('Optional arguments') optional.add_argument('--labels', '-l', metavar='sample1 sample2', help='User defined labels instead of default labels from ' 'file names. ' 'Multiple labels have to be separated by spaces, e.g. ' '--labels sample1 sample2 sample3', nargs='+') optional.add_argument('--regionLabels', metavar="region1 region2", help="For BED files, the label given to its region is " "the file name, but this can be overridden by providing " "a custom label. For GTF files this is ignored. Note " "that if you provide labels, you MUST provide one for each " "BED/GTF file, even though it will be ignored for GTF files.", nargs='+') optional.add_argument('--plotTitle', '-T', help='Title of the plot, to be printed on top of ' 'the generated image. Leave blank for no title.', default='') optional.add_argument('--plotFileFormat', metavar='FILETYPE', help='Image format type. If given, this option ' 'overrides the image format based on the plotFile ' 'ending. The available options are: png, ' 'eps, pdf and svg.', choices=['png', 'pdf', 'svg', 'eps']) optional.add_argument('--outRawCounts', help='Save the counts per region to a tab-delimited file.', metavar='FILE') optional.add_argument('--perSample', help='Group the plots by sample, rather than by feature type (the default).', action='store_true') optional.add_argument('--variableScales', help='By default, the y-axes are always 0-100. This allows the axis range to be restricted.', action='store_true') optional.add_argument('--plotHeight', help='Plot height in cm.', type=float, default=20) optional.add_argument('--plotWidth', help='Plot width in cm. The minimum value is 1 cm.', type=float, default=20) optional.add_argument('--colors', help='List of colors to use ' 'for the plotted lines. Color names ' 'and html hex strings (e.g., #eeff22) ' 'are accepted. The color names should ' 'be space separated. For example, ' '--colors red blue green ', nargs='+') optional.add_argument('--numPlotsPerRow', help='Number of plots per row', type=int, default=4) optional.add_argument('--alpha', default=0.9, type=parserCommon.check_float_0_1, help='The alpha channel (transparency) to use for the bars. ' 'The default is 0.9 and values must be between 0 and 1.') optional.add_argument('--Offset', help='Uses this offset inside of each read as the signal. This is useful in ' 'cases like RiboSeq or GROseq, where the signal is 12, 15 or 0 bases past the ' 'start of the read. This can be paired with the --filterRNAstrand option. ' 'Note that negative values indicate offsets from the end of each read. A value ' 'of 1 indicates the first base of the alignment (taking alignment orientation ' 'into account). Likewise, a value of -1 is the last base of the alignment. An ' 'offset of 0 is not permitted. If two values are specified, then they will be ' 'used to specify a range of positions. Note that specifying something like ' '--Offset 5 -1 will result in the 5th through last position being used, which ' 'is equivalent to trimming 4 bases from the 5-prime end of alignments.', metavar='INT', type=int, nargs='+', required=False) bed12 = parser.add_argument_group('BED12 arguments') bed12.add_argument('--keepExons', help="For BED12 files, use each exon as a region, rather than columns 2/3", action="store_true") return parser def getBAMBlocks(read, defaultFragmentLength, centerRead, offset=None): """ This is basically get_fragment_from_read from countReadsPerBin """ blocks = None maxPairedFragmentLength = 0 if defaultFragmentLength != "read length": maxPairedFragmentLength = 4 * defaultFragmentLength if defaultFragmentLength == 'read length': blocks = read.get_blocks() else: if cr.is_proper_pair(read, maxPairedFragmentLength): if read.is_reverse: fragmentStart = read.next_reference_start fragmentEnd = read.reference_end else: fragmentStart = read.reference_start # the end of the fragment is defined as # the start of the forward read plus the insert length fragmentEnd = read.reference_start + abs(read.template_length) # Extend using the default fragment length else: if read.is_reverse: fragmentStart = read.reference_end - defaultFragmentLength fragmentEnd = read.reference_end else: fragmentStart = read.reference_start fragmentEnd = read.reference_start + defaultFragmentLength if centerRead: fragmentCenter = fragmentEnd - (fragmentEnd - fragmentStart) / 2 fragmentStart = fragmentCenter - read.infer_query_length(always=False) / 2 fragmentEnd = fragmentStart + read.infer_query_length(always=False) assert fragmentStart < fragmentEnd, "fragment start greater than fragment" \ "end for read {}".format(read.query_name) blocks = [(int(fragmentStart), int(fragmentEnd))] # Handle read offsets, if needed if offset is not None: rv = [(None, None)] if len(offset) > 1: if offset[0] > 0: offset[0] -= 1 if offset[1] < 0: offset[1] += 1 else: if offset[0] > 0: offset[0] -= 1 offset = [offset[0], offset[0] + 1] else: offset = [offset[0], None] if offset[1] == 0: # -1 gets switched to 0, which screws things up offset = (offset[0], None) stretch = [] # For the sake of simplicity, convert [(10, 20), (30, 40)] to [10, 11, 12, 13, ..., 40] # Then subset accordingly for block in blocks: stretch.extend(range(block[0], block[1])) if read.is_reverse: stretch = stretch[::-1] try: foo = stretch[offset[0]:offset[1]] except: return rv if len(foo) == 0: return rv if read.is_reverse: foo = foo[::-1] # Convert the stretch back to a list of tuples foo = np.array(foo) d = foo[1:] - foo[:-1] idx = np.argwhere(d > 1).flatten().tolist() # This now holds the interval bounds as a list idx.append(-1) last = 0 blocks = [] for i in idx: blocks.append((foo[last].astype("int"), foo[i].astype("int") + 1)) last = i + 1 return blocks def getEnrichment_worker(arglist): """ This is the worker function of plotEnrichment. In short, given a region, iterate over all reads **starting** in it. Filter/extend them as requested and check each for an overlap with findOverlaps. For each overlap, increment the counter for that feature. """ chrom, start, end, args, defaultFragmentLength = arglist if args.verbose: sys.stderr.write("Processing {}:{}-{}\n".format(chrom, start, end)) gtf = Enrichment(args.BED, keepExons=args.keepExons, labels=args.regionLabels) olist = [] total = [0] * len(args.bamfiles) for idx, f in enumerate(args.bamfiles): odict = dict() for x in gtf.features: odict[x] = 0 fh = openBam(f) chrom = mungeChromosome(chrom, fh.references) prev_start_pos = None # to store the start positions for read in fh.fetch(chrom, start, end): # Filter if read.pos < start: # Ensure that a given alignment is processed only once continue if read.flag & 4: continue if args.minMappingQuality and read.mapq < args.minMappingQuality: continue if args.samFlagInclude and read.flag & args.samFlagInclude != args.samFlagInclude: continue if args.samFlagExclude and read.flag & args.samFlagExclude != 0: continue tLen = getTLen(read) if args.minFragmentLength > 0 and tLen < args.minFragmentLength: continue if args.maxFragmentLength > 0 and tLen > args.maxFragmentLength: continue if args.ignoreDuplicates and prev_start_pos \ and prev_start_pos == (read.reference_start, read.pnext, read.is_reverse): continue prev_start_pos = (read.reference_start, read.pnext, read.is_reverse) total[idx] += 1 # Get blocks, possibly extending features = gtf.findOverlaps(chrom, getBAMBlocks(read, defaultFragmentLength, args.centerReads, args.Offset)) if features is not None and len(features) > 0: for x in features: odict[x] += 1 olist.append(odict) return olist, gtf.features, total def plotEnrichment(args, featureCounts, totalCounts, features): # get the number of rows and columns if args.perSample: totalPlots = len(args.bamfiles) barsPerPlot = len(features) else: totalPlots = len(features) barsPerPlot = len(args.bamfiles) cols = min(args.numPlotsPerRow, totalPlots) rows = np.ceil(totalPlots / float(args.numPlotsPerRow)).astype(int) # Handle the colors if not args.colors: cmap_plot = plt.get_cmap('jet') args.colors = cmap_plot(np.arange(barsPerPlot, dtype=float) / float(barsPerPlot)) if len(args.colors) < barsPerPlot: sys.exit("Error: {0} colors were requested, but {1} were needed!".format(len(args.colors), barsPerPlot)) grids = gridspec.GridSpec(rows, cols) plt.rcParams['font.size'] = 10.0 # convert cm values to inches fig = plt.figure(figsize=(args.plotWidth / 2.54, args.plotHeight / 2.54)) fig.suptitle(args.plotTitle, y=(1 - (0.06 / args.plotHeight))) for i in range(totalPlots): col = i % cols row = np.floor(i / float(args.numPlotsPerRow)).astype(int) if args.perSample: xlabels = features ylabel = "% alignments in {0}".format(args.labels[i]) vals = [featureCounts[i][foo] for foo in features] vals = 100 * np.array(vals, dtype='float64') / totalCounts[i] else: xlabels = args.labels ylabel = "% {0}".format(features[i]) vals = [foo[features[i]] for foo in featureCounts] vals = 100 * np.array(vals, dtype='float64') / np.array(totalCounts, dtype='float64') ax = plt.subplot(grids[row, col]) ax.bar(np.arange(vals.shape[0]), vals, width=1.0, bottom=0.0, align='center', color=args.colors, edgecolor=args.colors, alpha=args.alpha) ax.set_ylabel(ylabel) ax.set_xticks(np.arange(vals.shape[0])) ax.set_xticklabels(xlabels, rotation='vertical') if args.variableScales is False: ax.set_ylim(0.0, 100.0) plt.subplots_adjust(wspace=0.05, hspace=0.3, bottom=0.15, top=0.80) plt.tight_layout() plt.savefig(args.plotFile, dpi=200, format=args.plotFileFormat) plt.close() def getChunkLength(args, chromSize): """ There's no point in parsing the GTF time over and over again needlessly. Emprically, it seems that adding ~4x the number of workers is ideal, since coverage is non-uniform. This is a heuristic way of approximating that. Note that if there are MANY small contigs and a few large ones (e.g., the max and median lengths are >10x different, then it's best to take a different tack. """ if args.region: chromSize, region_start, region_end, genomeChunkLength = getUserRegion(chromSize, args.region) rv = np.ceil((region_start - region_end) / float(4 * args.numberOfProcessors)).astype(int) return max(1, rv) bl = None if args.blackListFileName: bl = GTF(args.blackListFileName) lengths = [] for k, v in chromSize: regs = blSubtract(bl, k, [0, v]) for reg in regs: lengths.append(reg[1] - reg[0]) if len(lengths) >= 4 * args.numberOfProcessors: rv = np.median(lengths).astype(int) # In cases like dm6 or GRCh38, there are a LOT of really small contigs, which will cause the median to be small and performance to tank if np.max(lengths) >= 10 * rv: rv = np.ceil(np.sum(lengths) / (4.0 * args.numberOfProcessors)).astype(int) else: rv = np.ceil(np.sum(lengths) / (4.0 * args.numberOfProcessors)).astype(int) return max(1, rv) def main(args=None): args = parse_arguments().parse_args(args) if args.labels is None: args.labels = args.bamfiles if len(args.labels) != len(args.bamfiles): sys.exit("Error: The number of labels ({0}) does not match the number of BAM files ({1})!".format(len(args.labels), len(args.bamfiles))) # Get fragment size and chromosome dict fhs = [openBam(x) for x in args.bamfiles] chromSize, non_common_chr = getCommonChrNames(fhs, verbose=args.verbose) for fh in fhs: fh.close() frag_len_dict, read_len_dict = get_read_and_fragment_length(args.bamfiles[0], return_lengths=False, blackListFileName=args.blackListFileName, numberOfProcessors=args.numberOfProcessors, verbose=args.verbose) if args.extendReads: if args.extendReads is True: # try to guess fragment length if the bam file contains paired end reads if frag_len_dict: defaultFragmentLength = frag_len_dict['median'] else: sys.exit("*ERROR*: library is not paired-end. Please provide an extension length.") if args.verbose: print("Fragment length based on paired en data " "estimated to be {0}".format(frag_len_dict['median'])) elif args.extendReads < read_len_dict['median']: sys.stderr.write("*WARNING*: read extension is smaller than read length (read length = {}). " "Reads will not be extended.\n".format(int(read_len_dict['median']))) defaultFragmentLength = 'read length' elif args.extendReads > 2000: sys.exit("*ERROR*: read extension must be smaller that 2000. Value give: {} ".format(args.extendReads)) else: defaultFragmentLength = args.extendReads else: defaultFragmentLength = 'read length' # Get the chunkLength chunkLength = getChunkLength(args, chromSize) # Map reduce to get the counts/file/feature res = mapReduce([args, defaultFragmentLength], getEnrichment_worker, chromSize, genomeChunkLength=chunkLength, region=args.region, blackListFileName=args.blackListFileName, numberOfProcessors=args.numberOfProcessors, verbose=args.verbose) features = res[0][1] featureCounts = [] for i in list(range(len(args.bamfiles))): d = dict() for x in features: d[x] = 0 featureCounts.append(d) # res is a list, with each element a list (length len(args.bamfiles)) of dicts totalCounts = [0] * len(args.bamfiles) for x in res: for i, y in enumerate(x[2]): totalCounts[i] += y for i, y in enumerate(x[0]): for k, v in y.items(): featureCounts[i][k] += v # Make a plot plotEnrichment(args, featureCounts, totalCounts, features) # Raw counts if args.outRawCounts: of = open(args.outRawCounts, "w") of.write("file\tfeatureType\tpercent\n") for i, x in enumerate(args.labels): for k, v in featureCounts[i].items(): of.write("{0}\t{1}\t{2:5.2f}\n".format(x, k, (100.0 * v) / totalCounts[i])) of.close() deepTools-2.5.0/deeptools/plotFingerprint.py0000640000201600010240000004156513067414642020376 0ustar ryanbioinfo#!/usr/bin/env python # -*- coding: utf-8 -*- import numpy as np import argparse import sys import matplotlib matplotlib.use('Agg') matplotlib.rcParams['pdf.fonttype'] = 42 matplotlib.rcParams['svg.fonttype'] = 'none' import matplotlib.pyplot as plt from scipy import interpolate from scipy.stats import poisson import deeptools.countReadsPerBin as countR import deeptools.sumCoveragePerBin as sumR from deeptools import parserCommon old_settings = np.seterr(all='ignore') MAXLEN = 10000000 def parse_arguments(args=None): parent_parser = parserCommon.getParentArgParse(binSize=False) required_args = get_required_args() output_args = get_output_args() optional_args = get_optional_args() read_options_parser = parserCommon.read_options() parser = argparse.ArgumentParser( parents=[required_args, output_args, read_options_parser, optional_args, parent_parser], formatter_class=argparse.ArgumentDefaultsHelpFormatter, description='This tool samples indexed BAM files ' 'and plots a profile of cumulative read coverages for each. ' 'All reads overlapping a window (bin) of the ' 'specified length are counted; ' 'these counts are sorted ' 'and the cumulative sum is finally plotted. ', conflict_handler='resolve', usage='An example usage is: plotFingerprint -b treatment.bam control.bam ' '-plot fingerprint.png', add_help=False) return parser def process_args(args=None): args = parse_arguments().parse_args(args) if args.labels and len(args.bamfiles) != len(args.labels): print("The number of labels does not match the number of BAM files.") exit(0) if not args.labels: args.labels = args.bamfiles return args def get_required_args(): parser = argparse.ArgumentParser(add_help=False) required = parser.add_argument_group('Required arguments') # define the arguments required.add_argument('--bamfiles', '-b', metavar='bam files', nargs='+', help='List of indexed BAM files', required=True) return parser def get_optional_args(): parser = argparse.ArgumentParser(add_help=False, conflict_handler='resolve') optional = parser.add_argument_group('Optional arguments') optional.add_argument("--help", "-h", action="help", help="show this help message and exit") optional.add_argument('--labels', '-l', metavar='', help='List of labels to use in the output. ' 'If not given, the file names will be used instead. ' 'Separate the labels by spaces.', nargs='+') optional.add_argument('--binSize', '-bs', help='Window size in base pairs to ' 'sample the genome.', default=500, type=int) optional.add_argument('--numberOfSamples', '-n', help='Number of bins that sampled from the genome, ' 'for which the overlapping number of reads is computed.', default=5e5, type=int) optional.add_argument('--plotFileFormat', metavar='', help='image format type. If given, this option ' 'overrides the image format based on the ending ' 'given via --plotFile ' 'ending. The available options are: "png", ' '"eps", "pdf" and "svg"', choices=['png', 'pdf', 'svg', 'eps']) optional.add_argument('--plotTitle', '-T', help='Title of the plot, to be printed on top of ' 'the generated image. Leave blank for no title.', default='') optional.add_argument('--skipZeros', help='If set, then regions with zero overlapping reads' 'for *all* given BAM files are ignored. This ' 'will result in a reduced number of read ' 'counts than that specified in --numberOfSamples', action='store_true') optional.add_argument('--outQualityMetrics', help='Quality metrics can optionally be output to ' 'this file. The file will have one row per input BAM ' 'file and columns containing a number of metrics. ' 'Please see the online documentation for a longer ' 'explanation: http://deeptools.readthedocs.io/en/latest/content/feature/plotFingerprint_QC_metrics.html .', metavar='FILE.txt', type=argparse.FileType('w')) optional.add_argument('--JSDsample', help='Reference sample against which to compute the ' 'Jensen-Shannon distance and the CHANCE statistics. ' 'If this is not specified, ' 'then these will not be calculated. If ' '--outQualityMetrics is not specified then this will ' 'be ignored. The Jensen-Shannon implementation is ' 'based on code from Sitanshu Gakkhar at BCGSC. The ' 'CHANCE implementation is based on code from Matthias ' 'Haimel.', metavar='sample.bam') return parser def get_output_args(): parser = argparse.ArgumentParser(add_help=False) group = parser.add_argument_group('Output') group.add_argument('--plotFile', '-plot', help='File name of the output figure. The file ' 'ending will be used to determine the image ' 'format. The available options are typically: "png", ' '"eps", "pdf" and "svg", e.g. : fingerprint.png.', metavar='', type=argparse.FileType('w'), required=True) group.add_argument('--outRawCounts', help='Output file name to save the read counts per bin.', metavar='', type=argparse.FileType('w')) return parser def binRelEntropy(p, q): """ Return the relative binary entropy of x """ x1 = 0 x2 = 0 if p > 0: x1 = p * np.log2(p / q) if p < 1: x2 = (1 - p) * np.log2((1 - p) / (1 - q)) return np.fmax(0.0, x1 + x2) def getCHANCE(args, idx, mat): """ Compute the CHANCE p-value 1) In short, sort IP from lowest to highest, cosorting input at the same time. 2) Choose the argmax of the difference of the cumsum() of the above 3) Determine a scale factor according to the ratio at the position at step 2. """ # Get the index of the reference sample if args.JSDsample not in args.bamfiles: return ["NA", "NA", "NA"] refIdx = args.bamfiles.index(args.JSDsample) if refIdx == idx: return ["NA", "NA", "NA"] subMatrix = np.copy(mat[:, [idx, refIdx]]) subMatrix[np.isnan(subMatrix)] = 0 subMatrix = subMatrix[subMatrix[:, 0].argsort(), :] # Find the CHANCE statistic, which is the point of maximus difference cs = np.cumsum(subMatrix, axis=0) normed = cs / np.max(cs, axis=0).astype(float) csdiff = normed[:, 1] - normed[:, 0] k = np.argmax(csdiff) if csdiff[k] < 1e-6: # Don't bother with negative values return [0, 0, 0] p = normed[k, 0] # Percent enrichment in IP q = normed[k, 1] # Percent enrichment in input pcenrich = 100 * (len(csdiff) - k) / float(len(csdiff)) diffenrich = 100.0 * (q - p) # CHANCE's JS divergence with binary entropy # Its p value is a ztest of this, which is largely useless IMO M = (p + q) / 2.0 CHANCEdivergence = 0.5 * (binRelEntropy(p, M) + binRelEntropy(q, M)) CHANCEdivergence = np.sqrt(CHANCEdivergence) return [pcenrich, diffenrich, CHANCEdivergence] def getSyntheticJSD(vec): """ This is largely similar to getJSD, with the 'input' sample being a Poisson distribution with lambda the average coverage in the IP bins """ lamb = np.mean(vec) # Average coverage coverage = np.sum(vec) chip = np.zeros(MAXLEN, dtype=np.int) for val in vec: # N.B., we need to clip past the end of the array if val >= MAXLEN: val = MAXLEN - 1 # This effectively removes differences due to coverage percentages if val > 0: chip[int(val)] += 1 input = coverage * poisson.pmf(np.arange(1, MAXLEN), lamb) if chip[-1] > 0: print("{} bins had coverage over the maximum value of {} during synthetic JSD computation".format(chip[-1], MAXLEN)) return getJSDcommon(chip, input) def getJSD(args, idx, mat): """ Computes the Jensen-Shannon distance between two samples. This is essentially a symmetric version of Kullback-Leibler divergence. The implementation presented here is based on code from Sitanshu Gakkhar at BCGSC. Note that the interpolation has the effect of removing zero count coverage bins, which ends up being needed for the JSD calculation. args: The input arguments idx: The column index of the current sample mat: The matrix of counts """ # Get the index of the reference sample if args.JSDsample not in args.bamfiles: return "NA" refIdx = args.bamfiles.index(args.JSDsample) if refIdx == idx: return "NA" # These will hold the coverage histograms chip = np.zeros(MAXLEN, dtype=np.int) input = np.zeros(MAXLEN, dtype=np.int) for row in mat: # ChIP val = row[idx] # N.B., we need to clip past the end of the array if val >= MAXLEN: val = MAXLEN - 1 # This effectively removes differences due to coverage percentages if val > 0: chip[int(val)] += 1 # Input val = row[refIdx] if val >= MAXLEN: val = MAXLEN - 1 if val > 0: input[int(val)] += 1 if input[-1] > 0: print("{} bins had coverage over the maximum value of {} in the input sample".format(input[-1], MAXLEN)) if chip[-1] > 0: print("{} bins had coverage over the maximum value of {} in the ChIP sample".format(chip[-1], MAXLEN)) return getJSDcommon(chip, input) def getJSDcommon(chip, input): """ This is a continuation of getJSD to allow getSyntheticJSD to reuse code """ def signalAndBinDist(x): x = np.array(x) (n,) = x.shape signalValues = np.array(list(range(n))) totalSignal = x * signalValues normalizedTotalSignal = np.cumsum(totalSignal) / np.sum(totalSignal).astype("float") binDist = np.cumsum(x).astype("float") / sum(x) interpolater = interpolate.interp1d(binDist, normalizedTotalSignal, kind='linear', bounds_error=False, fill_value=(0, 1)) return (binDist, normalizedTotalSignal, interpolater) # Interpolate the signals to evenly spaced bins, which also removes 0-coverage bins chipSignal = signalAndBinDist(chip) inputSignal = signalAndBinDist(input) # These are basically CDFs inputSignalInterp = inputSignal[2](np.arange(0, 1.00001, 0.00001)) chipSignalInterp = chipSignal[2](np.arange(0, 1.00001, 0.00001)) # If there are no low coverage bins then you can get nan as the first interpolated value. # That should instead be some small value if np.isnan(inputSignalInterp[0]): inputSignalInterp[0] = 1e-12 if np.isnan(chipSignalInterp[0]): chipSignalInterp[0] = 1e-12 # Differentiate to PMFs, do some sanity checking PMFinput = np.ediff1d(inputSignalInterp) PMFchip = np.ediff1d(chipSignalInterp) if abs(sum(PMFinput) - 1) > 0.01 or abs(sum(PMFchip) - 1) > 0.01: sys.stderr.write("Warning: At least one PMF integral is significantly different from 1! The JSD will not be returned") return "NA" # Compute the JSD from the PMFs M = (PMFinput + PMFchip) / 2.0 JSD = 0.5 * (np.nansum(PMFinput * np.log2(PMFinput / M))) + 0.5 * (np.nansum(PMFchip * np.log2(PMFchip / M))) return np.sqrt(JSD) def getExpected(mu): """ Given a mean coverage mu, determine the AUC, X-intercept, and elbow point of a Poisson-distributed perfectly behaved input sample with the same coverage """ x = np.arange(round(poisson.interval(0.99999, mu=mu)[1] + 1)) # This will be an appropriate range pmf = poisson.pmf(x, mu=mu) cdf = poisson.cdf(x, mu=mu) cs = np.cumsum(pmf * x) cs /= max(cs) XInt = cdf[np.nonzero(cs)[0][0]] AUC = sum(poisson.pmf(x, mu=mu) * cs) elbow = cdf[np.argmax(cdf - cs)] return (AUC, XInt, elbow) def main(args=None): args = process_args(args) cr = sumR.SumCoveragePerBin( args.bamfiles, args.binSize, args.numberOfSamples, blackListFileName=args.blackListFileName, numberOfProcessors=args.numberOfProcessors, verbose=args.verbose, region=args.region, extendReads=args.extendReads, minMappingQuality=args.minMappingQuality, ignoreDuplicates=args.ignoreDuplicates, center_read=args.centerReads, samFlag_include=args.samFlagInclude, samFlag_exclude=args.samFlagExclude, minFragmentLength=args.minFragmentLength, maxFragmentLength=args.maxFragmentLength) num_reads_per_bin = cr.run() if num_reads_per_bin.sum() == 0: import sys sys.stderr.write( "\nNo reads were found in {} regions sampled. Check that the\n" "min mapping quality is not overly high and that the \n" "chromosome names between bam files are consistant.\n" "\n".format(num_reads_per_bin.shape[0])) exit(1) if args.skipZeros: num_reads_per_bin = countR.remove_row_of_zeros(num_reads_per_bin) total = len(num_reads_per_bin[:, 0]) x = np.arange(total).astype('float') / total # normalize from 0 to 1 i = 0 # matplotlib won't iterate through line styles by itself pyplot_line_styles = sum([7 * ["-"], 7 * ["--"], 7 * ["-."], 7 * [":"], 7 * ["."]], []) for i, reads in enumerate(num_reads_per_bin.T): count = np.cumsum(np.sort(reads)) count = count / count[-1] # to normalize y from 0 to 1 j = i % 35 plt.plot(x, count, label=args.labels[i], linestyle=pyplot_line_styles[j]) plt.xlabel('rank') plt.ylabel('fraction w.r.t. bin with highest coverage') plt.legend(loc='upper left') plt.suptitle(args.plotTitle) # set the plotFileFormat explicitly to None to trigger the # format from the file-extension if not args.plotFileFormat: args.plotFileFormat = None plt.savefig(args.plotFile.name, bbox_inches=0, format=args.plotFileFormat) plt.close() if args.outRawCounts: args.outRawCounts.write("'" + "'\t'".join(args.labels) + "'\n") fmt = "\t".join(np.repeat('%d', num_reads_per_bin.shape[1])) + "\n" for row in num_reads_per_bin: args.outRawCounts.write(fmt % tuple(row)) args.outRawCounts.close() if args.outQualityMetrics: args.outQualityMetrics.write("Sample\tAUC\tSynthetic AUC\tX-intercept\tSynthetic X-intercept\tElbow Point\tSynthetic Elbow Point") if args.JSDsample: args.outQualityMetrics.write("\tJS Distance\tSynthetic JS Distance\t% genome enriched\tdiff. enrichment\tCHANCE divergence") args.outQualityMetrics.write("\n") line = np.arange(num_reads_per_bin.shape[0]) / float(num_reads_per_bin.shape[0] - 1) for idx, reads in enumerate(num_reads_per_bin.T): counts = np.cumsum(np.sort(reads)) counts = counts / float(counts[-1]) AUC = np.sum(counts) / float(len(counts)) XInt = (np.argmax(counts > 0) + 1) / float(counts.shape[0]) elbow = (np.argmax(line - counts) + 1) / float(counts.shape[0]) expected = getExpected(np.mean(reads)) # A tuple of expected (AUC, XInt, elbow) args.outQualityMetrics.write("{0}\t{1}\t{2}\t{3}\t{4}\t{5}\t{6}".format(args.labels[idx], AUC, expected[0], XInt, expected[1], elbow, expected[2])) if args.JSDsample: JSD = getJSD(args, idx, num_reads_per_bin) syntheticJSD = getSyntheticJSD(num_reads_per_bin[:, idx]) CHANCE = getCHANCE(args, idx, num_reads_per_bin) args.outQualityMetrics.write("\t{0}\t{1}\t{2}\t{3}\t{4}".format(JSD, syntheticJSD, CHANCE[0], CHANCE[1], CHANCE[2])) args.outQualityMetrics.write("\n") args.outQualityMetrics.close() if __name__ == "__main__": main() deepTools-2.5.0/deeptools/plotHeatmap.py0000640000201600010240000006373313067414642017467 0ustar ryanbioinfo#!/usr/bin/env python # -*- coding: utf-8 -*- from __future__ import division import argparse from collections import OrderedDict import numpy as np import matplotlib matplotlib.use('Agg') matplotlib.rcParams['pdf.fonttype'] = 42 matplotlib.rcParams['svg.fonttype'] = 'none' import matplotlib.pyplot as plt from matplotlib.font_manager import FontProperties import matplotlib.gridspec as gridspec from matplotlib import ticker import sys # own modules from deeptools import parserCommon from deeptools import heatmapper from deeptools.heatmapper_utilities import plot_single, getProfileTicks debug = 0 old_settings = np.seterr(all='ignore') plt.ioff() def parse_arguments(args=None): parser = argparse.ArgumentParser( parents=[parserCommon.heatmapperMatrixArgs(), parserCommon.heatmapperOutputArgs(mode='heatmap'), parserCommon.heatmapperOptionalArgs(mode='heatmap')], formatter_class=argparse.ArgumentDefaultsHelpFormatter, description='This tool creates a heatmap for ' 'scores associated with genomic regions. ' 'The program requires a matrix file ' 'generated by the tool ``computeMatrix``.', epilog='An example usage is: plotHeatmap -m ', add_help=False) return parser def process_args(args=None): args = parse_arguments().parse_args(args) args.heatmapHeight = args.heatmapHeight if args.heatmapHeight > 3 and args.heatmapHeight <= 100 else 10 if not matplotlib.colors.is_color_like(args.missingDataColor): exit("The value {0} for --missingDataColor is not valid".format(args.missingDataColor)) args.boxAroundHeatmaps = True if args.boxAroundHeatmaps == 'yes' else False return args def get_heatmap_ticks(hm, reference_point_label, startLabel, endLabel): """ returns the position and labelling of the xticks that correspond to the heatmap """ w = hm.parameters['bin size'] b = hm.parameters['upstream'] a = hm.parameters['downstream'] c = hm.parameters.get('unscaled 5 prime', 0) d = hm.parameters.get('unscaled 3 prime', 0) m = hm.parameters['body'] if b < 1e5: quotient = 1000 symbol = 'Kb' else: quotient = 1e6 symbol = 'Mb' if m == 0: xticks = [(k / w) for k in [0, b, b + a]] xticks_label = ['{0:.1f}'.format(-(float(b) / quotient)), reference_point_label, '{0:.1f}{1}'.format(float(a) / quotient, symbol)] else: xticks_values = [0] xticks_label = [] # only if upstream region is set, add a x tick if b > 0: xticks_values.append(b) xticks_label.append('{0:.1f}'.format(-(float(b) / quotient))) xticks_label.append(startLabel) # 5 prime unscaled tick/label, if needed if c > 0: xticks_values.append(b + c) xticks_label.append('') # set the x tick for the body parameter, regardless if # upstream is 0 (not set) if d > 0: xticks_values.append(b + c + m) xticks_label.append('') xticks_values.append(b + c + m + d) xticks_label.append(endLabel) if a > 0: xticks_values.append(b + c + m + d + a) xticks_label.append('{0:.1f}{1}'.format(float(a) / quotient, symbol)) xticks = [k / w for k in xticks_values] return xticks, xticks_label def prepare_layout(hm_matrix, heatmapsize, showSummaryPlot, showColorbar, perGroup, colorbar_position): """ prepare the plot layout as a grid having as many rows as samples (+1 for colobar) and as many rows as groups (or clusters) (+1 for profile plot) """ heatmapwidth, heatmapheight = heatmapsize numcols = hm_matrix.get_num_samples() numrows = hm_matrix.get_num_groups() if perGroup: numcols, numrows = numrows, numcols # the rows have different size depending # on the number of regions contained in the if perGroup: # heatmap height_ratio = np.array([np.amax(np.diff(hm_matrix.group_boundaries))] * numrows) # scale ratio to sum = heatmapheight height_ratio = heatmapheight * (height_ratio.astype(float) / height_ratio.sum()) else: # heatmap height_ratio = np.diff(hm_matrix.group_boundaries) # scale ratio to sum = heatmapheight height_ratio = heatmapheight * (height_ratio.astype(float) / height_ratio.sum()) # convert the height_ratio from numpy array back to list height_ratio = height_ratio.tolist() # the width ratio is equal for all heatmaps width_ratio = [heatmapwidth] * numcols if showColorbar: if colorbar_position == 'below': numrows += 2 # a spacer needs to be added to avoid overlaps height_ratio += [4 / 2.54] # spacer height_ratio += [1 / 2.54] else: numcols += 1 width_ratio += [1 / 2.54] if showSummaryPlot: numrows += 2 # plus 2 because a spacer is added # make height of summary plot # proportional to the width of heatmap sumplot_height = heatmapwidth spacer_height = heatmapwidth / 8 # scale height_ratios to convert from row # numbers to heatmapheigt fractions height_ratio = np.concatenate([[sumplot_height, spacer_height], height_ratio]) grids = gridspec.GridSpec(numrows, numcols, height_ratios=height_ratio, width_ratios=width_ratio) return grids def addProfilePlot(hm, plt, fig, grids, iterNum, iterNum2, perGroup, averageType, xticks, xtickslabel, yAxisLabel, color_list, yMin, yMax, wspace, hspace, colorbar_position): """ A function to add profile plots to the given figure, possibly in a custom grid subplot which mimics a tight layout (if wspace and hspace are not None) """ if wspace is not None and hspace is not None: if colorbar_position == 'side': gridsSub = gridspec.GridSpecFromSubplotSpec(1, iterNum, subplot_spec=grids[0, :-1], wspace=wspace, hspace=hspace) else: gridsSub = gridspec.GridSpecFromSubplotSpec(1, iterNum, subplot_spec=grids[0, :], wspace=wspace, hspace=hspace) ax_list = [] for sample_id in range(iterNum): if perGroup: title = hm.matrix.group_labels[sample_id] else: title = hm.matrix.sample_labels[sample_id] if sample_id > 0 and len(yMin) == 1 and len(yMax) == 1: ax_profile = fig.add_subplot(grids[0, sample_id], sharey=ax_list[0]) else: if wspace is not None and hspace is not None: ax_profile = fig.add_subplot(gridsSub[0, sample_id]) else: ax_profile = fig.add_subplot(grids[0, sample_id]) ax_profile.set_title(title) for group in range(iterNum2): if perGroup: sub_matrix = hm.matrix.get_matrix(sample_id, group) line_label = sub_matrix['sample'] else: sub_matrix = hm.matrix.get_matrix(group, sample_id) line_label = sub_matrix['group'] plot_single(ax_profile, sub_matrix['matrix'], averageType, color_list[group], line_label, plot_type='simple') if sample_id > 0 and len(yMin) == 1 and len(yMax) == 1: plt.setp(ax_profile.get_yticklabels(), visible=False) if sample_id == 0 and yAxisLabel != '': ax_profile.set_ylabel(yAxisLabel) if np.ceil(max(xticks)) != float(sub_matrix['matrix'].shape[1]): tickscale = float(sub_matrix['matrix'].shape[1]) / max(xticks) xticks_use = [x * tickscale for x in xticks] ax_profile.axes.set_xticks(xticks_use) else: ax_profile.axes.set_xticks(xticks) ax_profile.axes.set_xticklabels(xtickslabel) ax_list.append(ax_profile) # align the first and last label # such that they don't fall off # the heatmap sides ticks = ax_profile.xaxis.get_major_ticks() ticks[0].label1.set_horizontalalignment('left') ticks[-1].label1.set_horizontalalignment('right') # It turns out that set_ylim only takes np.float64s localYMin = yMin[sample_id % len(yMin)] localYMax = yMax[sample_id % len(yMax)] lims = ax_list[0].get_ylim() if localYMin: lims = (np.float64(localYMin), lims[1]) if localYMax: lims = (lims[0], np.float64(localYMax)) if lims[0] >= lims[1]: lims = (lims[0], lims[0] + 1) if len(yMin) == 1 and len(yMax) == 1: ax_list[0].set_ylim(lims) else: ax_list[-1].set_ylim(lims) return ax_list def plotMatrix(hm, outFileName, colorMapDict={'colorMap': ['binary'], 'missingDataColor': 'black', 'alpha': 1.0}, plotTitle='', xAxisLabel='', yAxisLabel='', regionsLabel='', zMin=None, zMax=None, yMin=None, yMax=None, averageType='median', reference_point_label='TSS', startLabel='TSS', endLabel="TES", heatmapHeight=25, heatmapWidth=7.5, perGroup=False, whatToShow='plot, heatmap and colorbar', image_format=None, legend_location='upper-left', box_around_heatmaps=True, dpi=200): matrix_flatten = None if zMin is None: matrix_flatten = hm.matrix.flatten() # try to avoid outliers by using np.percentile zMin = np.percentile(matrix_flatten, 1.0) if np.isnan(zMin): zMin = [None] else: zMin = [zMin] # convert to list to support multiple entries if zMax is None: if matrix_flatten is None: matrix_flatten = hm.matrix.flatten() # try to avoid outliers by using np.percentile zMax = np.percentile(matrix_flatten, 98.0) if np.isnan(zMax) or zMax <= zMin[0]: zMax = [None] else: zMax = [zMax] if yMin is None: yMin = [None] if yMax is None: yMax = [None] if not isinstance(yMin, list): yMin = [yMin] if not isinstance(yMax, list): yMax = [yMax] plt.rcParams['font.size'] = 8.0 fontP = FontProperties() showSummaryPlot = False showColorbar = False if whatToShow == 'plot and heatmap': showSummaryPlot = True elif whatToShow == 'heatmap and colorbar': showColorbar = True elif whatToShow == 'plot, heatmap and colorbar': showSummaryPlot = True showColorbar = True # colormap for the heatmap if colorMapDict['colorMap']: cmap = [] for color_map in colorMapDict['colorMap']: cmap.append(plt.get_cmap(color_map)) cmap[-1].set_bad(colorMapDict['missingDataColor']) # nans are printed using this color if colorMapDict['colorList'] and len(colorMapDict['colorList']) > 0: # make a cmap for each color list given cmap = [] for color_list in colorMapDict['colorList']: cmap.append(matplotlib.colors.LinearSegmentedColormap.from_list( 'my_cmap', color_list.replace(' ', '').split(","), N=colorMapDict['colorNumber'])) cmap[-1].set_bad(colorMapDict['missingDataColor']) # nans are printed using this color if len(cmap) > 1 or len(zMin) > 1 or len(zMax) > 1: # position color bar below heatmap when more than one # heatmap color is given colorbar_position = 'below' else: colorbar_position = 'side' grids = prepare_layout(hm.matrix, (heatmapWidth, heatmapHeight), showSummaryPlot, showColorbar, perGroup, colorbar_position) # figsize: w,h tuple in inches figwidth = heatmapWidth / 2.54 figheight = heatmapHeight / 2.54 if showSummaryPlot: # the summary plot ocupies a height # equal to the fig width figheight += figwidth numsamples = hm.matrix.get_num_samples() if perGroup: num_cols = hm.matrix.get_num_groups() else: num_cols = numsamples total_figwidth = figwidth * num_cols if showColorbar: if colorbar_position == 'below': figheight += 1 / 2.54 else: total_figwidth += 1 / 2.54 fig = plt.figure(figsize=(total_figwidth, figheight)) xticks, xtickslabel = getProfileTicks(hm, reference_point_label, startLabel, endLabel) xticks_heat, xtickslabel_heat = get_heatmap_ticks(hm, reference_point_label, startLabel, endLabel) fig.suptitle(plotTitle, y=1 - (0.06 / figheight)) # color map for the summary plot (profile) on top of the heatmap cmap_plot = plt.get_cmap('jet') numgroups = hm.matrix.get_num_groups() if perGroup: color_list = cmap_plot(np.arange(hm.matrix.get_num_samples()) / hm.matrix.get_num_samples()) else: color_list = cmap_plot(np.arange(numgroups) / numgroups) alpha = colorMapDict['alpha'] # check if matrix is reference-point based using the upstream >0 value # and is sorted by region length. If this is # the case, prepare the data to plot a border at the regions end if hm.parameters['upstream'] > 0 and \ hm.matrix.sort_using == 'region_length' and \ hm.matrix.sort_method != 'no': _regions = hm.matrix.get_regions() regions_length_in_bins = [] for _group in _regions: _reg_len = [] for ind_reg in _group: if isinstance(ind_reg, dict): _len = ind_reg['end'] - ind_reg['start'] else: _len = sum([x[1] - x[0] for x in ind_reg[1]]) _reg_len.append((hm.parameters['upstream'] + _len) / hm.parameters['bin size']) regions_length_in_bins.append(_reg_len) else: regions_length_in_bins = None # plot the profiles on top of the heatmaps if showSummaryPlot: if perGroup: iterNum = numgroups iterNum2 = hm.matrix.get_num_samples() else: iterNum = hm.matrix.get_num_samples() iterNum2 = numgroups ax_list = addProfilePlot(hm, plt, fig, grids, iterNum, iterNum2, perGroup, averageType, xticks, xtickslabel, yAxisLabel, color_list, yMin, yMax, None, None, colorbar_position) if len(yMin) > 1 or len(yMax) > 1: # replot with a tight layout import matplotlib.tight_layout as tl specList = tl.get_subplotspec_list(fig.axes, grid_spec=grids) renderer = tl.get_renderer(fig) kwargs = tl.get_tight_layout_figure(fig, fig.axes, specList, renderer, pad=1.08) for ax in ax_list: fig.delaxes(ax) ax_list = addProfilePlot(hm, plt, fig, grids, iterNum, iterNum2, perGroup, averageType, xticks, xtickslabel, yAxisLabel, color_list, yMin, yMax, kwargs['wspace'], kwargs['hspace'], colorbar_position) # reduce the number of yticks by half num_ticks = len(ax_list[0].get_yticks()) yticks = [ax_list[0].get_yticks()[i] for i in range(1, num_ticks, 2)] ax_list[0].set_yticks(yticks) if legend_location != 'none': ax_list[-1].legend(loc=legend_location.replace('-', ' '), ncol=1, prop=fontP, frameon=False, markerscale=0.5) first_group = 0 # helper variable to place the title per sample/group for sample in range(hm.matrix.get_num_samples()): sample_idx = sample for group in range(numgroups): group_idx = group # add the respective profile to the # summary plot sub_matrix = hm.matrix.get_matrix(group, sample) if showSummaryPlot: if perGroup: sample_idx = sample + 2 # plot + spacer else: group += 2 # plot + spacer first_group = 1 if perGroup: ax = fig.add_subplot(grids[sample_idx, group]) # the remainder (%) is used to iterate # over the available color maps (cmap). # if the user only provided, lets say two # and there are 10 groups, colormaps they are reused every # two groups. cmap_idx = group_idx % len(cmap) zmin_idx = group_idx % len(zMin) zmax_idx = group_idx % len(zMax) else: ax = fig.add_subplot(grids[group, sample]) # see above for the use of '%' cmap_idx = sample % len(cmap) zmin_idx = sample % len(zMin) zmax_idx = sample % len(zMax) if group == first_group and not showSummaryPlot and not perGroup: title = hm.matrix.sample_labels[sample] ax.set_title(title) if box_around_heatmaps is False: # Turn off the boxes around the individual heatmaps ax.spines['top'].set_visible(False) ax.spines['right'].set_visible(False) ax.spines['bottom'].set_visible(False) ax.spines['left'].set_visible(False) rows, cols = sub_matrix['matrix'].shape interpolation_type = None if rows >= 1000 and cols >= 200 else 'nearest' img = ax.imshow(sub_matrix['matrix'], aspect='auto', interpolation=interpolation_type, origin='upper', vmin=zMin[zmin_idx], vmax=zMax[zmax_idx], cmap=cmap[cmap_idx], alpha=alpha, extent=[0, cols, rows, 0]) img.set_rasterized(True) # plot border at the end of the regions # if ordered by length if regions_length_in_bins is not None: x_lim = ax.get_xlim() y_lim = ax.get_ylim() ax.plot(regions_length_in_bins[group_idx], np.arange(len(regions_length_in_bins[group_idx])), '--', color='black', linewidth=0.5, dashes=(3, 2)) ax.set_xlim(x_lim) ax.set_ylim(y_lim) if perGroup: ax.axes.set_xlabel(sub_matrix['group']) if sample < hm.matrix.get_num_samples() - 1: ax.axes.get_xaxis().set_visible(False) else: ax.axes.get_xaxis().set_visible(False) ax.axes.set_xlabel(xAxisLabel) ax.axes.set_yticks([]) if perGroup and group == 0: ax.axes.set_ylabel(sub_matrix['sample']) elif not perGroup and sample == 0: ax.axes.set_ylabel(sub_matrix['group']) # add labels to last block in a column if (perGroup and sample == numsamples - 1) or \ (not perGroup and group_idx == numgroups - 1): # add xticks to the bottom heatmap (last group) ax.axes.get_xaxis().set_visible(True) if np.ceil(max(xticks_heat)) != float(sub_matrix['matrix'].shape[1]): tickscale = float(sub_matrix['matrix'].shape[1]) / max(xticks_heat) xticks_heat_use = [x * tickscale for x in xticks_heat] ax.axes.set_xticks(xticks_heat_use) else: ax.axes.set_xticks(xticks_heat) ax.axes.set_xticklabels(xtickslabel_heat, size=8) # align the first and last label # such that they don't fall off # the heatmap sides ticks = ax.xaxis.get_major_ticks() ticks[0].label1.set_horizontalalignment('left') ticks[-1].label1.set_horizontalalignment('right') ax.get_xaxis().set_tick_params( which='both', top='off', direction='out') if showColorbar and colorbar_position == 'below': # draw a colormap per each heatmap below the last block if perGroup: col = group_idx else: col = sample ax = fig.add_subplot(grids[-1, col]) tick_locator = ticker.MaxNLocator(nbins=3) cbar = fig.colorbar(img, cax=ax, alpha=alpha, orientation='horizontal', ticks=tick_locator) labels = cbar.ax.get_xticklabels() ticks = cbar.ax.get_xticks() if ticks[0] == 0: # if the label is at the start of the colobar # move it a bit inside to avoid overlapping # with other labels labels[0].set_horizontalalignment('left') if ticks[-1] == 1: # if the label is at the end of the colobar # move it a bit inside to avoid overlapping # with other labels labels[-1].set_horizontalalignment('right') # cbar.ax.set_xticklabels(labels, rotation=90) if showColorbar and colorbar_position != 'below': if showSummaryPlot: # we don't want to colorbar to extend # over the profiles and spacer top rows grid_start = 2 else: grid_start = 0 ax = fig.add_subplot(grids[grid_start:, -1]) fig.colorbar(img, cax=ax, alpha=alpha) if box_around_heatmaps: plt.subplots_adjust(wspace=0.10, hspace=0.025, top=0.85, bottom=0, left=0.04, right=0.96) else: # When no box is plotted the space between heatmaps is reduced plt.subplots_adjust(wspace=0.05, hspace=0.01, top=0.85, bottom=0, left=0.04, right=0.96) plt.savefig(outFileName, bbox_inches='tight', pdd_inches=0, dpi=dpi, format=image_format) plt.close() def mergeSmallGroups(matrixDict): group_lengths = [len(x) for x in matrixDict.values()] min_group_length = sum(group_lengths) * 0.01 to_merge = [] i = 0 _mergedHeatMapDict = OrderedDict() for label, ma in matrixDict.items(): # merge small groups together # otherwise visualization is impaired if group_lengths[i] > min_group_length: if len(to_merge): to_merge.append(label) new_label = " ".join(to_merge) new_ma = np.concatenate([matrixDict[item] for item in to_merge], axis=0) else: new_label = label new_ma = matrixDict[label] _mergedHeatMapDict[new_label] = new_ma to_merge = [] else: to_merge.append(label) i += 1 if len(to_merge) > 1: new_label = " ".join(to_merge) new_ma = np.array() for item in to_merge: new_ma = np.concatenate([new_ma, matrixDict[item]]) _mergedHeatMapDict[new_label] = new_ma return _mergedHeatMapDict def main(args=None): args = process_args(args) hm = heatmapper.heatmapper() matrix_file = args.matrixFile.name args.matrixFile.close() hm.read_matrix_file(matrix_file) if args.kmeans is not None: hm.matrix.hmcluster(args.kmeans, method='kmeans') else: if args.hclust is not None: print("Performing hierarchical clustering." "Please note that it might be very slow for large datasets.\n") hm.matrix.hmcluster(args.hclust, method='hierarchical') group_len_ratio = np.diff(hm.matrix.group_boundaries) / len(hm.matrix.regions) if np.any(group_len_ratio < 5.0 / 1000): problem = np.flatnonzero(group_len_ratio < 5.0 / 1000) sys.stderr.write("WARNING: Group '{}' is too small for plotting, you might want to remove it. " "There will likely be an error message from matplotlib regarding this " "below.\n".format(hm.matrix.group_labels[problem[0]])) if args.regionsLabel: hm.matrix.set_group_labels(args.regionsLabel) if args.samplesLabel and len(args.samplesLabel): hm.matrix.set_sample_labels(args.samplesLabel) if args.sortRegions != 'no': sortUsingSamples = [] if args.sortUsingSamples is not None: for i in args.sortUsingSamples: if (i > 0 and i <= hm.matrix.get_num_samples()): sortUsingSamples.append(i - 1) else: exit("The value {0} for --sortSamples is not valid. Only values from 1 to {1} are allowed.".format(args.sortUsingSamples, hm.matrix.get_num_samples())) print('Samples used for ordering within each group: ', sortUsingSamples) hm.matrix.sort_groups(sort_using=args.sortUsing, sort_method=args.sortRegions, sample_list=sortUsingSamples) if args.outFileNameMatrix: hm.save_matrix_values(args.outFileNameMatrix) if args.outFileSortedRegions: hm.save_BED(args.outFileSortedRegions) colormap_dict = {'colorMap': args.colorMap, 'colorList': args.colorList, 'colorNumber': args.colorNumber, 'missingDataColor': args.missingDataColor, 'alpha': args.alpha} plotMatrix(hm, args.outFileName, colormap_dict, args.plotTitle, args.xAxisLabel, args.yAxisLabel, args.regionsLabel, args.zMin, args.zMax, args.yMin, args.yMax, args.averageTypeSummaryPlot, args.refPointLabel, args.startLabel, args.endLabel, args.heatmapHeight, args.heatmapWidth, args.perGroup, args.whatToShow, image_format=args.plotFileFormat, legend_location=args.legendLocation, box_around_heatmaps=args.boxAroundHeatmaps, dpi=args.dpi) deepTools-2.5.0/deeptools/plotPCA.py0000640000201600010240000001110713067414642016477 0ustar ryanbioinfo#!/usr/bin/env python # -*- coding: utf-8 -*- import argparse import matplotlib matplotlib.use('Agg') matplotlib.rcParams['pdf.fonttype'] = 42 matplotlib.rcParams['svg.fonttype'] = 'none' from deeptools.correlation import Correlation from deeptools._version import __version__ def parse_arguments(args=None): basic_args = plotCorrelationArgs() parser = argparse.ArgumentParser( formatter_class=argparse.RawDescriptionHelpFormatter, description=""" Tool for generating a principal component analysis (PCA) plot from multiBamSummary or multiBigwigSummary output. Detailed help: plotPCA -h """, epilog='example usages:\n' 'plotPCA -in coverages.npz -o pca.png\n\n' ' \n\n', parents=[basic_args, ]) return parser def plotCorrelationArgs(): parser = argparse.ArgumentParser(add_help=False) required = parser.add_argument_group('Required arguments') # define the arguments required.add_argument('--corData', '-in', metavar='FILE', help='Coverage file (generated by multiBamSummary or multiBigwigSummary)', required=True) required.add_argument('--plotFile', '-o', help='File name to save the plot to. ' 'The extension determines the file format. ' 'For example: ' 'pca.pdf will save the PCA plot in PDF format. ' 'The available options are: .png, ' '.eps, .pdf and .svg.', type=argparse.FileType('w'), metavar='FILE', required=True) optional = parser.add_argument_group('Optional arguments') optional.add_argument('--labels', '-l', metavar='sample1 sample2', help='User defined labels instead of default labels from ' 'file names. ' 'Multiple labels have to be separated by spaces, e.g. ' '--labels sample1 sample2 sample3', nargs='+') optional.add_argument('--plotTitle', '-T', help='Title of the plot, to be printed on top of ' 'the generated image. Leave blank for no title.', default='') optional.add_argument('--plotFileFormat', metavar='FILETYPE', help='Image format type. If given, this option ' 'overrides the image format based on the plotFile ' 'ending. The available options are: png, ' 'eps, pdf and svg.', choices=['png', 'pdf', 'svg', 'eps']) optional.add_argument('--outFileNameData', help='File name to save the data ' 'underlying data for the average profile, e.g., ' 'myProfile.tab.', type=argparse.FileType('w')) optional.add_argument('--rowCenter', help='When specified, each row (bin, gene, etc.) ' 'in the matrix is centered at 0 before the PCA is ' 'computed. This is useful only if you have a strong ' 'bin/gene/etc. correlation and the resulting ' 'principal component has samples stacked vertically.', action='store_true') optional.add_argument('--version', action='version', version='%(prog)s {}'.format(__version__)) return parser def main(args=None): args = parse_arguments().parse_args(args) corr = Correlation(args.corData, labels=args.labels,) args.plotFile.close() corr.rowCenter = args.rowCenter corr.plot_pca(args.plotFile.name, plot_title=args.plotTitle, image_format=args.plotFileFormat) if args.outFileNameData is not None: import matplotlib mlab_pca = matplotlib.mlab.PCA(corr.matrix) n = len(corr.labels) of = args.outFileNameData of.write("Component\t{}\tEigenvalue\n".format("\t".join(corr.labels))) for i in range(n): of.write("{}".format(i + 1)) for v in mlab_pca.Wt[i, :]: of.write("\t{}".format(v)) of.write("\t{}\n".format(mlab_pca.s[i])) args.outFileNameData.close() if __name__ == "__main__": main() deepTools-2.5.0/deeptools/plotProfile.py0000640000201600010240000005462713067414642017512 0ustar ryanbioinfo#!/usr/bin/env python # -*- coding: utf-8 -*- import sys import argparse import numpy as np import matplotlib matplotlib.use('Agg') matplotlib.rcParams['pdf.fonttype'] = 42 matplotlib.rcParams['svg.fonttype'] = 'none' import matplotlib.pyplot as plt from matplotlib.font_manager import FontProperties from matplotlib import colors as pltcolors import matplotlib.gridspec as gridspec # own modules from deeptools import parserCommon from deeptools import heatmapper from deeptools.heatmapper_utilities import plot_single, getProfileTicks debug = 0 old_settings = np.seterr(all='ignore') plt.ioff() def parse_arguments(args=None): parser = argparse.ArgumentParser( parents=[parserCommon.heatmapperMatrixArgs(), parserCommon.heatmapperOutputArgs(mode='profile'), parserCommon.heatmapperOptionalArgs(mode='profile')], formatter_class=argparse.ArgumentDefaultsHelpFormatter, description='This tool creates a profile plot for ' 'scores over sets of genomic regions. ' 'Typically, these regions are genes, but ' 'any other regions defined in BED ' ' will work. A matrix generated ' 'by computeMatrix is required.', epilog='An example usage is: plotProfile -m ', add_help=False) return parser def process_args(args=None): args = parse_arguments().parse_args(args) # Ensure that yMin/yMax are there and a list try: assert(args.yMin is not None) except: args.yMin = [None] try: assert(args.yMax is not None) except: args.yMax = [None] # Sometimes Galaxy sends --yMax '' and --yMin '' if args.yMin == ['']: args.yMin = [None] if args.yMax == ['']: args.yMax = [None] # Convert to floats if args.yMin != [None]: foo = [float(x) for x in args.yMin] args.yMin = foo if args.yMax != [None]: foo = [float(x) for x in args.yMax] args.yMax = foo if args.plotHeight < 0.5: args.plotHeight = 0.5 elif args.plotHeight > 100: args.plotHeight = 100 return args class Profile(object): def __init__(self, hm, out_file_name, plot_title='', y_axis_label='', y_min=None, y_max=None, averagetype='median', reference_point_label='TSS', start_label='TSS', end_label="TES", plot_height=7, plot_width=11, per_group=False, plot_type='simple', image_format=None, color_list=None, legend_location='auto', plots_per_row=8, dpi=200): """ Using the hm matrix, makes a line plot either per group or per sample using the specified parameters. Args: hm: heatmapper object out_file_name: string plot_title: string y_axis_label: list y_min: list y_max: list averagetype: mean, sum, median reference_point_label: string start_label: string end_label: string plot_height: in cm plot_width: in cm per_group: bool plot_type: string image_format: string color_list: list legend_location: plots_per_row: int Returns: """ self.hm = hm self.out_file_name = out_file_name self.plot_title = plot_title self.y_axis_label = y_axis_label self.y_min = y_min self.y_max = y_max self.averagetype = averagetype self.reference_point_label = reference_point_label self.start_label = start_label self.end_label = end_label self.plot_height = plot_height self.plot_width = plot_width self.per_group = per_group self.plot_type = plot_type self.image_format = image_format self.color_list = color_list self.legend_location = legend_location self.plots_per_row = plots_per_row self.dpi = dpi # decide how many plots are needed if self.per_group: self.numplots = self.hm.matrix.get_num_groups() self.numlines = self.hm.matrix.get_num_samples() else: self.numplots = self.hm.matrix.get_num_samples() self.numlines = self.hm.matrix.get_num_groups() if self.numplots > self.plots_per_row: rows = np.ceil(self.numplots / float(self.plots_per_row)).astype(int) cols = self.plots_per_row else: rows = 1 cols = self.numplots self.grids = gridspec.GridSpec(rows, cols) plt.rcParams['font.size'] = 10.0 self.font_p = FontProperties() self.font_p.set_size('small') # convert cm values to inches plot_height_inches = rows * self.cm2inch(self.plot_height)[0] self.fig = plt.figure(figsize=self.cm2inch(cols * self.plot_width, rows * self.plot_height)) self.fig.suptitle(self.plot_title, y=(1 - (0.06 / plot_height_inches))) self.xticks, self.xtickslabel = getProfileTicks(self.hm, self.reference_point_label, self.start_label, self.end_label) @staticmethod def cm2inch(*tupl): inch = 2.54 if isinstance(tupl[0], tuple): return tuple(i / inch for i in tupl[0]) else: return tuple(i / inch for i in tupl) def plot_hexbin(self): from matplotlib import cm cmap = cm.coolwarm cmap.set_bad('black') for plot in range(self.numplots): col = plot % self.plots_per_row row = int(plot / float(self.plots_per_row)) localYMin = None localYMax = None # split the ax to make room for the colorbar and for each of the # groups sub_grid = gridspec.GridSpecFromSubplotSpec(self.numlines, 2, subplot_spec=self.grids[row, col], width_ratios=[0.92, 0.08], wspace=0.05, hspace=0.1) ax = self.fig.add_subplot(sub_grid[0, 0]) ax.tick_params( axis='y', which='both', left='off', right='off', labelleft='on') if self.per_group: title = self.hm.matrix.group_labels[plot] else: title = self.hm.matrix.sample_labels[plot] vmin = np.inf vmax = -np.inf for data_idx in range(self.numlines): # get the max and min if self.per_group: _row, _col = plot, data_idx else: _row, _col = data_idx, plot sub_matrix = self.hm.matrix.get_matrix(_row, _col) ma = sub_matrix['matrix'] x_values = np.tile(np.arange(ma.shape[1]), (ma.shape[0], 1)) img = ax.hexbin(x_values.flatten(), ma.flatten(), cmap=cmap, mincnt=1) _vmin, _vmax = img.get_clim() if _vmin < vmin: vmin = _vmin if _vmax > vmax: vmax = _vmax if localYMin is None or self.y_min[col % len(self.y_min)] < localYMin: localYMin = self.y_min[col % len(self.y_min)] if localYMax is None or self.y_max[col % len(self.y_max)] > localYMax: localYMax = self.y_max[col % len(self.y_max)] self.fig.delaxes(ax) # iterate again after having computed the vmin and vmax ax_list = [] for data_idx in range(self.numlines)[::-1]: ax = self.fig.add_subplot(sub_grid[data_idx, 0]) if data_idx == 0: ax.set_title(title) if data_idx != self.numlines - 1: plt.setp(ax.get_xticklabels(), visible=False) if self.per_group: _row, _col = plot, data_idx else: _row, _col = data_idx, plot sub_matrix = self.hm.matrix.get_matrix(_row, _col) if self.per_group: label = sub_matrix['sample'] else: label = sub_matrix['group'] ma = sub_matrix['matrix'] try: # matplotlib 2.0 ax.set_facecolor('black') except: # matplotlib <2.0 ax.set_axis_bgcolor('black') x_values = np.tile(np.arange(ma.shape[1]), (ma.shape[0], 1)) img = ax.hexbin(x_values.flatten(), ma.flatten(), cmap=cmap, mincnt=1, vmin=vmin, vmax=vmax) if plot == 0: ax.axes.set_ylabel(label) ax_list.append(ax) lims = ax.get_ylim() if localYMin is not None: lims = (localYMin, lims[1]) if localYMax is not None: lims = (lims[0], localYMax) if lims[0] >= lims[1]: lims = (lims[0], lims[0] + 1) ax.set_ylim(lims) if np.ceil(max(self.xticks)) != float(ma.shape[1]): tickscale = float(sub_matrix['matrix'].shape[1]) / max(self.xticks) xticks_use = [x * tickscale for x in self.xticks] ax_list[0].axes.set_xticks(xticks_use) else: ax_list[0].axes.set_xticks(self.xticks) ax_list[0].axes.set_xticklabels(self.xtickslabel) # align the first and last label # such that they don't fall off # the heatmap sides ticks = ax_list[-1].xaxis.get_major_ticks() ticks[0].label1.set_horizontalalignment('left') ticks[-1].label1.set_horizontalalignment('right') cax = self.fig.add_subplot(sub_grid[:, 1]) self.fig.colorbar(img, cax=cax) plt.subplots_adjust(wspace=0.05, hspace=0.3) plt.tight_layout() plt.savefig(self.out_file_name, dpi=self.dpi, format=self.image_format) plt.close() def plot_heatmap(self): matrix_flatten = None if self.y_min == [None]: matrix_flatten = self.hm.matrix.flatten() # try to avoid outliers by using np.percentile self.y_min = [np.percentile(matrix_flatten, 1.0)] if np.isnan(self.y_min[0]): self.y_min = [None] if self.y_max == [None]: if matrix_flatten is None: matrix_flatten = self.hm.matrix.flatten() # try to avoid outliers by using np.percentile self.y_max = [np.percentile(matrix_flatten, 98.0)] if np.isnan(self.y_max[0]): self.y_max = [None] ax_list = [] # turn off y ticks for plot in range(self.numplots): labels = [] col = plot % self.plots_per_row row = int(plot / float(self.plots_per_row)) localYMin = None localYMax = None # split the ax to make room for the colorbar sub_grid = gridspec.GridSpecFromSubplotSpec(1, 2, subplot_spec=self.grids[row, col], width_ratios=[0.92, 0.08], wspace=0.05) ax = self.fig.add_subplot(sub_grid[0]) cax = self.fig.add_subplot(sub_grid[1]) ax.tick_params( axis='y', which='both', left='off', right='off', labelleft='on') if self.per_group: title = self.hm.matrix.group_labels[plot] else: title = self.hm.matrix.sample_labels[plot] ax.set_title(title) mat = [] # when drawing a heatmap (in contrast to drawing lines) for data_idx in range(self.numlines): if self.per_group: row, col = plot, data_idx else: row, col = data_idx, plot if localYMin is None or self.y_min[col % len(self.y_min)] < localYMin: localYMin = self.y_min[col % len(self.y_min)] if localYMax is None or self.y_max[col % len(self.y_max)] > localYMax: localYMax = self.y_max[col % len(self.y_max)] sub_matrix = self.hm.matrix.get_matrix(row, col) if self.per_group: label = sub_matrix['sample'] else: label = sub_matrix['group'] labels.append(label) mat.append(np.ma.__getattribute__(self.averagetype)(sub_matrix['matrix'], axis=0)) img = ax.imshow(np.vstack(mat), interpolation='nearest', cmap='RdYlBu_r', aspect='auto', vmin=localYMin, vmax=localYMax) self.fig.colorbar(img, cax=cax) totalWidth = np.vstack(mat).shape[1] if np.ceil(max(self.xticks)) != float(totalWidth): tickscale = float(totalWidth) / max(self.xticks) xticks_use = [x * tickscale for x in self.xticks] ax.axes.set_xticks(xticks_use) else: ax.axes.set_xticks(self.xticks) ax.axes.set_xticklabels(self.xtickslabel) # align the first and last label # such that they don't fall off # the heatmap sides ticks = ax.xaxis.get_major_ticks() ticks[0].label1.set_horizontalalignment('left') ticks[-1].label1.set_horizontalalignment('right') # add labels as y ticks labels ymin, ymax = ax.axes.get_ylim() pos, distance = np.linspace(ymin, ymax, len(labels), retstep=True, endpoint=False) d_half = float(distance) / 2 yticks = [x + d_half for x in pos] # TODO: make rotation a parameter # ax.axes.set_yticklabels(labels[::-1], rotation='vertical') if plot == 0: ax.axes.set_yticks(yticks) ax.axes.set_yticklabels(labels[::-1]) else: ax.axes.set_yticklabels([]) ax_list.append(ax) plt.subplots_adjust(wspace=0.05, hspace=0.3) plt.tight_layout() plt.savefig(self.out_file_name, dpi=self.dpi, format=self.image_format) plt.close() def plot_profile(self): if self.y_min is None: self.y_min = [None] if self.y_max is None: self.y_max = [None] if not self.color_list: cmap_plot = plt.get_cmap('jet') if self.numlines > 1: # kmeans, so we need to color by cluster self.color_list = cmap_plot(np.arange(self.numlines, dtype=float) / float(self.numlines)) else: self.color_list = cmap_plot(np.arange(self.numplots, dtype=float) / float(self.numplots)) if (self.numlines > 1 and len(self.color_list) < self.numlines) or\ (self.numlines == 1 and len(self.color_list) < self.numplots): sys.exit("\nThe given list of colors is too small, " "at least {} colors are needed\n".format(self.numlines)) for color in self.color_list: if not pltcolors.is_color_like(color): sys.exit("\nThe color name {} is not valid. Check " "the name or try with a html hex string " "for example #eeff22".format(color)) first = True ax_list = [] for plot in range(self.numplots): localYMin = None localYMax = None col = plot % self.plots_per_row row = int(plot / float(self.plots_per_row)) if (row == 0 and col == 0) or len(self.y_min) > 1 or len(self.y_max) > 1: ax = self.fig.add_subplot(self.grids[row, col]) else: ax = self.fig.add_subplot(self.grids[row, col], sharey=ax_list[0]) if self.per_group: title = self.hm.matrix.group_labels[plot] if row != 0 and len(self.y_min) == 1 and len(self.y_max) == 1: plt.setp(ax.get_yticklabels(), visible=False) else: title = self.hm.matrix.sample_labels[plot] if col != 0 and len(self.y_min) == 1 and len(self.y_max) == 1: plt.setp(ax.get_yticklabels(), visible=False) ax.set_title(title) for data_idx in range(self.numlines): if self.per_group: _row, _col = plot, data_idx else: _row, _col = data_idx, plot if localYMin is None or self.y_min[_col % len(self.y_min)] < localYMin: localYMin = self.y_min[_col % len(self.y_min)] if localYMax is None or self.y_max[_col % len(self.y_max)] > localYMax: localYMax = self.y_max[_col % len(self.y_max)] sub_matrix = self.hm.matrix.get_matrix(_row, _col) if self.per_group: label = sub_matrix['sample'] else: label = sub_matrix['group'] if self.numlines > 1: coloridx = data_idx else: coloridx = plot plot_single(ax, sub_matrix['matrix'], self.averagetype, self.color_list[coloridx], label, plot_type=self.plot_type) # remove the numbers of the y axis for all plots plt.setp(ax.get_yticklabels(), visible=False) if col == 0 or len(self.y_min) > 1 or len(self.y_max) > 1: # add the y axis label for the first plot # on each row and make the numbers and ticks visible plt.setp(ax.get_yticklabels(), visible=True) ax.axes.set_ylabel(self.y_axis_label) """ # reduce the number of yticks by half num_ticks = len(ax.get_yticks()) yticks = [ax.get_yticks()[i] for i in range(1, num_ticks, 2)] ax.set_yticks(yticks) """ totalWidth = sub_matrix['matrix'].shape[1] if np.ceil(max(self.xticks)) != float(totalWidth): tickscale = float(totalWidth) / max(self.xticks) xticks_use = [x * tickscale for x in self.xticks] ax.axes.set_xticks(xticks_use) else: ax.axes.set_xticks(self.xticks) ax.axes.set_xticklabels(self.xtickslabel) # align the first and last label # such that they don't fall off # the heatmap sides ticks = ax.xaxis.get_major_ticks() ticks[0].label1.set_horizontalalignment('left') ticks[-1].label1.set_horizontalalignment('right') if first and self.plot_type not in ['heatmap', 'overlapped_lines']: ax.legend(loc=self.legend_location.replace('-', ' '), ncol=1, prop=self.font_p, frameon=False, markerscale=0.5) if len(self.y_min) == 1 and len(self.y_max) == 1: first = False """ ax.legend(bbox_to_anchor=(-0.05, -1.13, 1., 1), loc='upper center', ncol=1, mode="expand", prop=font_p, frameon=False, markerscale=0.5) """ lims = ax.get_ylim() if localYMin is not None: lims = (localYMin, lims[1]) if localYMax is not None: lims = (lims[0], localYMax) if lims[0] >= lims[1]: lims = (lims[0], lims[0] + 1) ax.set_ylim(lims) ax_list.append(ax) plt.subplots_adjust(wspace=0.05, hspace=0.3) plt.tight_layout() plt.savefig(self.out_file_name, dpi=self.dpi, format=self.image_format) plt.close() def main(args=None): args = process_args(args) hm = heatmapper.heatmapper() matrix_file = args.matrixFile.name args.matrixFile.close() hm.read_matrix_file(matrix_file) if args.kmeans is not None: hm.matrix.hmcluster(args.kmeans, method='kmeans') else: if args.hclust is not None: print("Performing hierarchical clustering." "Please note that it might be very slow for large datasets.\n") hm.matrix.hmcluster(args.hclust, method='hierarchical') group_len_ratio = np.diff(hm.matrix.group_boundaries) / float(len(hm.matrix.regions)) if np.any(group_len_ratio < 5.0 / 1000): problem = np.flatnonzero(group_len_ratio < 5.0 / 1000) sys.stderr.write("WARNING: Group '{}' is too small for plotting, you might want to remove it. \n".format(hm.matrix.group_labels[problem[0]])) if args.regionsLabel: hm.matrix.set_group_labels(args.regionsLabel) if args.samplesLabel and len(args.samplesLabel): hm.matrix.set_sample_labels(args.samplesLabel) if args.outFileNameData: hm.save_tabulated_values(args.outFileNameData, reference_point_label=args.refPointLabel, start_label=args.startLabel, end_label=args.endLabel, averagetype=args.averageType) if args.outFileSortedRegions: hm.save_BED(args.outFileSortedRegions) prof = Profile(hm, args.outFileName, plot_title=args.plotTitle, y_axis_label=args.yAxisLabel, y_min=args.yMin, y_max=args.yMax, averagetype=args.averageType, reference_point_label=args.refPointLabel, start_label=args.startLabel, end_label=args.endLabel, plot_height=args.plotHeight, plot_width=args.plotWidth, per_group=args.perGroup, plot_type=args.plotType, image_format=args.plotFileFormat, color_list=args.colors, legend_location=args.legendLocation, plots_per_row=args.numPlotsPerRow, dpi=args.dpi) if args.plotType == 'heatmap': prof.plot_heatmap() elif args.plotType == 'overlapped_lines': prof.plot_hexbin() else: prof.plot_profile() deepTools-2.5.0/deeptools/sumCoveragePerBin.py0000640000201600010240000002217513067414642020564 0ustar ryanbioinfoimport numpy as np import multiprocessing import time from deeptools import countReadsPerBin from deeptools.utilities import getTLen from deeptoolsintervals import GTF class SumCoveragePerBin(countReadsPerBin.CountReadsPerBin): r"""This is an extension of CountReadsPerBin for use with plotFingerprint. There, we need to sum the per-base coverage. """ def get_coverage_of_region(self, bamHandle, chrom, regions, fragmentFromRead_func=None): """ Returns a numpy array that corresponds to the number of reads that overlap with each tile. >>> test = Tester() >>> import pysam >>> c = SumCoveragePerBin([], stepSize=1, extendReads=300) For this case the reads are length 36. The number of overlapping read fragments is 4 and 5 for the positions tested. Note that reads are NOT extended, due to there being a 0 length input list of BAM files! >>> c.get_coverage_of_region(pysam.AlignmentFile(test.bamFile_PE), 'chr2', ... [(5000833, 5000834), (5000834, 5000835)]) array([ 4., 5.]) In the following case the reads length is 50. Reads are not extended. >>> c.extendReads=False >>> c.get_coverage_of_region(pysam.AlignmentFile(test.bamFile2), '3R', [(148, 150), (150, 152), (152, 154)]) array([ 2., 4., 4.]) """ if not fragmentFromRead_func: fragmentFromRead_func = self.get_fragment_from_read nbins = len(regions) if len(regions[0]) == 3: nbins = 0 for reg in regions: nbins += (reg[1] - reg[0]) // reg[2] coverages = np.zeros(nbins, dtype='float64') if self.defaultFragmentLength == 'read length': extension = 0 else: extension = self.maxPairedFragmentLength blackList = None if self.blackListFileName is not None: blackList = GTF(self.blackListFileName) vector_start = 0 for idx, reg in enumerate(regions): if len(reg) == 3: tileSize = int(reg[2]) nRegBins = (reg[1] - reg[0]) // tileSize else: nRegBins = 1 tileSize = int(reg[1] - reg[0]) # Blacklisted regions have a coverage of 0 if blackList and blackList.findOverlaps(chrom, reg[0], reg[1]): continue regStart = int(max(0, reg[0] - extension)) regEnd = reg[1] + int(extension) # If alignments are extended and there's a blacklist, ensure that no # reads originating in a blacklist are fetched if blackList and reg[0] > 0 and extension > 0: o = blackList.findOverlaps(chrom, regStart, reg[0]) if o is not None and len(o) > 0: regStart = o[-1][1] o = blackList.findOverlaps(chrom, reg[1], regEnd) if o is not None and len(o) > 0: regEnd = o[0][0] start_time = time.time() # caching seems faster. TODO: profile the function c = 0 try: # BAM input if chrom in bamHandle.references: reads = [r for r in bamHandle.fetch(chrom, regStart, regEnd) if r.flag & 4 == 0] else: raise NameError("chromosome {} not found in bam file".format(chrom)) except: # bigWig input, as used by plotFingerprint if bamHandle.chroms(chrom): _ = np.array(bamHandle.stats(chrom, regStart, regEnd, type="mean", nBins=nRegBins), dtype=np.float) _[np.isnan(_)] = 0.0 _ = _ * tileSize coverages += _ continue else: raise NameError("chromosome {} not found in bigWig file with chroms {}".format(chrom, bamHandle.chroms())) prev_start_pos = None # to store the start positions # of previous processed read pair for read in reads: if self.minMappingQuality and read.mapq < self.minMappingQuality: continue # filter reads based on SAM flag if self.samFlag_include and read.flag & self.samFlag_include != self.samFlag_include: continue if self.samFlag_exclude and read.flag & self.samFlag_exclude != 0: continue # Fragment lengths tLen = getTLen(read) if self.minFragmentLength > 0 and tLen < self.minFragmentLength: continue if self.maxFragmentLength > 0 and tLen > self.maxFragmentLength: continue # get rid of duplicate reads that have same position on each of the # pairs if self.ignoreDuplicates and prev_start_pos \ and prev_start_pos == (read.reference_start, read.pnext, read.is_reverse): continue # since reads can be split (e.g. RNA-seq reads) each part of the # read that maps is called a position block. try: position_blocks = fragmentFromRead_func(read) except TypeError: # the get_fragment_from_read functions returns None in some cases. # Those cases are to be skipped, hence the continue line. continue last_eIdx = None for fragmentStart, fragmentEnd in position_blocks: if fragmentEnd is None or fragmentStart is None: continue fragmentLength = fragmentEnd - fragmentStart if fragmentLength == 0: continue # skip reads that are not in the region being # evaluated. if fragmentEnd <= reg[0] or fragmentStart >= reg[1]: continue if fragmentStart < reg[0]: fragmentStart = reg[0] if fragmentEnd > reg[0] + len(coverages) * tileSize: fragmentEnd = reg[0] + len(coverages) * tileSize sIdx = vector_start + max((fragmentStart - reg[0]) // tileSize, 0) eIdx = vector_start + min(np.ceil(float(fragmentEnd - reg[0]) / tileSize).astype('int'), nRegBins) if eIdx >= len(coverages): eIdx = len(coverages) - 1 if last_eIdx is not None: sIdx = max(last_eIdx, sIdx) if sIdx >= eIdx: continue # First bin if fragmentEnd < reg[0] + (sIdx + 1) * tileSize: _ = fragmentEnd - fragmentStart else: _ = reg[0] + (sIdx + 1) * tileSize - fragmentStart if _ > tileSize: _ = tileSize coverages[sIdx] += _ _ = sIdx + 1 while _ < eIdx: coverages[_] += tileSize _ += 1 while eIdx - sIdx >= nRegBins: eIdx -= 1 if eIdx > sIdx: _ = fragmentEnd - (reg[0] + eIdx * tileSize) if _ > tileSize: _ = tileSize elif _ < 0: _ = 0 coverages[eIdx] += _ last_eIdx = eIdx prev_start_pos = (read.reference_start, read.pnext, read.is_reverse) c += 1 if self.verbose: endTime = time.time() print("%s, processing %s (%.1f per sec) reads @ %s:%s-%s" % ( multiprocessing.current_process().name, c, c / (endTime - start_time), chrom, reg[0], reg[1])) vector_start += nRegBins # change zeros to NAN if self.zerosToNans: coverages[coverages == 0] = np.nan return coverages class Tester(object): def __init__(self): """ The distribution of reads between the two bam files is as follows. They cover 200 bp 0 100 200 |------------------------------------------------------------| A =============== =============== B =============== =============== =============== =============== """ import os self.root = os.path.dirname(os.path.abspath(__file__)) + "/test/test_data/" self.bamFile1 = self.root + "testA.bam" self.bamFile2 = self.root + "testB.bam" self.bamFile_PE = self.root + "test_paired2.bam" self.chrom = '3R' deepTools-2.5.0/deeptools/utilities.py0000640000201600010240000003510513067414642017214 0ustar ryanbioinfoimport sys import os import pysam from deeptoolsintervals import GTF from deeptools.bamHandler import openBam debug = 0 def getTLen(read): """ Get the observed template length of a read. For a paired-end read, this is normally just the TLEN field. For SE reads this is the observed coverage of the genome (excluding splicing). """ if abs(read.template_length) > 0: return abs(read.template_length) tlen = 0 try: # the cigartuples property apparently didn't always exist for op, opLen in read.cigartuples: if op == 0: tlen += opLen elif op == 2: tlen += opLen elif op == 7: tlen += opLen elif op == 8: tlen += opLen except: pass return tlen def getGC_content(tb, chrom, fragStart, fragEnd, fraction=True): bases = tb.bases(chrom, fragStart, fragEnd, fraction=False) if fragEnd > tb.chroms(chrom): fragEnd = tb.chroms(chrom) if sum(bases.values()) < 0.95 * (fragEnd - fragStart): raise Exception("WARNING: too many NNNs present in {}:{}-{}".format(chrom, fragStart, fragEnd)) return None if fraction: return (bases['G'] + bases['C']) / float(fragEnd - fragStart) return bases['G'] + bases['C'] def tbitToBamChrName(tbitNames, bamNames): """ checks if the chromosome names from the two-bit and bam file coincide. In case they do not coincide, a fix is tried. If successful, then a mapping table is returned. tbitNames and bamNames should be lists """ chrNameBitToBam = dict((x, x) for x in tbitNames) if set(bamNames) != set(tbitNames): sys.stderr.write("Bam and 2bit do not have matching " "chromosome names:\n2bit:{}\n\nbam:{}" "\n\n".format(tbitNames, bamNames)) if len(set(bamNames).intersection(set(tbitNames))) > 0: sys.stderr.write("Using the following common chromosomes between " "bam chromosome names and 2bit chromosome " "names:\n") for item in set(bamNames).intersection(set(tbitNames)): sys.stderr.write(item + "\n") chrNameBitToBam = dict([(x, x) for x in set(bamNames).intersection(set(tbitNames))]) elif set(["chr" + x if x != 'dmel_mitochondrion_genome' else 'chrM' for x in bamNames]) == set(tbitNames): sys.stderr.write("Adding 'chr' seems to solve the problem. " "Continuing ...") chrNameBitToBam = dict([("chr" + x if x != 'dmel_mitochondrion_genome' else 'chrM', x) for x in bamNames]) elif set([x for x in tbitNames if x.count('random') == 0 and x.count('chrM') == 0]) == set(bamNames): if debug: print("Removing random and mitochondrial chromosomes" "fixes the problem") chrNameBitToBam = dict([(x, x) for x in tbitNames if x.count('random') == 0 and x.count('chrM') == 0]) elif len(set(["chr" + x for x in bamNames if x != 'dmel_mitochondrion_genome']).intersection(set(tbitNames))) > 0: bamNames2 = ["chr" + x for x in bamNames if x != 'dmel_mitochondrion_genome'] sys.stderr.write("Adding 'chr' seems to solve the problem for the following " "chromosomes...") for item in set(bamNames2).intersection(set(tbitNames)): sys.stderr.write(item + "\n") chrNameBitToBam = {"chrM": "MT"} for i in range(len(bamNames)): if bamNames2[i] in tbitNames: chrNameBitToBam.update({bamNames2[i]: bamNames[i]}) elif len(set([x[3:] for x in bamNames if x.startswith("chr")]).intersection(set(tbitNames))) > 0: bamNames = [x for x in bamNames] bamNames2 = [x[3:] for x in bamNames if x.startswith("chr")] if debug: sys.stderr.write("Removing 'chr' seems to solve the problem for the following " "chromosomes...") for item in set(bamNames).intersection(set(tbitNames)): sys.stderr.write(item + "\n") chrNameBitToBam = {"MT": "chrM"} for i in range(len(bamNames)): if bamNames2[i] in tbitNames: chrNameBitToBam.update({bamNames2[i]: bamNames[i]}) else: if debug: print("Index and reference do not have matching ") "chromosome names" exit(0) return chrNameBitToBam def getCommonChrNames(bamFileHandlers, verbose=True): r""" Compares the names and lengths of a list of bam file handlers. The input is list of pysam file handlers. The function returns a duple containing the common chromosome names and the common chromome lengths. Hopefully, only _random and chrM are not common. """ def get_chrom_and_size(bam_handler): """ Reads the chromosome/scaffold name and the length from the bam file and returns a list of (chromname, size) tuples :param bam_handler: :return: list of (chrom, size) tuples """ try: # BAM file return [(bam_handler.references[i], bam_handler.lengths[i]) for i in range(0, len(bam_handler.references))] except: return [(k, v) for k, v in bam_handler.chroms().items()] def print_chr_names_and_size(chr_set): sys.stderr.write("chromosome\tlength\n") for name, size in chr_set: sys.stderr.write("{0:>15}\t{1:>10}\n".format(name, size)) common_chr = set(get_chrom_and_size(bamFileHandlers[0])) non_common_chr = set() for j in range(1, len(bamFileHandlers)): _names_and_size = set(get_chrom_and_size(bamFileHandlers[j])) if len(common_chr & _names_and_size) == 0: # try to add remove 'chr' from the chromosome name _corr_names_size = set() for chrom_name, size in _names_and_size: if chrom_name.startswith('chr'): _corr_names_size.add((chrom_name[3:], size)) else: _corr_names_size.add(('chr' + chrom_name, size)) if len(common_chr & _corr_names_size) == 0: message = "No common chromosomes found. Are the bam files files " \ "from the same species and same assemblies?\n" sys.stderr.write(message) print_chr_names_and_size(common_chr) sys.stderr.write("\nand the following is the list of the unmatched chromosome and chromosome\n" "lengths from file\n{}\n".format(bamFileHandlers.name)) print_chr_names_and_size(_names_and_size) exit(1) else: _names_and_size = _corr_names_size non_common_chr |= common_chr ^ _names_and_size common_chr = common_chr & _names_and_size if len(non_common_chr) > 0: sys.stderr.write("\nThe following chromosome names did not match between the the bam files\n") print_chr_names_and_size(non_common_chr) # the common chromosomes has to be sorted as in the original # bam files chr_sizes = [] for tuple in get_chrom_and_size(bamFileHandlers[0]): if tuple in common_chr: chr_sizes.append(tuple) return chr_sizes, non_common_chr def copyFileInMemory(filePath, suffix=''): """ copies a file into the special /dev/shm device which moves the file into memory. This process speeds ups the multiprocessor access to such files """ # fallback for windows users if os.name == 'nt': return filePath memFileName = getTempFileName(suffix=suffix) import shutil shutil.copyfile(filePath, memFileName) return memFileName def getTempFileName(suffix=''): """ returns a temporary file name. If the special /dev/shm device is available, the temporary file would be located in that folder. /dv/shm is a folder that resides in memory and which has much faster accession. """ import tempfile from deeptools import config as cfg # get temp dir from configuration file tmp_dir = cfg.config.get('general', 'tmp_dir') if tmp_dir == 'default': _tempFile = tempfile.NamedTemporaryFile(prefix="_deeptools_", suffix=suffix, delete=False) else: try: _tempFile = tempfile.NamedTemporaryFile(prefix="_deeptools_", suffix=suffix, dir=tmp_dir, delete=False) # fall back to system tmp file except OSError: _tempFile = tempfile.NamedTemporaryFile(prefix="_deeptools_", suffix=suffix, delete=False) memFileName = _tempFile.name _tempFile.close() return memFileName def which(program): """ method to identify if a program is on the user PATH variable. From: http://stackoverflow.com/questions/377017/test-if-executable-exists-in-python """ import os def is_exe(fpath): return os.path.isfile(fpath) and os.access(fpath, os.X_OK) fpath, fname = os.path.split(program) if fpath: if is_exe(program): return program else: for path in os.environ["PATH"].split(os.pathsep): path = path.strip('"') exe_file = os.path.join(path, program) if is_exe(exe_file): return exe_file return None def gtfOptions(allArgs=None): """ This is used a couple places to setup arguments to mapReduce """ transcriptID = "transcript" exonID = "exon" transcript_id_designator = "transcript_id" keepExons = False if allArgs is not None: allArgs = vars(allArgs) transcriptID = allArgs.get("transcriptID", transcriptID) exonID = allArgs.get("exonID", exonID) transcript_id_designator = allArgs.get("transcript_id_designator", transcript_id_designator) keepExons = allArgs.get("keepExons", keepExons) return transcriptID, exonID, transcript_id_designator, keepExons def toString(s): """ This takes care of python2/3 differences """ if isinstance(s, str): return s if isinstance(s, bytes): if sys.version_info[0] == 2: return str(s) return s.decode('ascii') if isinstance(s, list): return [toString(x) for x in s] return s def toBytes(s): """ Like toString, but for functions requiring bytes in python3 """ if sys.version_info[0] == 2: return s if isinstance(s, bytes): return s if isinstance(s, str): return bytes(s, 'ascii') if isinstance(s, list): return [toBytes(x) for x in s] return s def mungeChromosome(chrom, chromList): """ A generic chromosome munging function. "chrom" is munged by adding/removing "chr" such that it appears in chromList On error, None is returned, but a common chromosome list should be used beforehand to avoid this possibility """ if chrom in chromList: return chrom if chrom == "MT" and "chrM" in chromList: return "chrM" if chrom == "chrM" and "MT" in chromList: return "MT" if chrom.startswith("chr") and chrom[3:] in chromList: return chrom[3:] if "chr" + chrom in chromList: return "chr" + chrom # This shouldn't actually happen return None def bam_total_reads(bam_handle, chroms_to_ignore): """Count the total number of mapped reads in a BAM file, filtering the chromosome given in chroms_to_ignore list """ if chroms_to_ignore: import pysam lines = pysam.idxstats(bam_handle.filename) lines = toString(lines) if type(lines) is str: lines = lines.strip().split('\n') if len(lines) == 0: # check if this is a test running under nose # in which case it will fail. if len([val for val in sys.modules.keys() if val.find("nose") >= 0]): sys.stderr.write("To run this code inside a test use disable " "output buffering `nosetest -s`\n".format(bam_handle.filename)) else: sys.stderr.write("Error running idxstats on {}\n".format(bam_handle.filename)) tot_mapped_reads = 0 for line in lines: chrom, _len, nmapped, _nunmapped = line.split('\t') if chrom not in chroms_to_ignore: tot_mapped_reads += int(nmapped) else: tot_mapped_reads = bam_handle.mapped return tot_mapped_reads def bam_blacklisted_worker(args): bam, chrom, start, end = args fh = openBam(bam) blacklisted = 0 for r in fh.fetch(reference=chrom, start=start, end=end): if r.reference_start >= start and r.reference_start + r.infer_query_length(always=False) - 1 <= end: blacklisted += 1 fh.close() return blacklisted def bam_blacklisted_reads(bam_handle, chroms_to_ignore, blackListFileName=None, numberOfProcessors=1): blacklisted = 0 if blackListFileName is None: return blacklisted # Get the chromosome lengths chromLens = {} lines = pysam.idxstats(bam_handle.filename) lines = toString(lines) if type(lines) is str: lines = lines.strip().split('\n') for line in lines: chrom, _len, nmapped, _nunmapped = line.split('\t') chromLens[chrom] = int(_len) bl = GTF(blackListFileName) regions = [] for chrom in bl.chroms: if (not chroms_to_ignore or chrom not in chroms_to_ignore) and chrom in chromLens: for reg in bl.findOverlaps(chrom, 0, chromLens[chrom]): regions.append([bam_handle.filename, chrom, reg[0], reg[1]]) if len(regions) > 0: import multiprocessing if len(regions) > 1 and numberOfProcessors > 1: pool = multiprocessing.Pool(numberOfProcessors) res = pool.map_async(bam_blacklisted_worker, regions).get(9999999) else: res = [bam_blacklisted_worker(x) for x in regions] for val in res: blacklisted += val return blacklisted deepTools-2.5.0/deeptools/writeBedGraph.py0000640000201600010240000003237313006372704017727 0ustar ryanbioinfoimport os import sys import shutil import numpy as np import pyBigWig # own modules from deeptools import mapReduce from deeptools.utilities import getCommonChrNames, toBytes import deeptools.countReadsPerBin as cr from deeptools import bamHandler from deeptools import utilities from deeptools import config as cfg debug = 0 old_settings = np.seterr(all='ignore') def writeBedGraph_wrapper(args): """ Passes the arguments to writeBedGraph_worker. This is a step required given the constrains from the multiprocessing module. The args var, contains as first element the 'self' value from the WriteBedGraph object """ return WriteBedGraph.writeBedGraph_worker(*args) class WriteBedGraph(cr.CountReadsPerBin): r"""Reads bam files coverages and writes a bedgraph or bigwig file Extends the CountReadsPerBin object such that the coverage of bam files is writen to multiple bedgraph files at once. The bedgraph files are later merge into one and converted into a bigwig file if necessary. The constructor arguments are the same as for CountReadsPerBin. However, when calling the `run` method, the following parameters have to be passed Examples -------- Given the following distribution of reads that cover 200 on a chromosome named '3R':: 0 100 200 |------------------------------------------------------------| A =============== =============== B =============== =============== =============== =============== >>> import tempfile >>> test_path = os.path.dirname(os.path.abspath(__file__)) + "/test/test_data/" >>> outFile = tempfile.NamedTemporaryFile() >>> bam_file = test_path + "testA.bam" For the example a simple scaling function is going to be used. This function takes the coverage found at each region and multiplies it to the scaling factor. In this case the scaling factor is 1.5 >>> function_to_call = scaleCoverage >>> funcArgs = {'scaleFactor': 1.5} Restrict process to a region between positions 0 and 200 of chromosome 3R >>> region = '3R:0:200' Set up such that coverage is computed for consecutive bins of length 25 bp >>> bin_length = 25 >>> step_size = 25 >>> num_sample_sites = 0 #overruled by step_size >>> c = WriteBedGraph([bam_file], binLength=bin_length, region=region, stepSize=step_size) >>> c.run(function_to_call, funcArgs, outFile.name) >>> f = open(outFile.name, 'r') >>> f.readlines() ['3R\t0\t100\t0\n', '3R\t100\t200\t1.5\n'] >>> f.close() >>> outFile.close() """ def run(self, func_to_call, func_args, out_file_name, blackListFileName=None, format="bedgraph", smoothLength=0): r""" Given a list of bamfiles, a function and a function arguments, this method writes a bedgraph file (or bigwig) file for a partition of the genome into tiles of given size and a value for each tile that corresponds to the given function and that is related to the coverage underlying the tile. Parameters ---------- func_to_call : str function name to be called to convert the list of coverages computed for each bam file at each position into a single value. An example is a function that takes the ratio between the coverage of two bam files. func_args : dict dict of arguments to pass to `func`. E.g. {'scaleFactor':1.0} out_file_name : str name of the file to save the resulting data. smoothLength : int Distance in bp for smoothing the coverage per tile. """ self.__dict__["smoothLength"] = smoothLength bam_handlers = [bamHandler.openBam(x) for x in self.bamFilesList] genome_chunk_length = getGenomeChunkLength(bam_handlers, self.binLength) # check if both bam files correspond to the same species # by comparing the chromosome names: chrom_names_and_size, non_common = getCommonChrNames(bam_handlers, verbose=False) if self.region: # in case a region is used, append the tilesize self.region += ":{}".format(self.binLength) for x in list(self.__dict__.keys()): sys.stderr.write("{}: {}\n".format(x, self.__getattribute__(x))) res = mapReduce.mapReduce([func_to_call, func_args], writeBedGraph_wrapper, chrom_names_and_size, self_=self, genomeChunkLength=genome_chunk_length, region=self.region, blackListFileName=blackListFileName, numberOfProcessors=self.numberOfProcessors) # concatenate intermediary bedgraph files out_file = open(out_file_name + ".bg", 'wb') for tempfilename in res: if tempfilename: # concatenate all intermediate tempfiles into one # bedgraph file _foo = open(tempfilename, 'rb') shutil.copyfileobj(_foo, out_file) _foo.close() os.remove(tempfilename) bedgraph_file = out_file.name out_file.close() if format == 'bedgraph': sort_cmd = cfg.config.get('external_tools', 'sort') os.system("LC_ALL=C {} -k1,1 -k2,2n {} > {}".format(sort_cmd, bedgraph_file, out_file_name)) os.remove(bedgraph_file) if self.verbose: print("output file: {}".format(out_file_name)) else: bedGraphToBigWig( chrom_names_and_size, bedgraph_file, out_file_name, True) if self.verbose: print("output file: {}".format(out_file_name)) os.remove(bedgraph_file) def writeBedGraph_worker(self, chrom, start, end, func_to_call, func_args, bed_regions_list=None): r"""Writes a bedgraph based on the read coverage found on bamFiles The given func is called to compute the desired bedgraph value using the funcArgs Parameters ---------- chrom : str Chrom name start : int start coordinate end : int end coordinate func_to_call : str function name to be called to convert the list of coverages computed for each bam file at each position into a single value. An example is a function that takes the ratio between the coverage of two bam files. func_args : dict dict of arguments to pass to `func`. smoothLength : int Distance in bp for smoothing the coverage per tile. bed_regions_list: list List of tuples of the form (chrom, start, end) corresponding to bed regions to be processed. If not bed file was passed to the object constructor then this list is empty. Returns ------- temporary file with the bedgraph results for the region queried. Examples -------- >>> test_path = os.path.dirname(os.path.abspath(__file__)) + "/test/test_data/" >>> bamFile1 = test_path + "testA.bam" >>> bin_length = 50 >>> number_of_samples = 0 # overruled by step_size >>> func_to_call = scaleCoverage >>> funcArgs = {'scaleFactor': 1.0} >>> c = WriteBedGraph([bamFile1], bin_length, number_of_samples, stepSize=50) >>> tempFile = c.writeBedGraph_worker( '3R', 0, 200, func_to_call, funcArgs) >>> f = open(tempFile, 'r') >>> f.readlines() ['3R\t0\t100\t0\n', '3R\t100\t200\t1\n'] >>> f.close() >>> os.remove(tempFile) """ if start > end: raise NameError("start position ({0}) bigger " "than end position ({1})".format(start, end)) coverage, _ = self.count_reads_in_region(chrom, start, end) _file = open(utilities.getTempFileName(suffix='.bg'), 'w') previous_value = None line_string = "{}\t{}\t{}\t{:g}\n" for tileIndex in range(coverage.shape[0]): if self.smoothLength is not None and self.smoothLength > 0: vector_start, vector_end = self.getSmoothRange(tileIndex, self.binLength, self.smoothLength, coverage.shape[0]) tileCoverage = np.mean(coverage[vector_start:vector_end, :], axis=0) else: tileCoverage = coverage[tileIndex, :] value = func_to_call(tileCoverage, func_args) """ # uncomment these lines if fixed step bedgraph is required if not np.isnan(value): writeStart = start + tileIndex*self.binLength writeEnd = min(writeStart+self.binLength, end) _file.write(line_string.format(chrom, writeStart, end, previous_value)) """ if previous_value is None: writeStart = start + tileIndex * self.binLength writeEnd = min(writeStart + self.binLength, end) previous_value = value elif previous_value == value: writeEnd = min(writeEnd + self.binLength, end) elif previous_value != value: if not np.isnan(previous_value): _file.write( line_string.format(chrom, writeStart, writeEnd, previous_value)) previous_value = value writeStart = writeEnd writeEnd = min(writeStart + self.binLength, end) # write remaining value if not a nan if previous_value is not None and writeStart != end and not np.isnan(previous_value): _file.write(line_string.format(chrom, writeStart, end, previous_value)) tempfilename = _file.name _file.close() return tempfilename def bedGraphToBigWig(chromSizes, bedGraphPath, bigWigPath, sort=True): """ takes a bedgraph file, orders it and converts it to a bigwig file using pyBigWig. """ from tempfile import NamedTemporaryFile from os import remove, system # Make a list of tuples for the bigWig header, this MUST be sorted identically to the bedGraph file sort_cmd = cfg.config.get('external_tools', 'sort') _file = NamedTemporaryFile(delete=False) for chrom, size in chromSizes: _file.write(toBytes("{}\t{}\n".format(chrom, size))) _file.close() system("LC_ALL=C {} -k1,1 -k2,2n {} > {}.sorted".format(sort_cmd, _file.name, _file.name)) cl = [] f = open("{}.sorted".format(_file.name)) for line in f: chrom, chromLen = line.split() cl.append((chrom, int(chromLen))) f.close() remove(_file.name) remove("{}.sorted".format(_file.name)) # check if the file is empty if os.stat(bedGraphPath).st_size < 10: import sys sys.stderr.write( "Error: The generated bedGraphFile was empty. Please adjust\n" "your deepTools settings and check your input files.\n") exit(1) if sort: # temporary file to store sorted bedgraph file _file = NamedTemporaryFile(delete=False) tempfilename1 = _file.name system("LC_ALL=C {} -k1,1 -k2,2n {} > {}".format(sort_cmd, bedGraphPath, tempfilename1)) bedGraphPath = tempfilename1 bw = pyBigWig.open(bigWigPath, "w") assert(bw is not None) # The lack of maxZooms will change the results a bit, perhaps the defaults are better bw.addHeader(cl, maxZooms=10) f = open(bedGraphPath) for line in f: interval = line.split() bw.addEntries([interval[0]], [int(interval[1])], ends=[int(interval[2])], values=[float(interval[3])]) f.close() bw.close() if sort: remove(tempfilename1) def getGenomeChunkLength(bamHandlers, tile_size): """ Tries to estimate the length of the genome sent to the workers based on the density of reads per bam file and the number of bam files. The chunk length should be a multiple of the tileSize """ genomeLength = sum(bamHandlers[0].lengths) max_reads_per_bp = max( [float(x.mapped) / genomeLength for x in bamHandlers]) # 2e6 is an empirical estimate genomeChunkLength = int( min(5e6, int(2e6 / (max_reads_per_bp * len(bamHandlers))))) genomeChunkLength -= genomeChunkLength % tile_size return genomeChunkLength def scaleCoverage(tile_coverage, args): """ tileCoverage should be an list with only one element """ return args['scaleFactor'] * tile_coverage[0] def ratio(tile_coverage, args): """ tileCoverage should be an list of two elements """ return float(tile_coverage[0]) / tile_coverage[1] deepTools-2.5.0/deeptools/writeBedGraph_bam_and_bw.py0000640000201600010240000002155413006372704022057 0ustar ryanbioinfo#!/usr/bin/env python # -*- coding: utf-8 -*- import os import shutil import tempfile import numpy as np import sys # NGS packages import pyBigWig # own module from deeptools import mapReduce from deeptools.utilities import getCommonChrNames, toBytes from deeptools.writeBedGraph import * from deeptools import bamHandler old_settings = np.seterr(all='ignore') def getCoverageFromBigwig(bigwigHandle, chrom, start, end, tileSize, missingDataAsZero=False): try: coverage = np.asarray(bigwigHandle.values(chrom, start, end)) except TypeError: # this error happens when chromosome # is not into the bigwig file return [] if coverage is None: return [] if missingDataAsZero is True: coverage[np.isnan(coverage)] = 0 # average the values per bin cov = np.array( [np.mean(coverage[x:x + tileSize]) for x in range(0, len(coverage), tileSize)]) return cov def writeBedGraph_wrapper(args): return writeBedGraph_worker(*args) def writeBedGraph_worker( chrom, start, end, tileSize, defaultFragmentLength, bamOrBwFileList, func, funcArgs, extendPairedEnds=True, smoothLength=0, missingDataAsZero=False, fixed_step=False): r""" Writes a bedgraph having as base a number of bam files. The given func is called to compute the desired bedgraph value using the funcArgs tileSize """ if start > end: raise NameError("start position ({0}) bigger than " "end position ({1})".format(start, end)) coverage = [] for indexFile, fileFormat in bamOrBwFileList: if fileFormat == 'bam': bamHandle = bamHandler.openBam(indexFile) coverage.append(getCoverageFromBam( bamHandle, chrom, start, end, tileSize, defaultFragmentLength, extendPairedEnds, True)) bamHandle.close() elif fileFormat == 'bigwig': bigwigHandle = pyBigWig.open(indexFile) coverage.append( getCoverageFromBigwig( bigwigHandle, chrom, start, end, tileSize, missingDataAsZero)) bigwigHandle.close() # is /dev/shm available? # working in this directory speeds the process try: _file = tempfile.NamedTemporaryFile(dir="/dev/shm", delete=False) except OSError: _file = tempfile.NamedTemporaryFile(delete=False) previousValue = None lengthCoverage = len(coverage[0]) for tileIndex in range(lengthCoverage): tileCoverage = [] for index in range(len(bamOrBwFileList)): if smoothLength > 0: vectorStart, vectorEnd = getSmoothRange( tileIndex, tileSize, smoothLength, lengthCoverage) tileCoverage.append( np.mean(coverage[index][vectorStart:vectorEnd])) else: try: tileCoverage.append(coverage[index][tileIndex]) except IndexError: sys.exit("Chromosome {} probably not in one of the bigwig " "files. Remove this chromosome from the bigwig file " "to continue".format(chrom)) # if zerosToNans == True and sum(tileCoverage) == 0.0: # continue value = func(tileCoverage, funcArgs) if fixed_step: writeStart = start + tileIndex * tileSize writeEnd = min(writeStart + tileSize, end) try: _file.write(toBytes("%s\t%d\t%d\t%.2f\n" % (chrom, writeStart, writeEnd, value))) except TypeError: _file.write(toBytes("{}\t{}\t{}\t{}\n".format(chrom, writeStart, writeEnd, value))) else: if previousValue is None: writeStart = start + tileIndex * tileSize writeEnd = min(writeStart + tileSize, end) previousValue = value elif previousValue == value: writeEnd = min(writeEnd + tileSize, end) elif previousValue != value: if not np.isnan(previousValue): _file.write( toBytes("{0}\t{1}\t{2}\t{3:g}\n".format(chrom, writeStart, writeEnd, previousValue))) previousValue = value writeStart = writeEnd writeEnd = min(writeStart + tileSize, end) if not fixed_step: # write remaining value if not a nan if previousValue and writeStart != end and \ not np.isnan(previousValue): _file.write(toBytes("{0}\t{1}\t{2}\t{3:g}\n".format(chrom, writeStart, end, previousValue))) tempFileName = _file.name _file.close() return(tempFileName) def writeBedGraph( bamOrBwFileList, outputFileName, fragmentLength, func, funcArgs, tileSize=25, region=None, blackListFileName=None, numberOfProcessors=None, format="bedgraph", extendPairedEnds=True, missingDataAsZero=False, smoothLength=0, fixed_step=False, verbose=False): r""" Given a list of bamfiles, a function and a function arguments, this method writes a bedgraph file (or bigwig) file for a partition of the genome into tiles of given size and a value for each tile that corresponds to the given function and that is related to the coverage underlying the tile. """ bamHandlers = [bamHandler.openBam(indexedFile) for indexedFile, fileFormat in bamOrBwFileList if fileFormat == 'bam'] if len(bamHandlers): genomeChunkLength = getGenomeChunkLength(bamHandlers, tileSize) # check if both bam files correspond to the same species # by comparing the chromosome names: chromNamesAndSize, __ = getCommonChrNames(bamHandlers, verbose=verbose) else: genomeChunkLength = int(10e6) cCommon = [] chromNamesAndSize = {} for fileName, fileFormat in bamOrBwFileList: if fileFormat == 'bigwig': fh = pyBigWig.open(fileName) else: continue for chromName, size in list(fh.chroms().items()): if chromName in chromNamesAndSize: cCommon.append(chromName) if chromNamesAndSize[chromName] != size: print("\nWARNING\n" "Chromosome {} length reported in the " "input files differ.\n{} for {}\n" "{} for {}.\n\nThe smallest " "length will be used".format( chromName, chromNamesAndSize[chromName], bamOrBwFileList[0][0], size, fileName)) chromNamesAndSize[chromName] = min( chromNamesAndSize[chromName], size) else: chromNamesAndSize[chromName] = size fh.close() # get the list of common chromosome names and sizes chromNamesAndSize = [(k, v) for k, v in chromNamesAndSize.items() if k in cCommon] if region: # in case a region is used, append the tilesize region += ":{}".format(tileSize) res = mapReduce.mapReduce((tileSize, fragmentLength, bamOrBwFileList, func, funcArgs, extendPairedEnds, smoothLength, missingDataAsZero, fixed_step), writeBedGraph_wrapper, chromNamesAndSize, genomeChunkLength=genomeChunkLength, region=region, blackListFileName=blackListFileName, numberOfProcessors=numberOfProcessors, verbose=verbose) # concatenate intermediary bedgraph files outFile = open(outputFileName + ".bg", 'wb') for tempFileName in res: if tempFileName: # concatenate all intermediate tempfiles into one # bedgraph file _foo = open(tempFileName, 'rb') shutil.copyfileobj(_foo, outFile) _foo.close() os.remove(tempFileName) bedGraphFile = outFile.name outFile.close() if format == 'bedgraph': os.rename(bedGraphFile, outputFileName) if debug: print("output file: %s" % (outputFileName)) else: bedGraphToBigWig( chromNamesAndSize, bedGraphFile, outputFileName, True) if debug: print("output file: %s" % (outputFileName)) os.remove(bedGraphFile) deepTools-2.5.0/deeptoolsintervals/0000750000201600010240000000000013067415120016542 5ustar ryanbioinfodeepTools-2.5.0/deeptoolsintervals/test/0000750000201600010240000000000013067415120017521 5ustar ryanbioinfodeepTools-2.5.0/deeptoolsintervals/test/GRCh38.84.2.gtf.gz0000640000201600010240000000373112757050137022207 0ustar ryanbioinfoVGRCh38.84.2.gtfߏ7ǟ_cO)C[UCN[]\.Yְ9C&,gƞOwߊiO`zox:~.:hZ<};ŨR:L(I::OoInu{1{|Ȩo^?u20oxŜ~gpt?? GۜM`2|n?fWZ>z R)YwJ[}oi+lΞ?v{77ܚꍗgTCQ܍OۛDxa1@G_IyRP)<6̅j*J|Ƃ B 8t֟,-˨WBjit>fM8JӨӧP^U:S6~Y4DU‘t.-oh$G˚s}A€R3͢613a2ip>{hʠ`΅Z$] )n-烺ِN;({͹[2nPq.n|w e^|zi}G{8mkߕÇ}tFI=žJ傖\5HAJ"w"͆å|sΡ6U3vʻ뿾{.wXUfZkQisbb6RREE/ bdsZo5Dbkhat%A !J5?n9Qx0eaIH'8qSHN "J\e:I&{G1*ER届Y­m)Y @ܐZy`Hq}3z`A&B2̍iPc sVnTq!QdJcTYԢQI<r bTBhըveJcTYԞQa˪?\] ~w`峕,寽GN=^gl=5J ~dLX" 5@oE2*vz'MN.h8phnt^߬'9=^#kG;EN:#/P҅{?rpXs^#;Gw-"[y?Yq1<rmY!٣ADx˿/bgideepTools-2.5.0/deeptoolsintervals/test/GRCh38.84.bed0000640000201600010240000000051712757050137021401 0ustar ryanbioinfo1 11868 14409 1 12009 13670 1 14403 29570 1 17368 17436 #group 1 1 29553 31097 1 30266 31109 1 30365 30503 1 34553 36081 1 35244 36073 1 52472 53312 1 62947 63887 1 69090 70008 1 89294 120932 #group2 1 92229 129217 1 110952 129173 1 120724 133723 1 129080 133566 1 89550 91105 1 131024 134836 1 135140 135895 # group 3 1 137681 137965 deepTools-2.5.0/deeptoolsintervals/test/GRCh38.84.bed12.bz20000640000201600010240000000120512757050137022233 0ustar ryanbioinfoBZh91AY&SYL&U 0 P>[:.T 2#0S4)M2&TP4Ɉ$"DѦ#:uWc?9z4)v-=/]Js2Xk8~b¬cV* D_ P||󝓦,ψGqe2w"!WpyzȬJXq2`tu:;9IB cU@5E2HKweFDv̢MQf(XödRBDmmvt{䯬 Mj(l߼V-o6&G*OnϜ|+2&Ld62jS&dbZ0>H0(P1c,7GXblR;)%{h\$(D:$O_ V V+lۚhN0i.i<*QMn+STBëʬw5 1̷(G!G]BBW 0deepTools-2.5.0/deeptoolsintervals/test/GRCh38.84.bed20000640000201600010240000000057112757050137021463 0ustar ryanbioinfo1 211868 214409 1 212009 213670 1 214403 229570 1 217368 217436 #group 1 1 229553 231097 1 230266 231109 1 230365 230503 1 234553 236081 1 235244 236073 1 252472 253312 1 262947 263887 1 269090 270008 1 289294 2120932 #group2 1 292229 2129217 1 2110952 2129173 1 2120724 2133723 1 2129080 2133566 1 289550 291105 1 2131024 2134836 1 2135140 2135895 # group 3 1 2137681 2137965 deepTools-2.5.0/deeptoolsintervals/test/GRCh38.84.bed60000640000201600010240000000141312757050137021463 0ustar ryanbioinfo1 11868 14409 ENST00000456328.2 0 + 1 12009 13670 ENST00000450305.2 0 + 1 14403 29570 ENST00000488147.1 0 - 1 17368 17436 ENST00000619216.1 0 - 1 29553 31097 ENST00000473358.1 0 + 1 30266 31109 ENST00000469289.1 0 + #group 1 1 30365 30503 ENST00000607096.1 0 + 1 34553 36081 ENST00000417324.1 0 - 1 35244 36073 ENST00000461467.1 0 - 1 52472 53312 ENST00000606857.1 0 + 1 62947 63887 ENST00000492842.1 0 + 1 69090 70008 ENST00000335137.3 0 + 1 89294 120932 ENST00000466430.5 0 - 1 92229 129217 ENST00000477740.5 0 - 1 110952 129173 ENST00000471248.1 0 - 1 120724 133723 ENST00000610542.1 0 - 1 129080 133566 ENST00000453576.2 0 - 1 89550 91105 ENST00000495576.1 0 - 1 131024 134836 ENST00000442987.3 0 + 1 135140 135895 ENST00000494149.2 0 - 1 137681 137965 ENST00000595919.1 0 - deepTools-2.5.0/deeptoolsintervals/test/GRCh38.84.gtf.gz0000640000201600010240000000546612757050137022056 0ustar ryanbioinfoVGRCh38.84.gtf[oǟu>X(pxm\$'@c8)7C$Xv~rw%‹vklȉV^83^׿|?ۗחzs|V6Ogn-o3Mo}ǧ}!`d<~Y/@~џdT|ncDލjo<ܟ֔guo./Ow>̟0o??Mf˻l4/jeXN_gͯT{So~DMLQ7\9;[+ jel#mxxcn]{-߼.f|(ܦnh/qsX}~:]|7ߟ/ls1|&R*OJD7ӧ"))uo+fl}%OPh^%| vh WTjL R}48@s4K, Ovb"7bE tH Iq}Tg(|hTPG1yQL׉, h8{5Bm,MȣDMΩ*& 8cHq&2%74Cl`T i19CX Q| u9;bHaеÐ:CJo[aռdhaHR<8˫·+޼D\]D)`E[bwD-@ 7D~90e.qᰇPaE ̫Ґ:DRvE_ e^Q|@JRRԤH ܐBDFRIDWh>R:&P4ce#E $S(g45)BqHy>R@JZR8*mύŒ"4Rd$E $%EP2(&N|联PA:T')3)@T޴q@29*e'0digib%t}\M[6 7+{tmd=,WgzDMq1,@ST&NcmsOmwӡ;-iФN %es6BLqK$;oF}|U [Z}xZrA>I"rߖDsDn \%Ar׌p! pm-lx J7 B$2j B,aA) 8]Xh)2\Eq".=1b|pMwfSd3lKa;C1FҮ8S>]Bq~T9)$R0As!n ;龔rRILZUștœ~)WH`sCe9{3 aT m)ㅳ Lܯ-?߫#쏻 J*{p_=8o=|GW1ӿb#Bp{ko(.7sP>)N=]lxI@ \ 2sirewM4zjF ͔/\p Dse`:uԴzYM)ɗ"#i1ݳ{>dЌS[MX@M4e ޼,?}w4avs7}?3 lo39/"XEsu%ᅳ/*YàFrXfB‱Iƈy!y:{@oKi+}V0,g;j<11|V+tI"Q/VHl_iyy3 M(B9[&eCkZZ(뱪52pz xTPӥxF[)H\sy L"$-Ը"E*GĿ}> Km6 NV>6q `{eB:l# gų4qb-(R7g②JYh'3в2;\hx|Ms&H8ÍFL,( 8/mF#&zBvѠ*ѳD(-[bx\]߂ y\˫ |HԪ9R̮aQA&z)v4Q OMx:]~<]L^9ܣ[sֶFbtjJE[kȕìp<27^aB[τq'^{5: :"&V==y֌`BQI!chҜHPkfQj_Hd@?ςZy97rލNhHqZf U25ڠ&y;!<4|d,~mTJҹ)L`"e~OW PkM@paPECUOk-lbd-}}k^M*5ykpW' rXK6quA ;deepTools-2.5.0/deeptoolsintervals/test/GRCh38.84.labels.bed0000640000201600010240000000102512757050137022635 0ustar ryanbioinfo# # chrom start end deepTools_group #another random line 1 11868 14409 group 1 1 12009 13670 group 1 1 14403 29570 group 1 1 17368 17436 group 1 1 29553 31097 group 2 1 30266 31109 group 2 1 30365 30503 group 2 1 34553 36081 group 2 1 35244 36073 group 2 1 52472 53312 group 2 1 62947 63887 group 2 1 69090 70008 group 2 1 89294 120932 group 2 1 92229 129217 group 3 1 110952 129173 group 3 1 120724 133723 group 3 1 129080 133566 group 3 1 89550 91105 group 3 1 131024 134836 group 3 1 135140 135895 group 3 1 137681 137965 group 4 deepTools-2.5.0/deeptoolsintervals/tree/0000750000201600010240000000000013067415120017501 5ustar ryanbioinfodeepTools-2.5.0/deeptoolsintervals/tree/findOverlaps.c0000640000201600010240000004333312757050137022320 0ustar ryanbioinfo#include #include #include #include "gtf.h" /******************************************************************************* * * Comparison functions * * These are according to Allen's Interval Algebra * *******************************************************************************/ static inline int rangeAny(uint32_t start, uint32_t end, GTFentry *e) { if(end <= e->start) return -1; if(start >= e->end) return 1; return 0; } static inline int rangeContains(uint32_t start, uint32_t end, GTFentry *e) { if(e->start >= start && e->end <= end) return 0; if(e->end < end) return -1; return 1; } static inline int rangeWithin(uint32_t start, uint32_t end, GTFentry *e) { if(start >= e->start && end <= e->end) return 0; if(start < e->start) return -1; return 1; } static inline int rangeExact(uint32_t start, uint32_t end, GTFentry *e) { if(start == e->start && end == e->end) return 0; if(start < e->start) return -1; if(end < e->end) return -1; return 1; } static inline int rangeStart(uint32_t start, uint32_t end, GTFentry *e) { if(start == e->start) return 0; if(start < e->start) return -1; return 1; } static inline int rangeEnd(uint32_t start, uint32_t end, GTFentry *e) { if(end == e->end) return 0; if(end < e->end) return -1; return 1; } static inline int exactSameStrand(int strand, GTFentry *e) { return strand == e->strand; } static inline int sameStrand(int strand, GTFentry *e) { if(strand == 3 || e->strand == 3) return 1; if(strand == e->strand) return 1; return 0; } static inline int oppositeStrand(int strand, GTFentry *e) { if(strand == 3 || e->strand == 3) return 1; if(strand != e->strand) return 1; return 0; } /******************************************************************************* * * OverlapSet functions * *******************************************************************************/ overlapSet *os_init(GTFtree *t) { overlapSet *os = calloc(1, sizeof(overlapSet)); assert(os); os->tree = t; return os; } void os_reset(overlapSet *os) { int i; for(i=0; il; i++) os->overlaps[i] = NULL; os->l = 0; } void os_destroy(overlapSet *os) { if(os->overlaps) free(os->overlaps); free(os); } overlapSet *os_grow(overlapSet *os) { int i; os->m++; kroundup32(os->m); os->overlaps = realloc(os->overlaps, os->m * sizeof(GTFentry*)); assert(os->overlaps); for(i=os->l; im; i++) os->overlaps[i] = NULL; return os; } static void os_push(overlapSet *os, GTFentry *e) { if(os->l+1 >= os->m) os = os_grow(os); os->overlaps[os->l++] = e; } overlapSet *os_dup(overlapSet *os) { int i; overlapSet *os2 = os_init(os->tree); for(i=0; il; i++) os_push(os2, os->overlaps[i]); return os2; } void os_exclude(overlapSet *os, int i) { int j; for(j=i; jl-1; j++) os->overlaps[j] = os->overlaps[j+1]; os->overlaps[--os->l] = NULL; } static int os_sortFunc(const void *a, const void *b) { GTFentry *pa = *(GTFentry**) a; GTFentry *pb = *(GTFentry**) b; if(pa->start < pb->start) return -1; if(pb->start < pa->start) return 1; if(pa->end < pb->end) return -1; if(pb->end < pa->end) return 1; return 0; } static void os_sort(overlapSet *os) { qsort((void *) os->overlaps, os->l, sizeof(GTFentry**), os_sortFunc); } //Non-existant keys/values will be ignored void os_requireAttributes(overlapSet *os, char **key, char **val, int len) { int i, j, k, filter; int32_t keyHash, valHash; for(i=0; il) break; keyHash = str2valHT(os->tree->htAttributes, key[i]); valHash = str2valHT(os->tree->htAttributes, val[i]); assert(keyHash>=0); assert(valHash>=0); for(j=0; jl; j++) { filter = 1; for(k=0; koverlaps[j]->nAttributes; k++) { if(os->overlaps[j]->attrib[k]->key == keyHash) { if(os->overlaps[j]->attrib[k]->val == valHash) { filter = 0; break; } } } if(filter) { os_exclude(os, j); j--; //os_exclude shifts everything } } } } //This is an inefficient implementation. It would be faster to sort according //to COMPARE_FUNC and then do an O(n) merge. overlapSet *os_intersect(overlapSet *os1, overlapSet *os2, COMPARE_FUNC f) { overlapSet *os = os_init(os1->tree); int i, j; for(i=0; il; i++) { for(j=0; jl; j++) { if(f(os1->overlaps[i],os2->overlaps[j]) == 0) { os_push(os, os1->overlaps[i]); os_exclude(os2, j); break; } } } return os; } /******************************************************************************* * * OverlapSetList functions * *******************************************************************************/ overlapSetList *osl_init() { overlapSetList *osl = calloc(1, sizeof(overlapSetList)); assert(osl); return osl; } void osl_reset(overlapSetList *osl) { int i; for(i=0; il; i++) os_destroy(osl->os[i]); osl->l = 0; } void osl_destroy(overlapSetList *osl) { osl_reset(osl); if(osl->os) free(osl->os); free(osl); } void osl_grow(overlapSetList *osl) { int i; osl->m++; kroundup32(osl->m); osl->os = realloc(osl->os, osl->m * sizeof(overlapSet*)); assert(osl->os); for(i=osl->l; im; i++) osl->os[i] = NULL; } void osl_push(overlapSetList *osl, overlapSet *os) { if(osl->l+1 >= osl->m) osl_grow(osl); osl->os[osl->l++] = os; } //The output needs to be destroyed overlapSet *osl_intersect(overlapSetList *osl, COMPARE_FUNC f) { int i; if(!osl->l) return NULL; overlapSet *osTmp, *os = os_dup(osl->os[0]); for(i=1; il; i++) { osTmp = os_intersect(os, osl->os[i], f); os_destroy(os); os = osTmp; if(os->l == 0) break; } return os; } //Returns 1 if the node is in the overlapSet, otherwise 0. int os_contains(overlapSet *os, GTFentry *e) { int i; for(i=0; il; i++) { if(os->overlaps[i] == e) return 1; } return 0; } //This could be made much more efficient overlapSet *osl_union(overlapSetList *osl) { int i, j; if(!osl->l) NULL; if(!osl->os) return NULL; if(!osl->os[0]) return NULL; overlapSet *os = os_dup(osl->os[0]); for(i=1; il; i++) { for(j=0; jos[i]->l; j++) { if(!os_contains(os, osl->os[i]->overlaps[j])) { os_push(os, osl->os[i]->overlaps[j]); } } } return os; } /******************************************************************************* * * uniqueSet functions * *******************************************************************************/ static uniqueSet *us_init(hashTable *ht) { uniqueSet *us = calloc(1, sizeof(uniqueSet)); assert(us); us->ht = ht; return us; } void us_destroy(uniqueSet *us) { if(!us) return; if(us->IDs) { free(us->IDs); free(us->cnts); } free(us); } static uniqueSet *us_grow(uniqueSet *us) { int i; us->m++; kroundup32(us->m); us->IDs = realloc(us->IDs, us->m * sizeof(int32_t)); assert(us->IDs); us->cnts = realloc(us->cnts, us->m * sizeof(uint32_t)); assert(us->cnts); for(i=us->l; im; i++) { us->IDs[i] = -1; us->cnts[i] = 0; } return us; } static void us_push(uniqueSet *us, int32_t ID) { if(us->l+1 >= us->m) us = us_grow(us); us->IDs[us->l] = ID; us->cnts[us->l++] = 1; } static void us_inc(uniqueSet *us) { assert(us->l<=us->m); us->cnts[us->l-1]++; } uint32_t us_cnt(uniqueSet *us, int32_t i) { assert(il); return us->cnts[i]; } char *us_val(uniqueSet *us, int32_t i) { if(i>=us->l) return NULL; return val2strHT(us->ht, us->IDs[i]); } /******************************************************************************* * * Overlap set count/unique functions * *******************************************************************************/ static int int32_t_cmp(const void *a, const void *b) { int32_t ia = *((int32_t*) a); int32_t ib = *((int32_t*) b); return ia-ib; } int32_t cntAttributes(overlapSet *os, char *attributeName) { int32_t IDs[os->l], i, j, key, last, n = 0; if(!strExistsHT(os->tree->htAttributes, attributeName)) return n; key = str2valHT(os->tree->htAttributes, attributeName); for(i=0; il; i++) { IDs[i] = -1; for(j=0; joverlaps[i]->nAttributes; j++) { if(os->overlaps[i]->attrib[j]->key == key) { IDs[i] = os->overlaps[i]->attrib[j]->val; break; } } } qsort((void*) IDs, os->l, sizeof(int32_t), int32_t_cmp); last = IDs[0]; n = (last >= 0) ? 1 : 0; for(i = 1; il; i++) { if(IDs[i] != last) { n++; last = IDs[i]; } } return n; } uniqueSet *uniqueAttributes(overlapSet *os, char *attributeName) { if(!os) return NULL; if(os->l == 0) return NULL; int32_t IDs[os->l], i, j, key, last; if(!strExistsHT(os->tree->htAttributes, attributeName)) return NULL; uniqueSet *us = us_init(os->tree->htAttributes); key = str2valHT(os->tree->htAttributes, attributeName); for(i=0; il; i++) { IDs[i] = -1; for(j=0; joverlaps[i]->nAttributes; j++) { if(os->overlaps[i]->attrib[j]->key == key) { IDs[i] = os->overlaps[i]->attrib[j]->val; break; } } } qsort((void*) IDs, os->l, sizeof(int32_t), int32_t_cmp); last = -1; for(i=0; il; i++) { if(IDs[i] != last || last < 0) { us_push(us, IDs[i]); last = IDs[i]; } else { us_inc(us); } } if(us->l) return us; us_destroy(us); return NULL; } /******************************************************************************* * * Node iterator functions * *******************************************************************************/ //bit 1: go left, bit 2: go right (a value of 3 is then "do both") static int centerDirection(uint32_t start, uint32_t end, GTFnode *n) { if(n->center >= start && n->center < end) return 3; if(n->center < start) return 2; return 1; } static int matchingStrand(GTFentry *e, int strand, int strandType) { if(strandType == GTF_IGNORE_STRAND) return 1; if(strandType == GTF_SAME_STRAND) { return sameStrand(strand, e); } else if(strandType == GTF_OPPOSITE_STRAND) { return oppositeStrand(strand, e); } else if(strandType == GTF_EXACT_SAME_STRAND) { return exactSameStrand(strand, e); } fprintf(stderr, "[matchingStrand] Unknown strand type %i. Assuming a match.\n", strandType); return 1; } static void filterStrand(overlapSet *os, int strand, int strandType) { int i; if(strandType == GTF_IGNORE_STRAND) return; for(i=os->l-1; i>=0; i--) { if(strandType == GTF_SAME_STRAND) { if(!sameStrand(strand, os->overlaps[i])) os_exclude(os, i); } else if(strandType == GTF_OPPOSITE_STRAND) { if(!oppositeStrand(strand, os->overlaps[i])) os_exclude(os, i); } else if(strandType == GTF_EXACT_SAME_STRAND) { if(!exactSameStrand(strand, os->overlaps[i])) os_exclude(os, i); } } } static void pushOverlaps(overlapSet *os, GTFtree *t, GTFentry *e, uint32_t start, uint32_t end, int comparisonType, int direction, FILTER_ENTRY_FUNC ffunc) { int dir; int keep = 1; if(!e) return; if(ffunc) keep = ffunc(t, e); switch(comparisonType) { case GTF_MATCH_EXACT : if((dir = rangeExact(start, end, e)) == 0) { if(keep) os_push(os, e); } break; case GTF_MATCH_WITHIN : if((dir = rangeAny(start, end, e)) == 0) { if(keep) if(rangeWithin(start, end ,e) == 0) os_push(os, e); } break; case GTF_MATCH_CONTAIN : if((dir = rangeAny(start, end, e)) == 0) { if(keep) if(rangeContains(start, end, e) == 0) os_push(os, e); } break; case GTF_MATCH_START : if((dir = rangeStart(start, end, e)) == 0) { if(keep) os_push(os, e); } break; case GTF_MATCH_END : if((dir = rangeEnd(start, end, e)) == 0) { if(keep) os_push(os, e); } break; default : if((dir = rangeAny(start, end, e)) == 0) { if(keep) os_push(os, e); } break; } if(direction) { if(dir > 0) return; pushOverlaps(os, t, e->right, start, end, comparisonType, direction, ffunc); } else { if(dir < 0) return; pushOverlaps(os, t, e->left, start, end, comparisonType, direction, ffunc); } } static int32_t countOverlapsEntry(GTFtree *t, GTFentry *e, uint32_t start, uint32_t end, int strand, int matchType, int strandType, int direction, int32_t max, FILTER_ENTRY_FUNC ffunc) { int dir; int32_t cnt = 0; if(!e) return cnt; switch(matchType) { case GTF_MATCH_EXACT : if((dir = rangeExact(start, end, e)) == 0) { cnt = 1; } break; case GTF_MATCH_WITHIN : if((dir = rangeAny(start, end, e)) == 0) { if(rangeWithin(start, end, e) == 0) cnt = 1; } break; case GTF_MATCH_CONTAIN : if((dir = rangeAny(start, end, e)) == 0) { if(rangeContains(start, end, e) == 0) cnt = 1; } break; case GTF_MATCH_START : if((dir = rangeStart(start, end, e)) == 0) { cnt = 1; } break; case GTF_MATCH_END : if((dir = rangeEnd(start, end, e)) == 0) { cnt = 1; } break; default : if((dir = rangeAny(start, end, e)) == 0) { cnt = 1; } break; } if(cnt) { if(!matchingStrand(e, strand, strandType)) cnt = 0; } if(cnt && ffunc) { if(!ffunc(t, e)) cnt = 0; } if(max && cnt >= max) return max; if(direction) { if(dir > 0) return cnt; return cnt + countOverlapsEntry(t, e->right, start, end, strand, matchType, strandType, direction, max, ffunc); } else { if(dir < 0) return cnt; return cnt + countOverlapsEntry(t, e->left, start, end, strand, matchType, strandType, direction, max, ffunc); } } static void pushOverlapsNode(overlapSet *os, GTFtree *t, GTFnode *n, uint32_t start, uint32_t end, int matchType, FILTER_ENTRY_FUNC ffunc) { int dir; if(!n) return; dir = centerDirection(start, end, n); if(dir&1) { pushOverlaps(os, t, n->starts, start, end, matchType, 1, ffunc); pushOverlapsNode(os, t, n->left, start, end, matchType, ffunc); } if(dir&2) { if(dir!=3) pushOverlaps(os, t, n->ends, start, end, matchType, 0, ffunc); pushOverlapsNode(os, t, n->right, start, end, matchType, ffunc); } } static int32_t countOverlapsNode(GTFtree *t, GTFnode *n, uint32_t start, uint32_t end, int strand, int matchType, int strandType, int32_t max, FILTER_ENTRY_FUNC ffunc) { int32_t cnt = 0; int dir; if(!n) return cnt; dir = centerDirection(start, end, n); if(dir&1) { cnt += countOverlapsEntry(t, n->starts, start, end, strand, matchType, strandType, 1, max, ffunc); if(max && cnt >= max) return max; cnt += countOverlapsNode(t, n->left, start, end, strand, matchType, strandType, max, ffunc); if(max && cnt >= max) return max; } if(dir&2) { if(dir!=3) cnt += countOverlapsEntry(t, n->starts, start, end, strand, matchType, strandType, 0, max, ffunc); if(max && cnt >= max) return max; cnt += countOverlapsNode(t, n->right, start, end, strand, matchType, strandType, max, ffunc); if(max && cnt >= max) return max; } return cnt; } /******************************************************************************* * * Driver functions for end use. * *******************************************************************************/ overlapSet * findOverlaps(overlapSet *os, GTFtree *t, char *chrom, uint32_t start, uint32_t end, int strand, int matchType, int strandType, int keepOS, FILTER_ENTRY_FUNC ffunc) { int32_t tid = str2valHT(t->htChroms, chrom); overlapSet *out = os; if(out && !keepOS) os_reset(out); else if(!out) out = os_init(t); if(tid<0) return out; if(!t->balanced) { fprintf(stderr, "[findOverlaps] The tree has not been balanced! No overlaps will be returned.\n"); return out; } pushOverlapsNode(out, t, (GTFnode*) t->chroms[tid]->tree, start, end, matchType, ffunc); if(out->l) filterStrand(out, strand, strandType); if(out->l) os_sort(out); return out; } int32_t countOverlaps(GTFtree *t, char *chrom, uint32_t start, uint32_t end, int strand, int matchType, int strandType, FILTER_ENTRY_FUNC ffunc) { int32_t tid = str2valHT(t->htChroms, chrom); if(tid<0) return 0; if(!t->balanced) { fprintf(stderr, "[countOverlaps] The tree has not been balanced! No overlaps will be returned.\n"); return 0; } return countOverlapsNode(t, (GTFnode*) t->chroms[tid]->tree, start, end, strand, matchType, strandType, 0, ffunc); } int overlapsAny(GTFtree *t, char *chrom, uint32_t start, uint32_t end, int strand, int matchType, int strandType, FILTER_ENTRY_FUNC ffunc) { int32_t tid = str2valHT(t->htChroms, chrom); if(tid<0) return 0; if(!t->balanced) { fprintf(stderr, "[overlapsAny] The tree has not been balanced! No overlaps will be returned.\n"); return 0; } return countOverlapsNode(t, (GTFnode*) t->chroms[tid]->tree, start, end, strand, matchType, strandType, 1, ffunc); } deepTools-2.5.0/deeptoolsintervals/tree/gtf.c0000640000201600010240000003724612757050137020452 0ustar ryanbioinfo#include #include #include #include #include "gtf.h" //Nodes for the interval tree typedef struct { int32_t center; int32_t l; GTFentry *start; GTFentry *end; struct treeNode *left; struct treeNode *right; } treeNode; //The sizes shouldn't be preset... GTFtree * initGTFtree() { GTFtree *t = calloc(1, sizeof(GTFtree)); assert(t); //Initialize the hash tables t->htChroms = initHT(128); t->htSources = initHT(128); t->htFeatures = initHT(128); t->htAttributes = initHT(128); return t; } void destroyGTFentry(GTFentry *e) { int32_t i; if(!e) return; if(e->right) destroyGTFentry(e->right); for(i=0; inAttributes; i++) { if(e->attrib[i]) free(e->attrib[i]); } if(e->attrib) free(e->attrib); free(e); } void destroyGTFnode(GTFnode *n) { if(n->left) destroyGTFnode(n->left); if(n->starts) destroyGTFentry(n->starts); if(n->right) destroyGTFnode(n->right); free(n); } void destroyGTFchrom(GTFchrom *c, int balanced) { if(balanced) destroyGTFnode((GTFnode*) c->tree); else destroyGTFentry((GTFentry*) c->tree); free(c); } //This need to handle htTargets and htGenes still void destroyGTFtree(GTFtree *t) { uint32_t i; for(i=0; in_targets; i++) { destroyGTFchrom(t->chroms[i], t->balanced); } destroyHT(t->htChroms); destroyHT(t->htSources); destroyHT(t->htFeatures); destroyHT(t->htAttributes); free(t->chroms); free(t); } void addChrom(GTFtree *t) { int i; t->n_targets++; //Grow if needed if(t->n_targets >= t->m) { t->m++; kroundup32(t->m); t->chroms = realloc(t->chroms, t->m * sizeof(GTFchrom *)); assert(t->chroms); for(i=t->n_targets-1; im; i++) t->chroms[i] = NULL; } assert(!t->chroms[t->n_targets-1]); //We shouldn't be adding over anything... t->chroms[t->n_targets-1] = calloc(1,sizeof(GTFchrom)); assert(t->chroms[t->n_targets-1]); } //Returns NULL on error static Attribute *makeAttribute(GTFtree *t, char *value) { int32_t idx; Attribute *a = malloc(sizeof(Attribute)); if(!a) return NULL; if(!strExistsHT(t->htAttributes, "transcript_id")) { idx = addHTelement(t->htAttributes, "transcript_id"); } else { idx = str2valHT(t->htAttributes, "transcript_id"); } a->key = idx; if(!strExistsHT(t->htAttributes, value)) { idx = addHTelement(t->htAttributes, value); } else { idx = str2valHT(t->htAttributes, value); } a->val = idx; return a; } /* This currently hard-codes the following: feature source frame all attributes (most are skipped) returns 1 on error */ int addGTFentry(GTFtree *t, char *chrom, uint32_t start, uint32_t end, uint8_t strand, char *transcriptID, uint32_t labelIDX, double score) { int32_t IDchrom, IDfeature, IDsource; char feature[] = "transcript", source[] = "deepTools"; uint8_t frame = 3; GTFentry *e = NULL; Attribute *a = NULL; Attribute **attribs = calloc(1, sizeof(Attribute *)); if(!attribs) return 1; //Get the chromosome ID if(!strExistsHT(t->htChroms, chrom)) { addChrom(t); IDchrom = addHTelement(t->htChroms, chrom); } else { IDchrom = str2valHT(t->htChroms, chrom); } //Handle the hard-coded stuff, which in case they're ever requested if(!strExistsHT(t->htSources, source)) { IDsource = addHTelement(t->htSources, source); } else { IDsource = str2valHT(t->htSources, source); } if(!strExistsHT(t->htFeatures, feature)) { IDfeature = addHTelement(t->htFeatures, feature); } else { IDfeature = str2valHT(t->htFeatures, feature); } //Create the attribute a = makeAttribute(t, transcriptID); if(!a) goto error; attribs[0] = a; //Initialize the entry e = malloc(sizeof(GTFentry)); if(!e) goto error; e->right = NULL; e->chrom = IDchrom; e->feature = IDfeature; e->source = IDsource; e->start = start; e->end = end; e->strand = strand; e->frame = frame; e->score = score; e->nAttributes = 1; e->attrib = attribs; e->labelIdx = labelIDX; if(t->chroms[IDchrom]->tree) { e->left = ((GTFentry*) t->chroms[IDchrom]->tree)->left; e->left->right = e; ((GTFentry*) t->chroms[IDchrom]->tree)->left = e; } else { t->chroms[IDchrom]->tree = (void *) e; e->left = e; } t->chroms[IDchrom]->n_entries++; return 0; error: if(attribs) free(attribs); if(a) free(a); if(e) free(e); return 1; } /* This currently hard-codes the following: name source frame all attributes returns 1 on error */ int addEnrichmententry(GTFtree *t, char *chrom, uint32_t start, uint32_t end, uint8_t strand, double score, char *feature) { int32_t IDchrom, IDfeature, IDsource; char source[] = "deepTools"; uint8_t frame = 3; GTFentry *e = NULL; //Attribute **attribs = calloc(1, sizeof(Attribute *)); //if(!attribs) return 1; //Get the chromosome ID if(!strExistsHT(t->htChroms, chrom)) { addChrom(t); IDchrom = addHTelement(t->htChroms, chrom); } else { IDchrom = str2valHT(t->htChroms, chrom); } //Handle the hard-coded stuff, in case they're ever requested if(!strExistsHT(t->htSources, source)) { IDsource = addHTelement(t->htSources, source); } else { IDsource = str2valHT(t->htSources, source); } if(!strExistsHT(t->htFeatures, feature)) { IDfeature = addHTelement(t->htFeatures, feature); } else { IDfeature = str2valHT(t->htFeatures, feature); } //Initialize the entry e = malloc(sizeof(GTFentry)); if(!e) goto error; e->right = NULL; e->chrom = IDchrom; e->feature = IDfeature; e->source = IDsource; e->start = start; e->end = end; e->strand = strand; e->frame = frame; e->score = score; e->nAttributes = 0; e->attrib = NULL; if(t->chroms[IDchrom]->tree) { e->left = ((GTFentry*) t->chroms[IDchrom]->tree)->left; e->left->right = e; ((GTFentry*) t->chroms[IDchrom]->tree)->left = e; } else { t->chroms[IDchrom]->tree = (void *) e; e->left = e; } t->chroms[IDchrom]->n_entries++; return 0; error: //if(attribs) free(attribs); //if(a) free(a); if(e) free(e); return 1; } /******************************************************************************* * * Sorting functions * *******************************************************************************/ GTFentry *getMiddleR(GTFentry *e, uint32_t pos) { uint32_t i; GTFentry *tmp, *o = e; if(!o->right) return o; for(i=1; iright); o = o->right; } tmp = o; assert(o->right); o = o->right; tmp->right = NULL; return o; } GTFentry *getMiddleL(GTFentry *e, uint32_t pos) { uint32_t i; GTFentry *tmp, *o = e; if(!o->left) { return o; } for(i=1; ileft); o = o->left; } tmp = o; assert(o->left); o = o->left; tmp->left = NULL; return o; } int cmpRangesStart(GTFentry *a, GTFentry *b) { if(!b && !a) return 0; if(!b) return -1; if(!a) return 1; if(a->start < b->start) return -1; if(b->start < a->start) return 1; if(b->end < a->end) return 1; return -1; } int cmpRangesEnd(GTFentry *a, GTFentry *b) { if(!b && !a) return 0; if(!a) return 1; if(!b) return -1; if(a->end > b->end) return -1; if(b->end > a->end) return 1; if(a->start > b->start) return -1; return 1; } GTFentry *mergeSortStart(GTFentry *a, GTFentry *b) { GTFentry *o = a, *last; int i = cmpRangesStart(a,b); if(i<0) { o = a; a = a->right; } else if(i>0) { o = b; b = b->right; } else{ return NULL; } last = o; last->right = NULL; while((i=cmpRangesStart(a,b))) { if(i>0) { last->right= b; last = b; b = b->right; } else { last->right= a; last = a; a = a->right; } } last->right = NULL; return o; } GTFentry *mergeSortEnd(GTFentry *a, GTFentry *b) { GTFentry *o = a, *last; int i = cmpRangesEnd(a,b); if(i<0) { o = a; a = a->left; } else if(i>0) { o = b; b = b->left; } else { return NULL; } last = o; last->left = NULL; while((i=cmpRangesEnd(a,b))) { if(i<0) { assert(a != last); last->left = a; last = a; a = a->left; } else { assert(b != last); last->left = b; last = b; b = b->left; } } last->left = NULL; return o; } GTFentry *sortTreeStart(GTFentry *e, uint32_t l) { if(l==1) return e; uint32_t half = l/2; GTFentry *middle = getMiddleR(e, half); return mergeSortStart(sortTreeStart(e,half), sortTreeStart(middle,half+(l&1))); } GTFentry *sortTreeEnd(GTFentry *e, uint32_t l) { if(l==1) { e->left = NULL; //The list is circular, so... return e; } uint32_t half = l/2; assert(e->left); assert(e != e->left); GTFentry *middle = getMiddleL(e, half); assert(e != middle); assert(e != e->left); return mergeSortEnd(sortTreeEnd(e,half), sortTreeEnd(middle,half+(l&1))); } /******************************************************************************* * * Functions for interval tree construction * *******************************************************************************/ //Note the returned object is the rightmost interval sorted by end position GTFentry *sortChrom(GTFchrom *c) { GTFentry *e = ((GTFentry *)c->tree)->left; ((GTFentry*) c->tree)->left = NULL; c->tree = (void *) sortTreeStart((GTFentry *) c->tree, c->n_entries); e = sortTreeEnd(e, c->n_entries); return e; } uint32_t getCenter(GTFentry *ends) { GTFentry *slow = ends; GTFentry *fast = ends; while(fast->left && fast->left->left) { slow = slow->left; fast = fast->left->left; } return slow->end-1; } GTFentry *getMembers(GTFentry **members, GTFentry **rStarts, GTFentry *starts, uint32_t pos) { GTFentry *tmp, *newStarts = NULL; GTFentry *last = NULL, *lastMember = NULL; *members = NULL, *rStarts = NULL; while(starts && starts->start <= pos) { if(starts->end > pos) { tmp = starts->right; if(!*members) { lastMember = starts; *members = starts; } else { lastMember->right = starts; lastMember = starts; } starts->right = NULL; starts = tmp; } else { if(!newStarts) { newStarts = starts; last = starts; } else { last->right = starts; last = starts; } starts = starts->right; } } *rStarts = starts; if(lastMember) lastMember->right = NULL; if(last) last->right = NULL; assert(*members); return newStarts; } GTFentry *getRMembers(GTFentry **members, GTFentry **lEnds, GTFentry *ends, uint32_t pos) { GTFentry *tmp, *newEnds = NULL; GTFentry *last = NULL, *lastMember = NULL; *members = NULL, *lEnds = NULL; while(ends && ends->end > pos) { tmp = ends->left; if(ends->start <= pos) { if(!*members) { *members = ends; lastMember = ends; } else { lastMember->left = ends; lastMember = ends; } } else { if(!newEnds) { newEnds = ends; last = ends; } else { last->left = ends; last = ends; } } ends->left = NULL; ends = tmp; } *lEnds = ends; assert(*members); lastMember->left = NULL; if(newEnds) last->left = NULL; return newEnds; } GTFnode *makeIntervalTree(GTFentry *starts, GTFentry *ends) { uint32_t center = getCenter(ends);//, nMembers; GTFentry *rStarts = NULL; //getRStarts(starts, center); GTFentry *lEnds = NULL; //getLEnds(ends, center); GTFentry *memberStarts = NULL, *memberEnds = NULL; GTFnode *out = calloc(1, sizeof(GTFnode)); assert(out); starts = getMembers(&memberStarts, &rStarts, starts, center); ends = getRMembers(&memberEnds, &lEnds, ends, center); out->center = center; out->starts = memberStarts; out->ends = memberEnds; if(lEnds && starts) { out->left = makeIntervalTree(starts, lEnds); } else { out->left = NULL; } if(rStarts && ends) { out->right = makeIntervalTree(rStarts, ends); } else { out->right = NULL; } return out; } void sortGTF(GTFtree *t) { int32_t i; GTFentry *ends; for(i=0; in_targets; i++) { ends = sortChrom(t->chroms[i]); t->chroms[i]->tree = (void*) makeIntervalTree((GTFentry*) t->chroms[i]->tree, ends); } t->balanced = 1; } /******************************************************************************* * * Misc. functions * *******************************************************************************/ void printBalancedGTF(GTFnode *n, const char *chrom) { kstring_t ks, ks2; ks.s = NULL; ks.l = ks.m = 0; ks2.s = NULL; ks2.l = ks2.m = 0; kputs(chrom, &ks); kputc(':', &ks); kputuw(n->center, &ks); if(n->left) { kputs(chrom, &ks2); kputc(':', &ks2); kputuw(n->left->center, &ks2); printf("\t\"%s\" -> \"%s\";\n", ks.s, ks2.s); printBalancedGTF(n->left, chrom); } printf("\t\"%s:%"PRIu32"\" [shape=box];\n", chrom, n->center); GTFentry *e = n->starts; if(e) printGTFvineStart(e, chrom, ks.s); if(n->ends) printGTFvineStartR(n->ends, chrom, ks.s); if(n->right) { ks2.l = 0; kputs(chrom, &ks2); kputc(':', &ks2); kputuw(n->right->center, &ks2); printf("\t\"%s\" -> \"%s\";\n", ks.s, ks2.s); printBalancedGTF(n->right, chrom); } free(ks.s); if(ks2.s) free(ks2.s); } void printGTFvineR(GTFentry *e, const char* chrom) { if(e->left == e) return; if(!e->left) return; printf("\t\"%s:%"PRIu32"-%"PRIu32"\" -> \"%s:%"PRIu32"-%"PRIu32"\" [color=red];\n", chrom, e->start, e->end, chrom, e->left->start, e->left->end); printGTFvineR(e->left, chrom); } void printGTFvineStartR(GTFentry *e, const char *chrom, const char *str) { printf("\t\"%s\" -> \"%s:%"PRIu32"-%"PRIu32"\" [color=red];\n", str, chrom, e->start, e->end); if(e->left) printGTFvineR(e, chrom); } void printGTFvine(GTFentry *e, const char* chrom) { if(!e->right) return; printf("\t\"%s:%"PRIu32"-%"PRIu32"\" -> \"%s:%"PRIu32"-%"PRIu32"\";\n", chrom, e->start, e->end, chrom, e->right->start, e->right->end); printGTFvine(e->right, chrom); } void printGTFvineStart(GTFentry *e, const char *chrom, const char *str) { printf("\t\"%s\" -> \"%s:%"PRIu32"-%"PRIu32"\";\n", str, chrom, e->start, e->end); if(e->right) printGTFvine(e, chrom); } void printGTFtree(GTFtree *t) { int32_t i; const char *chromName; if(t->balanced) printf("digraph balancedTree {\n"); else printf("digraph unbalancedTree {\n"); for(i=0; in_targets; i++) { chromName = val2strHT(t->htChroms, i); if(t->balanced) { printBalancedGTF((GTFnode*) t->chroms[i]->tree, chromName); } else { printGTFvineStart((GTFentry*) t->chroms[i]->tree, chromName, chromName); } } printf("}\n"); } deepTools-2.5.0/deeptoolsintervals/tree/gtf.h0000640000201600010240000001242512757050137020447 0ustar ryanbioinfo#include #include "kstring.h" /***************** * Strand macros * *****************/ #define GTF_IGNORE_STRAND 0 #define GTF_SAME_STRAND 1 #define GTF_OPPOSITE_STRAND 2 #define GTF_EXACT_SAME_STRAND 3 /*********************** * Overlap type macros * ***********************/ #define GTF_MATCH_ANY 0 #define GTF_MATCH_EXACT 1 #define GTF_MATCH_CONTAIN 2 #define GTF_MATCH_WITHIN 3 #define GTF_MATCH_START 4 #define GTF_MATCH_END 5 typedef struct { int32_t key; int32_t val; } Attribute; /*! @typedef @abstract Structure for a single GTF line @field chrom Index into the chrom hash table @field source Index into the source hash table @field feature Index into the feature hash table @field start 0-based starting position @field end 1-based end position @field score The score field. A value of DBL_MAX indicates a "." @field strand 0: '+'; 1: '-'; 3: '.' @field frame 0: '0'; 1: '1'; 2: '2'; 3: '.' @field gene_id Index into the gene_id hash table @field transcript_id Index into the transcript_id hash table @discussion Positions are 0-based half open ([start, end)), like BED files. */ typedef struct GTFentry { int32_t chrom; int32_t source; int32_t feature; uint32_t start; uint32_t end; double score; uint8_t strand:4, frame:4; int32_t gene_id; int32_t transcript_id; uint32_t labelIdx; int nAttributes; Attribute **attrib; struct GTFentry *left, *right; } GTFentry; typedef struct { kstring_t chrom; kstring_t feature; kstring_t source; uint32_t start; uint32_t end; double score; uint8_t strand:4, frame: 4; kstring_t gene; kstring_t transcript; int nAttributes; Attribute **attrib; } GTFline; typedef struct GTFnode { uint32_t center; GTFentry *starts, *ends; struct GTFnode *left, *right; } GTFnode; typedef struct { int32_t chrom; uint32_t n_entries; void **tree; } GTFchrom; typedef struct hashTableElement { int32_t val; struct hashTableElement *next; } hashTableElement; typedef struct { uint64_t l, m; hashTableElement **elements; char **str; } hashTable; typedef struct { int32_t n_targets, m; int balanced; hashTable *htChroms; hashTable *htSources; hashTable *htFeatures; hashTable *htAttributes; GTFchrom **chroms; } GTFtree; typedef struct { int32_t l, m; GTFentry **overlaps; GTFtree *tree; } overlapSet; typedef struct { int32_t l, m; overlapSet **os; } overlapSetList; typedef struct { int32_t l, m; int32_t *IDs; uint32_t *cnts; hashTable *ht; } uniqueSet; //A function that can be applied to all entries in a GTF/BED/etc. file as it's //being processed. The pointer as input is currently a GTFline *. The return //value is 0 (ignore entry) or 1 (keep entry). typedef int (*FILTER_FUNC)(void*); typedef int (*FILTER_ENTRY_FUNC)(GTFtree *, GTFentry *); //A function used to compare to GTFentry items to see if the intersect in some //way (e.g., due to sharing a gene_id). This is used to intersect overlapsets. typedef int (*COMPARE_FUNC)(GTFentry *, GTFentry *); //gtf.c GTFtree * initGTFtree(void); void destroyGTFtree(GTFtree *t); void sortGTF(GTFtree *o); void printGTFtree(GTFtree *t); void printGTFvineStart(GTFentry *e, const char *chrom, const char *str); void printGTFvineStartR(GTFentry *e, const char *chrom, const char *str); int addGTFentry(GTFtree *t, char *chrom, uint32_t start, uint32_t end, uint8_t strand, char *transcriptID, uint32_t labelIDX, double score); int addEnrichmententry(GTFtree *t, char *chrom, uint32_t start, uint32_t end, uint8_t strand, double score, char *feature); //hashTable.c hashTable *initHT(uint64_t size); void destroyHTelement(hashTableElement *e); void destroyHT(hashTable *ht); int32_t addHTelement(hashTable *ht, char *s); uint64_t hashString(char *s); int strExistsHT(hashTable *ht, char *s); int32_t str2valHT(hashTable *ht, char *s); char *val2strHT(hashTable *ht, int32_t val); int hasAttribute(GTFtree *t, GTFentry *e, char *str); char *getAttribute(GTFtree *t, GTFentry *e, char *str); //NULL if the attribute isn't there //findOverlaps.c //overlapSet functions overlapSet *os_init(GTFtree *t); void os_reset(overlapSet *os); void os_destroy(overlapSet *os); overlapSet *os_grow(overlapSet *os); void os_exclude(overlapSet *os, int i); void os_requireAttributes(overlapSet *os, char **keys, char **vals, int len); void os_requireSource(overlapSet *os, char *val); void os_requireFeature(overlapSet *os, char *val); overlapSet *os_intersect(overlapSet *os1, overlapSet *os2, COMPARE_FUNC f); //overlapSetList functions overlapSetList *osl_init(void); void osl_reset(overlapSetList *osl); void osl_destroy(overlapSetList *osl); void osl_push(overlapSetList *osl, overlapSet *os); void osl_grow(overlapSetList *osl); overlapSet *osl_intersect(overlapSetList *osl, COMPARE_FUNC f); overlapSet *osl_union(overlapSetList *osl); //uniqueSet functions void us_destroy(uniqueSet *us); uint32_t us_cnt(uniqueSet *us, int32_t i); char *us_val(uniqueSet *us, int32_t i); //Driver functions overlapSet * findOverlaps(overlapSet *os, GTFtree *t, char *chrom, uint32_t start, uint32_t end, int strand, int matchType, int strandType, int keepOS, FILTER_ENTRY_FUNC ffunc); deepTools-2.5.0/deeptoolsintervals/tree/hashTable.c0000640000201600010240000000754612757050137021565 0ustar ryanbioinfo#include #include #include #include #include "murmur3.h" #include "gtf.h" uint64_t hashString(char *s) { int len = strlen(s); uint64_t hash_val[2]; uint32_t seed = 0xAAAAAAAA; #if UINTPTR_MAX == 0xffffffff MurmurHash3_x86_128((void *) s, len, seed, (void *) &hash_val); #else MurmurHash3_x64_128((void *) s, len, seed, (void *) &hash_val); #endif return hash_val[0]; } hashTable *initHT(uint64_t size) { hashTable *ht = calloc(1, sizeof(hashTable)); assert(ht); ht->elements = calloc(size, sizeof(hashTableElement*)); assert(ht->elements); ht->str = calloc(size, sizeof(char*)); assert(ht->str); ht->m = size; return ht; } void insertHTelement(hashTable *ht, hashTableElement *e, uint64_t hash) { uint64_t i = hash%ht->m; hashTableElement *curr = ht->elements[i]; if(!curr) ht->elements[i] = e; else { while(curr->next) curr = curr->next; curr->next = e; } } static void rehashElement(hashTable *ht, hashTableElement *e) { hashTableElement *next = e->next; if(!e) return; uint64_t hash = hashString(ht->str[e->val]); e->next = NULL; insertHTelement(ht, e, hash); if(next) rehashElement(ht, next); } static void rehashHT(hashTable *ht) { int32_t i; hashTableElement *e; for(i=0; il; i++) { if(ht->elements[i]) { e = ht->elements[i]; ht->elements[i] = NULL; rehashElement(ht, e); } } } static void growHT(hashTable *ht) { int i; ht->m = ht->l+1; kroundup32(ht->m); ht->str = realloc(ht->str, ht->m*sizeof(char*)); assert(ht->str); ht->elements = realloc(ht->elements, ht->m*sizeof(hashTableElement*)); for(i=ht->l; im; i++) { ht->str[i] = NULL; ht->elements[i] = NULL; } rehashHT(ht); } //don't do this if the element's already in the table! int32_t addHTelement(hashTable *ht, char *s) { if(!s) return -1; uint64_t hash = hashString(s); int32_t val = ht->l++; if(ht->l >= ht->m) growHT(ht); ht->str[val] = strdup(s); hashTableElement *e = calloc(1, sizeof(hashTableElement)); assert(e); e->val = val; insertHTelement(ht, e, hash); return val; } void destroyHTelement(hashTableElement *e) { hashTableElement *next = e->next; free(e); if(next) destroyHTelement(next); } void destroyHT(hashTable *ht) { int i; for(i=0; il; i++) free(ht->str[i]); for(i=0; im; i++) { if(ht->elements[i]) destroyHTelement(ht->elements[i]); } free(ht->elements); free(ht->str); free(ht); } int strExistsHT(hashTable *ht, char *s) { if(!s) return 0; uint64_t h = hashString(s); hashTableElement *curr = ht->elements[h%ht->m]; while(curr) { if(strcmp(ht->str[curr->val], s) == 0) return 1; curr = curr->next; } return 0; } //Returns -1 if not present int32_t str2valHT(hashTable *ht, char *s) { if(!s) return -1; uint64_t h = hashString(s); hashTableElement *curr = ht->elements[h%ht->m]; while(curr) { if(strcmp(ht->str[curr->val], s) == 0) return curr->val; curr = curr->next; } return -1; } //Returns NULL on error char *val2strHT(hashTable *ht, int32_t val) { if(val<0) return NULL; if(val>=ht->l) return NULL; return ht->str[val]; } int hasAttribute(GTFtree *t, GTFentry *e, char *str) { int32_t i, key = str2valHT(t->htAttributes, str); for(i=0; inAttributes; i++) { if(e->attrib[i]->key == key) return 1; } return 0; } //Returns NULL if the entry lacks the attribute char *getAttribute(GTFtree *t, GTFentry *e, char *str) { int32_t i, key = str2valHT(t->htAttributes, str); for(i=0; inAttributes; i++) { if(e->attrib[i]->key == key) return val2strHT(t->htAttributes, e->attrib[i]->val); } return NULL; } deepTools-2.5.0/deeptoolsintervals/tree/kseq.h0000640000201600010240000002130412757050137020626 0ustar ryanbioinfo/* The MIT License Copyright (c) 2008, 2009, 2011 Attractive Chaos Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* Last Modified: 05MAR2012 */ #ifndef AC_KSEQ_H #define AC_KSEQ_H #include #include #include #define KS_SEP_SPACE 0 // isspace(): \t, \n, \v, \f, \r #define KS_SEP_TAB 1 // isspace() && !' ' #define KS_SEP_LINE 2 // line separator: "\n" (Unix) or "\r\n" (Windows) #define KS_SEP_MAX 2 #define __KS_TYPE(type_t) \ typedef struct __kstream_t { \ int begin, end; \ int is_eof:2, bufsize:30; \ uint64_t seek_pos; \ type_t f; \ unsigned char *buf; \ } kstream_t; #define ks_eof(ks) ((ks)->is_eof && (ks)->begin >= (ks)->end) #define ks_rewind(ks) ((ks)->is_eof = (ks)->begin = (ks)->end = 0) #define __KS_BASIC(SCOPE, type_t, __bufsize) \ SCOPE kstream_t *ks_init(type_t f) \ { \ kstream_t *ks = (kstream_t*)calloc(1, sizeof(kstream_t)); \ ks->f = f; ks->bufsize = __bufsize; \ ks->buf = (unsigned char*)malloc(__bufsize); \ return ks; \ } \ SCOPE void ks_destroy(kstream_t *ks) \ { \ if (!ks) return; \ free(ks->buf); \ free(ks); \ } #define __KS_INLINED(__read) \ static inline int ks_getc(kstream_t *ks) \ { \ if (ks->is_eof && ks->begin >= ks->end) return -1; \ if (ks->begin >= ks->end) { \ ks->begin = 0; \ ks->end = __read(ks->f, ks->buf, ks->bufsize); \ if (ks->end == 0) { ks->is_eof = 1; return -1; } \ } \ ks->seek_pos++; \ return (int)ks->buf[ks->begin++]; \ } \ static inline int ks_getuntil(kstream_t *ks, int delimiter, kstring_t *str, int *dret) \ { return ks_getuntil2(ks, delimiter, str, dret, 0); } #ifndef KSTRING_T #define KSTRING_T kstring_t typedef struct __kstring_t { size_t l, m; char *s; } kstring_t; #endif #ifndef kroundup32 #define kroundup32(x) (--(x), (x)|=(x)>>1, (x)|=(x)>>2, (x)|=(x)>>4, (x)|=(x)>>8, (x)|=(x)>>16, ++(x)) #endif #define __KS_GETUNTIL(SCOPE, __read) \ SCOPE int ks_getuntil2(kstream_t *ks, int delimiter, kstring_t *str, int *dret, int append) \ { \ int gotany = 0; \ if (dret) *dret = 0; \ str->l = append? str->l : 0; \ uint64_t seek_pos = str->l; \ for (;;) { \ int i; \ if (ks->begin >= ks->end) { \ if (!ks->is_eof) { \ ks->begin = 0; \ ks->end = __read(ks->f, ks->buf, ks->bufsize); \ if (ks->end == 0) { ks->is_eof = 1; break; } \ } else break; \ } \ if (delimiter == KS_SEP_LINE) { \ for (i = ks->begin; i < ks->end; ++i) \ if (ks->buf[i] == '\n') break; \ } else if (delimiter > KS_SEP_MAX) { \ for (i = ks->begin; i < ks->end; ++i) \ if (ks->buf[i] == delimiter) break; \ } else if (delimiter == KS_SEP_SPACE) { \ for (i = ks->begin; i < ks->end; ++i) \ if (isspace(ks->buf[i])) break; \ } else if (delimiter == KS_SEP_TAB) { \ for (i = ks->begin; i < ks->end; ++i) \ if (isspace(ks->buf[i]) && ks->buf[i] != ' ') break; \ } else i = 0; /* never come to here! */ \ if (str->m - str->l < (size_t)(i - ks->begin + 1)) { \ str->m = str->l + (i - ks->begin) + 1; \ kroundup32(str->m); \ str->s = (char*)realloc(str->s, str->m); \ } \ seek_pos += i - ks->begin; if ( i < ks->end ) seek_pos++; \ gotany = 1; \ memcpy(str->s + str->l, ks->buf + ks->begin, i - ks->begin); \ str->l = str->l + (i - ks->begin); \ ks->begin = i + 1; \ if (i < ks->end) { \ if (dret) *dret = ks->buf[i]; \ break; \ } \ } \ if (!gotany && ks_eof(ks)) return -1; \ ks->seek_pos += seek_pos; \ if (str->s == 0) { \ str->m = 1; \ str->s = (char*)calloc(1, 1); \ } else if (delimiter == KS_SEP_LINE && str->l > 1 && str->s[str->l-1] == '\r') --str->l; \ str->s[str->l] = '\0'; \ return str->l; \ } #define KSTREAM_INIT2(SCOPE, type_t, __read, __bufsize) \ __KS_TYPE(type_t) \ __KS_BASIC(SCOPE, type_t, __bufsize) \ __KS_GETUNTIL(SCOPE, __read) \ __KS_INLINED(__read) #define KSTREAM_INIT(type_t, __read, __bufsize) KSTREAM_INIT2(static, type_t, __read, __bufsize) #define KSTREAM_DECLARE(type_t, __read) \ __KS_TYPE(type_t) \ extern int ks_getuntil2(kstream_t *ks, int delimiter, kstring_t *str, int *dret, int append); \ extern kstream_t *ks_init(type_t f); \ extern void ks_destroy(kstream_t *ks); \ __KS_INLINED(__read) /****************** * FASTA/Q parser * ******************/ #define kseq_rewind(ks) ((ks)->last_char = (ks)->f->is_eof = (ks)->f->begin = (ks)->f->end = 0) #define __KSEQ_BASIC(SCOPE, type_t) \ SCOPE kseq_t *kseq_init(type_t fd) \ { \ kseq_t *s = (kseq_t*)calloc(1, sizeof(kseq_t)); \ s->f = ks_init(fd); \ return s; \ } \ SCOPE void kseq_destroy(kseq_t *ks) \ { \ if (!ks) return; \ free(ks->name.s); free(ks->comment.s); free(ks->seq.s); free(ks->qual.s); \ ks_destroy(ks->f); \ free(ks); \ } /* Return value: >=0 length of the sequence (normal) -1 end-of-file -2 truncated quality string */ #define __KSEQ_READ(SCOPE) \ SCOPE int kseq_read(kseq_t *seq) \ { \ int c; \ kstream_t *ks = seq->f; \ if (seq->last_char == 0) { /* then jump to the next header line */ \ while ((c = ks_getc(ks)) != -1 && c != '>' && c != '@'); \ if (c == -1) return -1; /* end of file */ \ seq->last_char = c; \ } /* else: the first header char has been read in the previous call */ \ seq->comment.l = seq->seq.l = seq->qual.l = 0; /* reset all members */ \ if (ks_getuntil(ks, 0, &seq->name, &c) < 0) return -1; /* normal exit: EOF */ \ if (c != '\n') ks_getuntil(ks, KS_SEP_LINE, &seq->comment, 0); /* read FASTA/Q comment */ \ if (seq->seq.s == 0) { /* we can do this in the loop below, but that is slower */ \ seq->seq.m = 256; \ seq->seq.s = (char*)malloc(seq->seq.m); \ } \ while ((c = ks_getc(ks)) != -1 && c != '>' && c != '+' && c != '@') { \ if (c == '\n') continue; /* skip empty lines */ \ seq->seq.s[seq->seq.l++] = c; /* this is safe: we always have enough space for 1 char */ \ ks_getuntil2(ks, KS_SEP_LINE, &seq->seq, 0, 1); /* read the rest of the line */ \ } \ if (c == '>' || c == '@') seq->last_char = c; /* the first header char has been read */ \ if (seq->seq.l + 1 >= seq->seq.m) { /* seq->seq.s[seq->seq.l] below may be out of boundary */ \ seq->seq.m = seq->seq.l + 2; \ kroundup32(seq->seq.m); /* rounded to the next closest 2^k */ \ seq->seq.s = (char*)realloc(seq->seq.s, seq->seq.m); \ } \ seq->seq.s[seq->seq.l] = 0; /* null terminated string */ \ if (c != '+') return seq->seq.l; /* FASTA */ \ if (seq->qual.m < seq->seq.m) { /* allocate memory for qual in case insufficient */ \ seq->qual.m = seq->seq.m; \ seq->qual.s = (char*)realloc(seq->qual.s, seq->qual.m); \ } \ while ((c = ks_getc(ks)) != -1 && c != '\n'); /* skip the rest of '+' line */ \ if (c == -1) return -2; /* error: no quality string */ \ while (ks_getuntil2(ks, KS_SEP_LINE, &seq->qual, 0, 1) >= 0 && seq->qual.l < seq->seq.l); \ seq->last_char = 0; /* we have not come to the next header line */ \ if (seq->seq.l != seq->qual.l) return -2; /* error: qual string is of a different length */ \ return seq->seq.l; \ } #define __KSEQ_TYPE(type_t) \ typedef struct { \ kstring_t name, comment, seq, qual; \ int last_char; \ kstream_t *f; \ } kseq_t; #define KSEQ_INIT2(SCOPE, type_t, __read) \ KSTREAM_INIT(type_t, __read, 16384) \ __KSEQ_TYPE(type_t) \ __KSEQ_BASIC(SCOPE, type_t) \ __KSEQ_READ(SCOPE) #define KSEQ_INIT(type_t, __read) KSEQ_INIT2(static, type_t, __read) #define KSEQ_DECLARE(type_t) \ __KS_TYPE(type_t) \ __KSEQ_TYPE(type_t) \ extern kseq_t *kseq_init(type_t fd); \ void kseq_destroy(kseq_t *ks); \ int kseq_read(kseq_t *seq); #endif deepTools-2.5.0/deeptoolsintervals/tree/kstring.h0000640000201600010240000001563712757050137021360 0ustar ryanbioinfo/* The MIT License Copyright (C) 2011 by Attractive Chaos Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #ifndef KSTRING_H #define KSTRING_H #include #include #include #include #include #ifndef kroundup32 #define kroundup32(x) (--(x), (x)|=(x)>>1, (x)|=(x)>>2, (x)|=(x)>>4, (x)|=(x)>>8, (x)|=(x)>>16, ++(x)) #endif #if defined __GNUC__ && (__GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ > 4)) #define KS_ATTR_PRINTF(fmt, arg) __attribute__((__format__ (__printf__, fmt, arg))) #else #define KS_ATTR_PRINTF(fmt, arg) #endif /* kstring_t is a simple non-opaque type whose fields are likely to be * used directly by user code (but see also ks_str() and ks_len() below). * A kstring_t object is initialised by either of * kstring_t str = { 0, 0, NULL }; * kstring_t str; ...; str.l = str.m = 0; str.s = NULL; * and either ownership of the underlying buffer should be given away before * the object disappears (see ks_release() below) or the kstring_t should be * destroyed with free(str.s); */ #ifndef KSTRING_T #define KSTRING_T kstring_t typedef struct __kstring_t { size_t l, m; char *s; } kstring_t; #endif typedef struct { uint64_t tab[4]; int sep, finished; const char *p; // end of the current token } ks_tokaux_t; #ifdef __cplusplus extern "C" { #endif int kvsprintf(kstring_t *s, const char *fmt, va_list ap) KS_ATTR_PRINTF(2,0); int ksprintf(kstring_t *s, const char *fmt, ...) KS_ATTR_PRINTF(2,3); int ksplit_core(char *s, int delimiter, int *_max, int **_offsets); char *kstrstr(const char *str, const char *pat, int **_prep); char *kstrnstr(const char *str, const char *pat, int n, int **_prep); void *kmemmem(const void *_str, int n, const void *_pat, int m, int **_prep); /* kstrtok() is similar to strtok_r() except that str is not * modified and both str and sep can be NULL. For efficiency, it is * actually recommended to set both to NULL in the subsequent calls * if sep is not changed. */ char *kstrtok(const char *str, const char *sep, ks_tokaux_t *aux); /* kgetline() uses the supplied fgets()-like function to read a "\n"- * or "\r\n"-terminated line from fp. The line read is appended to the * kstring without its terminator and 0 is returned; EOF is returned at * EOF or on error (determined by querying fp, as per fgets()). */ typedef char *kgets_func(char *, int, void *); int kgetline(kstring_t *s, kgets_func *fgets, void *fp); #ifdef __cplusplus } #endif static inline int ks_resize(kstring_t *s, size_t size) { if (s->m < size) { char *tmp; s->m = size; kroundup32(s->m); if ((tmp = (char*)realloc(s->s, s->m))) s->s = tmp; else return -1; } return 0; } static inline char *ks_str(kstring_t *s) { return s->s; } static inline size_t ks_len(kstring_t *s) { return s->l; } // Give ownership of the underlying buffer away to something else (making // that something else responsible for freeing it), leaving the kstring_t // empty and ready to be used again, or ready to go out of scope without // needing free(str.s) to prevent a memory leak. static inline char *ks_release(kstring_t *s) { char *ss = s->s; s->l = s->m = 0; s->s = NULL; return ss; } static inline int kputsn(const char *p, int l, kstring_t *s) { if (s->l + l + 1 >= s->m) { char *tmp; s->m = s->l + l + 2; kroundup32(s->m); if ((tmp = (char*)realloc(s->s, s->m))) s->s = tmp; else return EOF; } memcpy(s->s + s->l, p, l); s->l += l; s->s[s->l] = 0; return l; } static inline int kputs(const char *p, kstring_t *s) { return kputsn(p, strlen(p), s); } static inline int kputc(int c, kstring_t *s) { if (s->l + 1 >= s->m) { char *tmp; s->m = s->l + 2; kroundup32(s->m); if ((tmp = (char*)realloc(s->s, s->m))) s->s = tmp; else return EOF; } s->s[s->l++] = c; s->s[s->l] = 0; return c; } static inline int kputc_(int c, kstring_t *s) { if (s->l + 1 > s->m) { char *tmp; s->m = s->l + 1; kroundup32(s->m); if ((tmp = (char*)realloc(s->s, s->m))) s->s = tmp; else return EOF; } s->s[s->l++] = c; return 1; } static inline int kputsn_(const void *p, int l, kstring_t *s) { if (s->l + l > s->m) { char *tmp; s->m = s->l + l; kroundup32(s->m); if ((tmp = (char*)realloc(s->s, s->m))) s->s = tmp; else return EOF; } memcpy(s->s + s->l, p, l); s->l += l; return l; } static inline int kputw(int c, kstring_t *s) { char buf[16]; int i, l = 0; unsigned int x = c; if (c < 0) x = -x; do { buf[l++] = x%10 + '0'; x /= 10; } while (x > 0); if (c < 0) buf[l++] = '-'; if (s->l + l + 1 >= s->m) { char *tmp; s->m = s->l + l + 2; kroundup32(s->m); if ((tmp = (char*)realloc(s->s, s->m))) s->s = tmp; else return EOF; } for (i = l - 1; i >= 0; --i) s->s[s->l++] = buf[i]; s->s[s->l] = 0; return 0; } static inline int kputuw(unsigned c, kstring_t *s) { char buf[16]; int l, i; unsigned x; if (c == 0) return kputc('0', s); for (l = 0, x = c; x > 0; x /= 10) buf[l++] = x%10 + '0'; if (s->l + l + 1 >= s->m) { char *tmp; s->m = s->l + l + 2; kroundup32(s->m); if ((tmp = (char*)realloc(s->s, s->m))) s->s = tmp; else return EOF; } for (i = l - 1; i >= 0; --i) s->s[s->l++] = buf[i]; s->s[s->l] = 0; return 0; } static inline int kputl(long c, kstring_t *s) { char buf[32]; int i, l = 0; unsigned long x = c; if (c < 0) x = -x; do { buf[l++] = x%10 + '0'; x /= 10; } while (x > 0); if (c < 0) buf[l++] = '-'; if (s->l + l + 1 >= s->m) { char *tmp; s->m = s->l + l + 2; kroundup32(s->m); if ((tmp = (char*)realloc(s->s, s->m))) s->s = tmp; else return EOF; } for (i = l - 1; i >= 0; --i) s->s[s->l++] = buf[i]; s->s[s->l] = 0; return 0; } /* * Returns 's' split by delimiter, with *n being the number of components; * NULL on failue. */ static inline int *ksplit(kstring_t *s, int delimiter, int *n) { int max = 0, *offsets = 0; *n = ksplit_core(s->s, delimiter, &max, &offsets); return offsets; } #endif deepTools-2.5.0/deeptoolsintervals/tree/murmur3.c0000640000201600010240000001655412757050137021303 0ustar ryanbioinfo//----------------------------------------------------------------------------- // MurmurHash3 was written by Austin Appleby, and is placed in the public // domain. The author hereby disclaims copyright to this source code. // Note - The x86 and x64 versions do _not_ produce the same results, as the // algorithms are optimized for their respective platforms. You can still // compile and run any of them on any platform, but your performance with the // non-native version will be less than optimal. #include "murmur3.h" //----------------------------------------------------------------------------- // Platform-specific functions and macros #ifdef __GNUC__ #define FORCE_INLINE __attribute__((always_inline)) inline #else #define FORCE_INLINE inline #endif static FORCE_INLINE uint32_t rotl32 ( uint32_t x, int8_t r ) { return (x << r) | (x >> (32 - r)); } static FORCE_INLINE uint64_t rotl64 ( uint64_t x, int8_t r ) { return (x << r) | (x >> (64 - r)); } #define ROTL32(x,y) rotl32(x,y) #define ROTL64(x,y) rotl64(x,y) #define BIG_CONSTANT(x) (x##LLU) //----------------------------------------------------------------------------- // Block read - if your platform needs to do endian-swapping or can only // handle aligned reads, do the conversion here #define getblock(p, i) (p[i]) //----------------------------------------------------------------------------- // Finalization mix - force all bits of a hash block to avalanche static FORCE_INLINE uint32_t fmix32 ( uint32_t h ) { h ^= h >> 16; h *= 0x85ebca6b; h ^= h >> 13; h *= 0xc2b2ae35; h ^= h >> 16; return h; } //---------- static FORCE_INLINE uint64_t fmix64 ( uint64_t k ) { k ^= k >> 33; k *= BIG_CONSTANT(0xff51afd7ed558ccd); k ^= k >> 33; k *= BIG_CONSTANT(0xc4ceb9fe1a85ec53); k ^= k >> 33; return k; } //----------------------------------------------------------------------------- void MurmurHash3_x86_32 ( const void * key, int len, uint32_t seed, void * out ) { const uint8_t * data = (const uint8_t*)key; const int nblocks = len / 4; int i; uint32_t h1 = seed; uint32_t c1 = 0xcc9e2d51; uint32_t c2 = 0x1b873593; //---------- // body const uint32_t * blocks = (const uint32_t *)(data + nblocks*4); for(i = -nblocks; i; i++) { uint32_t k1 = getblock(blocks,i); k1 *= c1; k1 = ROTL32(k1,15); k1 *= c2; h1 ^= k1; h1 = ROTL32(h1,13); h1 = h1*5+0xe6546b64; } //---------- // tail const uint8_t * tail = (const uint8_t*)(data + nblocks*4); uint32_t k1 = 0; switch(len & 3) { case 3: k1 ^= tail[2] << 16; case 2: k1 ^= tail[1] << 8; case 1: k1 ^= tail[0]; k1 *= c1; k1 = ROTL32(k1,15); k1 *= c2; h1 ^= k1; }; //---------- // finalization h1 ^= len; h1 = fmix32(h1); *(uint32_t*)out = h1; } //----------------------------------------------------------------------------- void MurmurHash3_x86_128 ( const void * key, const int len, uint32_t seed, void * out ) { const uint8_t * data = (const uint8_t*)key; const int nblocks = len / 16; int i; uint32_t h1 = seed; uint32_t h2 = seed; uint32_t h3 = seed; uint32_t h4 = seed; uint32_t c1 = 0x239b961b; uint32_t c2 = 0xab0e9789; uint32_t c3 = 0x38b34ae5; uint32_t c4 = 0xa1e38b93; //---------- // body const uint32_t * blocks = (const uint32_t *)(data + nblocks*16); for(i = -nblocks; i; i++) { uint32_t k1 = getblock(blocks,i*4+0); uint32_t k2 = getblock(blocks,i*4+1); uint32_t k3 = getblock(blocks,i*4+2); uint32_t k4 = getblock(blocks,i*4+3); k1 *= c1; k1 = ROTL32(k1,15); k1 *= c2; h1 ^= k1; h1 = ROTL32(h1,19); h1 += h2; h1 = h1*5+0x561ccd1b; k2 *= c2; k2 = ROTL32(k2,16); k2 *= c3; h2 ^= k2; h2 = ROTL32(h2,17); h2 += h3; h2 = h2*5+0x0bcaa747; k3 *= c3; k3 = ROTL32(k3,17); k3 *= c4; h3 ^= k3; h3 = ROTL32(h3,15); h3 += h4; h3 = h3*5+0x96cd1c35; k4 *= c4; k4 = ROTL32(k4,18); k4 *= c1; h4 ^= k4; h4 = ROTL32(h4,13); h4 += h1; h4 = h4*5+0x32ac3b17; } //---------- // tail const uint8_t * tail = (const uint8_t*)(data + nblocks*16); uint32_t k1 = 0; uint32_t k2 = 0; uint32_t k3 = 0; uint32_t k4 = 0; switch(len & 15) { case 15: k4 ^= tail[14] << 16; case 14: k4 ^= tail[13] << 8; case 13: k4 ^= tail[12] << 0; k4 *= c4; k4 = ROTL32(k4,18); k4 *= c1; h4 ^= k4; case 12: k3 ^= tail[11] << 24; case 11: k3 ^= tail[10] << 16; case 10: k3 ^= tail[ 9] << 8; case 9: k3 ^= tail[ 8] << 0; k3 *= c3; k3 = ROTL32(k3,17); k3 *= c4; h3 ^= k3; case 8: k2 ^= tail[ 7] << 24; case 7: k2 ^= tail[ 6] << 16; case 6: k2 ^= tail[ 5] << 8; case 5: k2 ^= tail[ 4] << 0; k2 *= c2; k2 = ROTL32(k2,16); k2 *= c3; h2 ^= k2; case 4: k1 ^= tail[ 3] << 24; case 3: k1 ^= tail[ 2] << 16; case 2: k1 ^= tail[ 1] << 8; case 1: k1 ^= tail[ 0] << 0; k1 *= c1; k1 = ROTL32(k1,15); k1 *= c2; h1 ^= k1; }; //---------- // finalization h1 ^= len; h2 ^= len; h3 ^= len; h4 ^= len; h1 += h2; h1 += h3; h1 += h4; h2 += h1; h3 += h1; h4 += h1; h1 = fmix32(h1); h2 = fmix32(h2); h3 = fmix32(h3); h4 = fmix32(h4); h1 += h2; h1 += h3; h1 += h4; h2 += h1; h3 += h1; h4 += h1; ((uint32_t*)out)[0] = h1; ((uint32_t*)out)[1] = h2; ((uint32_t*)out)[2] = h3; ((uint32_t*)out)[3] = h4; } //----------------------------------------------------------------------------- void MurmurHash3_x64_128 ( const void * key, const int len, const uint32_t seed, void * out ) { const uint8_t * data = (const uint8_t*)key; const int nblocks = len / 16; int i; uint64_t h1 = seed; uint64_t h2 = seed; uint64_t c1 = BIG_CONSTANT(0x87c37b91114253d5); uint64_t c2 = BIG_CONSTANT(0x4cf5ad432745937f); //---------- // body const uint64_t * blocks = (const uint64_t *)(data); for(i = 0; i < nblocks; i++) { uint64_t k1 = getblock(blocks,i*2+0); uint64_t k2 = getblock(blocks,i*2+1); k1 *= c1; k1 = ROTL64(k1,31); k1 *= c2; h1 ^= k1; h1 = ROTL64(h1,27); h1 += h2; h1 = h1*5+0x52dce729; k2 *= c2; k2 = ROTL64(k2,33); k2 *= c1; h2 ^= k2; h2 = ROTL64(h2,31); h2 += h1; h2 = h2*5+0x38495ab5; } //---------- // tail const uint8_t * tail = (const uint8_t*)(data + nblocks*16); uint64_t k1 = 0; uint64_t k2 = 0; switch(len & 15) { case 15: k2 ^= (uint64_t)(tail[14]) << 48; case 14: k2 ^= (uint64_t)(tail[13]) << 40; case 13: k2 ^= (uint64_t)(tail[12]) << 32; case 12: k2 ^= (uint64_t)(tail[11]) << 24; case 11: k2 ^= (uint64_t)(tail[10]) << 16; case 10: k2 ^= (uint64_t)(tail[ 9]) << 8; case 9: k2 ^= (uint64_t)(tail[ 8]) << 0; k2 *= c2; k2 = ROTL64(k2,33); k2 *= c1; h2 ^= k2; case 8: k1 ^= (uint64_t)(tail[ 7]) << 56; case 7: k1 ^= (uint64_t)(tail[ 6]) << 48; case 6: k1 ^= (uint64_t)(tail[ 5]) << 40; case 5: k1 ^= (uint64_t)(tail[ 4]) << 32; case 4: k1 ^= (uint64_t)(tail[ 3]) << 24; case 3: k1 ^= (uint64_t)(tail[ 2]) << 16; case 2: k1 ^= (uint64_t)(tail[ 1]) << 8; case 1: k1 ^= (uint64_t)(tail[ 0]) << 0; k1 *= c1; k1 = ROTL64(k1,31); k1 *= c2; h1 ^= k1; }; //---------- // finalization h1 ^= len; h2 ^= len; h1 += h2; h2 += h1; h1 = fmix64(h1); h2 = fmix64(h2); h1 += h2; h2 += h1; ((uint64_t*)out)[0] = h1; ((uint64_t*)out)[1] = h2; } //----------------------------------------------------------------------------- deepTools-2.5.0/deeptoolsintervals/tree/murmur3.h0000640000201600010240000000143012757050137021273 0ustar ryanbioinfo//----------------------------------------------------------------------------- // MurmurHash3 was written by Austin Appleby, and is placed in the // public domain. The author hereby disclaims copyright to this source // code. #ifndef _MURMURHASH3_H_ #define _MURMURHASH3_H_ #include #ifdef __cplusplus extern "C" { #endif //----------------------------------------------------------------------------- void MurmurHash3_x86_32 (const void *key, int len, uint32_t seed, void *out); void MurmurHash3_x86_128(const void *key, int len, uint32_t seed, void *out); void MurmurHash3_x64_128(const void *key, int len, uint32_t seed, void *out); //----------------------------------------------------------------------------- #ifdef __cplusplus } #endif #endif // _MURMURHASH3_H_ deepTools-2.5.0/deeptoolsintervals/tree/tree.c0000640000201600010240000002477212757050137020631 0ustar ryanbioinfo#include #include #include #include "tree.h" #include #include static void pyGTFDealloc(pyGTFtree_t *self) { if(self->t) destroyGTFtree(self->t); PyObject_DEL(self); } #if PY_MAJOR_VERSION >= 3 //Return 1 iff obj is a ready unicode type int PyString_Check(PyObject *obj) { if(PyUnicode_Check(obj)) { return PyUnicode_READY(obj)+1; } return 0; } char *PyString_AsString(PyObject *obj) { return PyBytes_AsString(PyUnicode_AsASCIIString(obj)); } PyObject *PyString_FromString(char *s) { return PyUnicode_FromString(s); } #endif //Will return 1 for long or int types currently int isNumeric(PyObject *obj) { #if PY_MAJOR_VERSION < 3 if(PyInt_Check(obj)) return 1; #endif return PyLong_Check(obj); } //On error, throws a runtime error, so use PyErr_Occurred() after this uint32_t Numeric2Uint(PyObject *obj) { long l; #if PY_MAJOR_VERSION < 3 if(PyInt_Check(obj)) { return (uint32_t) PyInt_AsLong(obj); } #endif l = PyLong_AsLong(obj); //Check bounds if(l > 0xFFFFFFFF) { PyErr_SetString(PyExc_RuntimeError, "Length out of bounds for a bigWig file!"); return (uint32_t) -1; } return (uint32_t) l; } static PyObject *pyGTFinit(PyObject *self, PyObject *args) { GTFtree *t = NULL; pyGTFtree_t *pt; t = initGTFtree(); if(!t) return NULL; pt = PyObject_New(pyGTFtree_t, &pyGTFtree); if(!pt) goto error; pt->t = t; return (PyObject*) pt; error: if(t) destroyGTFtree(t); PyErr_SetString(PyExc_RuntimeError, "Received an error during tree initialization!"); return NULL; } static PyObject *pyAddEntry(pyGTFtree_t *self, PyObject *args) { GTFtree *t = self->t; char *chrom = NULL, *name = NULL, *sscore = NULL; uint32_t start, end, labelIdx; double score; uint8_t strand; unsigned long lstrand, lstart, lend, llabelIdx; if(!(PyArg_ParseTuple(args, "skkskks", &chrom, &lstart, &lend, &name, &lstrand, &llabelIdx, &sscore))) { PyErr_SetString(PyExc_RuntimeError, "pyAddEntry received an invalid or missing argument!"); return NULL; } //Convert all of the longs if(lstart >= (uint32_t) -1 || lend >= (uint32_t) -1 || lend <= lstart) { PyErr_SetString(PyExc_RuntimeError, "pyAddEntry received invalid bounds!"); return NULL; } start = (uint32_t) lstart; end = (uint32_t) lend; if(lstrand != 0 && lstrand != 1 && lstrand != 3) { PyErr_SetString(PyExc_RuntimeError, "pyAddEntry received an invalid strand!"); return NULL; } strand = (uint8_t) lstrand; if(llabelIdx >= (uint32_t) -1) { PyErr_SetString(PyExc_RuntimeError, "pyAddEntry received an invalid label idx (too large)!"); return NULL; } labelIdx = (uint32_t) llabelIdx; //Handle the score if(strcmp(sscore, ".") == 0) { score = DBL_MAX; } else { score = strtod(sscore, NULL); } //Actually add the entry if(addGTFentry(t, chrom, start, end, strand, name, labelIdx, score)) { PyErr_SetString(PyExc_RuntimeError, "pyAddEntry received an error while inserting an entry!"); return NULL; } Py_INCREF(Py_None); return Py_None; } static PyObject *pyAddEnrichmentEntry(pyGTFtree_t *self, PyObject *args) { GTFtree *t = self->t; char *chrom = NULL, *sscore = NULL, *feature = NULL; uint32_t start, end; double score; uint8_t strand; unsigned long lstrand, lstart, lend; if(!(PyArg_ParseTuple(args, "skkkss", &chrom, &lstart, &lend, &lstrand, &sscore, &feature))) { PyErr_SetString(PyExc_RuntimeError, "pyAddEnrichmentEntry received an invalid or missing argument!"); return NULL; } //Convert all of the longs if(lstart >= (uint32_t) -1 || lend >= (uint32_t) -1 || lend <= lstart) { PyErr_SetString(PyExc_RuntimeError, "pyAddEnrichmentEntry received invalid bounds!"); return NULL; } start = (uint32_t) lstart; end = (uint32_t) lend; if(lstrand != 0 && lstrand != 1 && lstrand != 3) { PyErr_SetString(PyExc_RuntimeError, "pyAddEnrichmentEntry received an invalid strand!"); return NULL; } strand = (uint8_t) lstrand; //Handle the score if(strcmp(sscore, ".") == 0) { score = DBL_MAX; } else { score = strtod(sscore, NULL); } //Actually add the entry if(addEnrichmententry(t, chrom, start, end, strand, score, feature)) { PyErr_SetString(PyExc_RuntimeError, "pyAddEnrichmentEntry received an error while inserting an entry!"); return NULL; } Py_INCREF(Py_None); return Py_None; } static PyObject *pyVine2Tree(pyGTFtree_t *self, PyObject *args) { GTFtree *t = self->t; sortGTF(t); Py_INCREF(Py_None); return Py_None; } static PyObject *pyPrintGTFtree(pyGTFtree_t *self, PyObject *args) { GTFtree *t = self->t; printGTFtree(t); Py_INCREF(Py_None); return Py_None; } static PyObject *pyCountEntries(pyGTFtree_t *self, PyObject *args) { GTFtree *t = self->t; uint32_t nEntries = 0; unsigned long lnEntries = 0; int32_t i; PyObject *out = NULL; for(i=0; in_targets; i++) { nEntries += t->chroms[i]->n_entries; } lnEntries = (unsigned long) nEntries; out = PyLong_FromUnsignedLong(lnEntries); return out; } static PyObject *pyIsTree(pyGTFtree_t *self, PyObject *args) { GTFtree *t = self->t; if(t->balanced) Py_RETURN_TRUE; Py_RETURN_FALSE; } static PyObject *pyFindOverlaps(pyGTFtree_t *self, PyObject *args) { GTFtree *t = self->t; char *chrom = NULL, *name = NULL, *transcript_id = NULL, strandChar; int32_t i; uint32_t start, end; int strand = 3, strandType = 0, matchType = 0; unsigned long lstrand, lstart, lend, lmatchType, lstrandType, llabelIdx; overlapSet *os = NULL; PyObject *olist = NULL, *otuple = NULL, *includeStrand = Py_False, *oscore = NULL; if(!(PyArg_ParseTuple(args, "skkkkksO", &chrom, &lstart, &lend, &lstrand, &lmatchType, &lstrandType, &transcript_id, &includeStrand))) { PyErr_SetString(PyExc_RuntimeError, "pyFindOverlaps received an invalid or missing argument!"); return NULL; } //I'm assuming that this is never called outside of the module strandType = (int) lstrandType; strand = (int) lstrand; matchType = (int) matchType; start = (uint32_t) lstart; end = (uint32_t) lend; os = findOverlaps(NULL, t, chrom, start, end, strand, matchType, strandType, 0, NULL); // Did we receive an error? if(!os) { PyErr_SetString(PyExc_RuntimeError, "findOverlaps returned NULL!"); return NULL; } // Convert the overlapSet to a list of tuples olist = PyList_New(os->l); if(!olist) goto error; for(i=0; il; i++) { // Make the tuple if(includeStrand == Py_True) { otuple = PyTuple_New(6); } else { otuple = PyTuple_New(5); } if(!otuple) goto error; lstart = (unsigned long) os->overlaps[i]->start; lend = (unsigned long) os->overlaps[i]->end; name = getAttribute(t, os->overlaps[i], transcript_id); llabelIdx = (unsigned long) os->overlaps[i]->labelIdx; strandChar = '.'; if(os->overlaps[i]->strand == 0) { strandChar = '+'; } else if(os->overlaps[i]->strand == 1) { strandChar = '-'; } if (os->overlaps[i]->score == DBL_MAX) { oscore = Py_BuildValue("s", "."); } else { oscore = Py_BuildValue("d", os->overlaps[i]->score); } if(!oscore) goto error; if(includeStrand == Py_True) { otuple = Py_BuildValue("(kkskcO)", lstart, lend, name, llabelIdx, strandChar, oscore); } else { otuple = Py_BuildValue("(kkskO)", lstart, lend, name, llabelIdx, oscore); } if(!otuple) goto error; // Add the tuple if(PyList_SetItem(olist, i, otuple)) goto error; otuple = NULL; } os_destroy(os); return olist; error: if(otuple) Py_DECREF(otuple); if(olist) Py_DECREF(olist); PyErr_SetString(PyExc_RuntimeError, "findOverlaps received an error!"); return NULL; } static PyObject *pyFindOverlappingFeatures(pyGTFtree_t *self, PyObject *args) { GTFtree *t = self->t; char *chrom = NULL; int32_t i; uint32_t start, end; int strand = 3, strandType = 0, matchType = 0; unsigned long lstrand, lstart, lend, lmatchType, lstrandType; overlapSet *os = NULL; PyObject *olist = NULL, *ostring = NULL; if(!(PyArg_ParseTuple(args, "skkkkk", &chrom, &lstart, &lend, &lstrand, &lmatchType, &lstrandType))) { PyErr_SetString(PyExc_RuntimeError, "pyFindOverlaps received an invalid or missing argument!"); return NULL; } //I'm assuming that this is never called outside of the module strandType = (int) lstrandType; strand = (int) lstrand; matchType = (int) matchType; start = (uint32_t) lstart; end = (uint32_t) lend; os = findOverlaps(NULL, t, chrom, start, end, strand, matchType, strandType, 0, NULL); // Did we receive an error? if(!os) { PyErr_SetString(PyExc_RuntimeError, "findOverlaps returned NULL!"); return NULL; } if(!os->l) { os_destroy(os); Py_INCREF(Py_None); return Py_None; } // Convert the overlapSet to a list of tuples olist = PyList_New(os->l); if(!olist) goto error; for(i=0; il; i++) { //Make the python string ostring = PyString_FromString(val2strHT(t->htFeatures, os->overlaps[i]->feature)); if(!ostring) goto error; // Add the item if(PyList_SetItem(olist, i, ostring)) goto error; ostring = NULL; } os_destroy(os); return olist; error: if(ostring) Py_DECREF(ostring); if(olist) Py_DECREF(olist); PyErr_SetString(PyExc_RuntimeError, "findOverlappingFeatures received an error!"); return NULL; } #if PY_MAJOR_VERSION >= 3 PyMODINIT_FUNC PyInit_tree(void) { PyObject *res; errno = 0; if(PyType_Ready(&pyGTFtree) < 0) return NULL; res = PyModule_Create(&treemodule); if(!res) return NULL; Py_INCREF(&pyGTFtree); PyModule_AddObject(res, "pyGTFtree", (PyObject *) &pyGTFtree); return res; } #else //Python2 initialization PyMODINIT_FUNC inittree(void) { errno = 0; //Sometimes libpython2.7.so is missing some links... if(PyType_Ready(&pyGTFtree) < 0) return; Py_InitModule3("tree", treeMethods, "A module for handling GTF files for deepTools"); } #endif deepTools-2.5.0/deeptoolsintervals/tree/tree.h0000640000201600010240000001046512757050137020630 0ustar ryanbioinfo#include #include #include "gtf.h" typedef struct { PyObject_HEAD GTFtree *t; } pyGTFtree_t; /* Remove all asserts and ensure that the new return values are honoured. Profile the code with a test to eliminate unneeded cruft. */ static PyObject *pyGTFinit(PyObject *self, PyObject *args); static PyObject *pyAddEntry(pyGTFtree_t *self, PyObject *args); static PyObject *pyAddEnrichmentEntry(pyGTFtree_t *self, PyObject *args); static PyObject *pyVine2Tree(pyGTFtree_t *self, PyObject *args); static PyObject *pyPrintGTFtree(pyGTFtree_t *self, PyObject *args); static PyObject *pyCountEntries(pyGTFtree_t *self, PyObject *args); static PyObject *pyFindOverlaps(pyGTFtree_t *self, PyObject *args); static PyObject *pyFindOverlappingFeatures(pyGTFtree_t *self, PyObject *args); static PyObject *pyIsTree(pyGTFtree_t *self, PyObject *args); static void pyGTFDealloc(pyGTFtree_t *self); static PyMethodDef treeMethods[] = { {"initTree", (PyCFunction) pyGTFinit, METH_VARARGS, "Initialize the tree\n"}, {"addEntry", (PyCFunction) pyAddEntry, METH_VARARGS, "Some documentation for pyAddEntry\n"}, {"addEnrichmentEntry", (PyCFunction) pyAddEnrichmentEntry, METH_VARARGS, "Some documentation for pyAddEnrichmentEntry\n"}, {"finish", (PyCFunction) pyVine2Tree, METH_VARARGS, "This must be called after ALL entries from ALL files have been added.\n"}, {"printGTFtree", (PyCFunction) pyPrintGTFtree, METH_VARARGS, "Prints a text representation in dot format.\n"}, {"countEntries", (PyCFunction) pyCountEntries, METH_VARARGS, "Count the number of entries in a GTFtree\n"}, {"isTree", (PyCFunction) pyIsTree, METH_VARARGS, "Return True if the object is a tree\n"}, {"findOverlaps", (PyCFunction) pyFindOverlaps, METH_VARARGS, "Find overlapping intervals\n"}, {"findOverlappingFeatures", (PyCFunction) pyFindOverlappingFeatures, METH_VARARGS, "Find overlapping intervals, returning a list of features\n"}, {NULL, NULL, 0, NULL} }; #if PY_MAJOR_VERSION >= 3 struct treemodule_state { PyObject *error; }; #define GETSTATE(m) ((struct treemodule_state*)PyModule_GetState(m)) static PyModuleDef treemodule = { PyModuleDef_HEAD_INIT, "tree", "A python module creating/accessing GTF-based interval trees with associated meta-data", -1, treeMethods, NULL, NULL, NULL, NULL }; #endif //Should set tp_dealloc, tp_print, tp_repr, tp_str, tp_members static PyTypeObject pyGTFtree = { #if PY_MAJOR_VERSION >= 3 PyVarObject_HEAD_INIT(NULL, 0) #else PyObject_HEAD_INIT(NULL) 0, /*ob_size*/ #endif "pyGTFtree", /*tp_name*/ sizeof(pyGTFtree_t), /*tp_basicsize*/ 0, /*tp_itemsize*/ (destructor)pyGTFDealloc, /*tp_dealloc*/ 0, /*tp_print*/ 0, /*tp_getattr*/ 0, /*tp_setattr*/ 0, /*tp_compare*/ 0, /*tp_repr*/ 0, /*tp_as_number*/ 0, /*tp_as_sequence*/ 0, /*tp_as_mapping*/ 0, /*tp_hash*/ 0, /*tp_call*/ 0, /*tp_str*/ PyObject_GenericGetAttr, /*tp_getattro*/ PyObject_GenericSetAttr, /*tp_setattro*/ 0, /*tp_as_buffer*/ #if PY_MAJOR_VERSION >= 3 Py_TPFLAGS_DEFAULT, /*tp_flags*/ #else Py_TPFLAGS_HAVE_CLASS, /*tp_flags*/ #endif "GTF tree", /*tp_doc*/ 0, /*tp_traverse*/ 0, /*tp_clear*/ 0, /*tp_richcompare*/ 0, /*tp_weaklistoffset*/ 0, /*tp_iter*/ 0, /*tp_iternext*/ treeMethods, /*tp_methods*/ 0, /*tp_members*/ 0, /*tp_getset*/ 0, /*tp_base*/ 0, /*tp_dict*/ 0, /*tp_descr_get*/ 0, /*tp_descr_set*/ 0, /*tp_dictoffset*/ 0, /*tp_init*/ 0, /*tp_alloc*/ 0, /*tp_new*/ 0,0,0,0,0,0 }; deepTools-2.5.0/deeptoolsintervals/__init__.py0000640000201600010240000000013612757050137020664 0ustar ryanbioinfofrom deeptoolsintervals.parse import GTF from deeptoolsintervals.enrichment import Enrichment deepTools-2.5.0/deeptoolsintervals/enrichment.py0000640000201600010240000002306312757050137021265 0ustar ryanbioinfo#!/usr/bin/env python from deeptoolsintervals import tree from deeptoolsintervals.parse import GTF, openPossiblyCompressed import sys from os.path import basename import csv class Enrichment(GTF): """ This is like the GTF object, but has no groups or exons (but a "features" list). BED files are given a 'peaks' feature and GTF files use column 3. """ def parseBEDcore(self, line, ncols, feature): strand = 3 cols = line.split("\t") if int(cols[1]) < 0: cols[1] = 0 if int(cols[1]) >= int(cols[2]): sys.stderr.write("Warning: {0}:{1}-{2} is an invalid BED interval! Ignoring it.\n".format(cols[0], cols[1], cols[2])) return # BED6/BED12: set name and strand score = '.' if ncols > 3: if cols[5] == '+': strand = 0 elif cols[5] == '-': strand = 1 score = cols[4] if ncols != 12 or self.keepExons is False: self.tree.addEnrichmentEntry(self.mungeChromosome(cols[0]), int(cols[1]), int(cols[2]), strand, score, feature) else: starts = cols[10].strip(",").split(",") widths = cols[11].strip(",").split(",") starts = [int(x) + int(cols[1]) for x in starts] ends = [x + int(y) for x, y in zip(starts, widths)] for x, y in zip(starts, ends): self.tree.addEnrichmentEntry(self.mungeChromosome(cols[0]), x, y, strand, score, feature) def parseBED(self, fp, line, ncols=3, feature='peaks', labelColumn=None): """ parse a BED file. The default feature label is 'peaks' fp: A python file pointer line: The first line ncols: The number of columns to care about feature: The feature label labelColumn: If this isn't None, it overrides the 'feature' option >>> from deeptoolsintervals import enrichment >>> from os.path import dirname >>> gtf = enrichment.Enrichment("{0}/test/GRCh38.84.bed".format(dirname(enrichment.__file__)), keepExons=True) >>> o = gtf.findOverlaps("1", [(1, 3000000)]) >>> assert(o == frozenset(['GRCh38.84.bed'])) >>> o = gtf.findOverlaps("chr1", [(1, 3000000)]) >>> assert(o == frozenset(['GRCh38.84.bed'])) """ # Handle the first line if labelColumn is not None: cols = line.split("\t") feature = cols.pop(labelColumn) line = "\t".join(cols) self.parseBEDcore(line, ncols, feature) if feature not in self.features: self.features.append(feature) # iterate over the remaining lines for line in fp: if not isinstance(line, str): line = line.decode('ascii') line = line.strip() if len(line) == 0: # Apparently this happens, some people seem to like trying to break things continue if line.startswith("#"): continue else: if labelColumn is not None: cols = line.split("\t") feature = cols.pop(labelColumn) line = "\t".join(cols) self.parseBEDcore(line, ncols, feature) if feature not in self.features: self.features.append(feature) def parseGTF(self, fp, line): """ >>> from deeptoolsintervals import enrichment >>> from os.path import dirname >>> gtf = enrichment.Enrichment("{0}/test/GRCh38.84.gtf.gz".format(dirname(enrichment.__file__)), keepExons=True) >>> o = gtf.findOverlaps("1", [(0, 2000000)]) >>> assert(o == frozenset(['start_codon', 'exon', 'stop_codon', 'CDS', 'gene', 'transcript', 'group 1', 'group 2'])) """ # Handle the first line cols = line.split("\t") strand = 3 if cols[6] == '+': strand = 0 elif cols[6] == '-': strand = 1 feature = cols[2] if "deepTools_group" in cols[8]: s = next(csv.reader([cols[8]], delimiter=' ')) if s[-1] != "deepTools_group": feature = s[s.index("deepTools_group") + 1].rstrip(";") self.tree.addEnrichmentEntry(self.mungeChromosome(cols[0]), int(cols[3]) - 1, int(cols[4]), strand, cols[5], feature) if feature not in self.features: self.features.append(feature) # Handle the remaining lines for line in fp: if not isinstance(line, str): line = line.decode('ascii') if not line.startswith('#'): cols = line.split("\t") if len(cols) == 0: continue strand = 3 if cols[6] == '+': strand = 0 elif cols[6] == '-': strand = 1 feature = cols[2] if "deepTools_group" in cols[8]: s = next(csv.reader([cols[8]], delimiter=" ")) if s[-1] != "deepTools_group": feature = s[s.index("deepTools_group") + 1].rstrip(";") self.tree.addEnrichmentEntry(self.mungeChromosome(cols[0]), int(cols[3]) - 1, int(cols[4]), strand, cols[5], feature) if feature not in self.features: self.features.append(feature) def __init__(self, fnames, keepExons=False, labels=None, verbose=False): """ Driver function to actually parse files. The steps are as follows: 1) skip to the first non-comment line 2) Infer the type from that 3) Call a type-specific processing function accordingly * These call the underlying C code for storage * These handle chromsome name conversions (python-level) Required inputs are as follows: fnames: A list of (possibly compressed with gzip or bzip2) GTF or BED files. Optional input is: keepExons: For BED12 files, exons are ignored by default. labels: Override the feature labels supplied in the file(s). Note that this might instead be replaced later in the .features attribute. verbose: Whether to print warnings (default: False) """ self.fname = [] self.filename = "" self.chroms = [] self.features = [] self.tree = tree.initTree() self.keepExons = keepExons self.verbose = verbose if not isinstance(fnames, list): fnames = [fnames] # Load the files for labelIdx, fname in enumerate(fnames): self.filename = fname fp = openPossiblyCompressed(fname) line, labelColumn = self.firstNonComment(fp) if line is None: # This will only ever happen if a file is empty or just has a header/comment continue line = line.strip() ftype = self.inferType(fp, line, labelColumn) if ftype != 'GTF' and labels is not None: assert(len(labels) > labelIdx) bname = labels[labelIdx] else: bname = basename(fname) if ftype == 'GTF': self.parseGTF(fp, line) elif ftype == 'BED3': self.parseBED(fp, line, 3, feature=bname, labelColumn=labelColumn) elif ftype == 'BED6': self.parseBED(fp, line, 6, feature=bname, labelColumn=labelColumn) else: self.parseBED(fp, line, 12, feature=bname, labelColumn=labelColumn) fp.close() # Sanity check if self.tree.countEntries() == 0: raise RuntimeError("None of the input BED/GTF files had valid regions") if len(self.features) == 0: raise RuntimeError("There were no valid feature labels!") # vine -> tree self.tree.finish() # findOverlaps() def findOverlaps(self, chrom, blocks, strand=".", matchType=0, strandType=0): """ Given a chromosome and start/end coordinates with an optional strand, return a frozenset of the overlap features. If there are no overlaps, return None. This function allows stranded searching, though the default is to ignore strand! The non-obvious options are defined in gtf.h: matchType: 0, GTF_MATCH_ANY 1, GTF_MATCH_EXACT 2, GTF_MATCH_CONTAIN 3, GTF_MATCH_WITHIN 4, GTF_MATCH_START 5, GTF_MATCH_END strandType: 0, GTF_IGNORE_STRAND 1, GTF_SAME_STRAND 2, GTF_OPPOSITE_STRAND 3, GTF_EXACT_SAME_STRAND """ chrom = self.mungeChromosome(chrom, append=False) if not chrom: return None # Ensure that this is a tree and has entries if self.tree.countEntries() == 0: return None if not self.tree.isTree(): raise RuntimeError('The GTFtree is actually a vine! There must have been an error during creation (this shouldn\'t happen)...') # Convert the strand to a number if strand == '+': strand = 1 elif strand == '-': strand = 2 else: strand = 0 oset = frozenset() for block in blocks: overlaps = self.tree.findOverlappingFeatures(chrom, block[0], block[1], strand, matchType, strandType) if overlaps is not None: oset = oset.union(frozenset(overlaps)) return oset deepTools-2.5.0/deeptoolsintervals/parse.py0000640000201600010240000007270713067414642020254 0ustar ryanbioinfo#!/usr/bin/env python from deeptoolsintervals import tree import sys import gzip try: import bz2 supportsBZ2 = True except: supportsBZ2 = False import os.path import csv def getNext(fp): """ Sometimes we need to decode, sometimes not """ line = fp.readline() if isinstance(line, str): return line return line.decode('ascii') def seemsLikeGTF(cols): """ Does a line look like it could be from a GTF file? Column contents must be: 3: int 4: int 5: '.' or float 6: '+', '-', or '.' 7: 0, 1 or 2 8: matches the attribute regular expression """ try: int(cols[3]) int(cols[4]) if cols[5] != '.': float(cols[5]) cols[6] in ['+', '-', '.'] if cols[7] != '.': int(cols[7]) in [0, 1, 2] s = next(csv.reader([cols[8]], delimiter=' ')) assert("gene_id" in s) assert(s[-1] != "gene_id") return True except: return False def findRandomLabel(labels, name): """ Because some people are too clever by half, ensure that group labels are unique... """ if name not in labels: return name # This is what the heatmapper.py did to ensure unique names i = 0 while True: i += 1 nameTry = name + "_r" + str(i) if nameTry not in labels: return nameTry def parseExonBounds(start, end, n, sizes, offsets): """ Parse the last 2 columns of a BED12 file and return a list of tuples with (exon start, exon end) entries. If the line is malformed, issue a warning and return (start, end) """ offsets = offsets.strip(",").split(",") sizes = sizes.strip(",").split(",") offsets = offsets[0:n] sizes = sizes[0:n] try: starts = [start + int(x) for x in offsets] ends = [start + int(x) + int(y) for x, y in zip(offsets, sizes)] except: sys.stderr.write("Warning: Received an invalid exon offset ({0}) or size ({1}), using the entry bounds instead ({2}-{3})\n".format(offsets, sizes, start, end)) return [(start, end)] if len(offsets) < n or len(sizes) < n: sys.stderr.write("Warning: There were too few exon start/end offsets ({0}) or sizes ({1}), using the entry bounds instead ({2}-{3})\n".format(offsets, sizes, start, end)) return [(start, end)] return [(x, y) for x, y in zip(starts, ends)] def openPossiblyCompressed(fname): """ A wrapper to open gzip/bzip/uncompressed files """ with open(fname, "rb") as f: first3 = bytes(f.read(3)) if first3 == b"\x1f\x8b\x08": return gzip.open(fname, "rb") elif first3 == b"\x42\x5a\x68" and supportsBZ2: return bz2.BZ2File(fname, "rb") else: return open(fname) def getLabel(line): """ Split by tabs and return the index of "deepTools_group" (or None) """ cols = line.strip().split("\t") if "deepTools_group" in cols: return cols.index("deepTools_group") return None class GTF(object): """ A class to hold an interval tree and its associated functions >>> from deeptoolsintervals import parse >>> from os.path import dirname >>> gtf = parse.GTF("{0}/test/GRCh38.84.gtf.gz".format(dirname(parse.__file__)), keepExons=True) >>> gtf.findOverlaps("1", 1, 20000) [(11868, 14409, 'ENST00000456328', 'group 1', [(11868, 12227), (12612, 12721), (13220, 14409)], '.'), (12009, 13670, 'ENST00000450305', 'group 1', [(12009, 12057), (12178, 12227), (12612, 12697), (12974, 13052), (13220, 13374), (13452, 13670)], '.'), (14403, 29570, 'ENST00000488147', 'group 1', [(14403, 14501), (15004, 15038), (15795, 15947), (16606, 16765), (16857, 17055), (17232, 17368), (17605, 17742), (17914, 18061), (18267, 18366), (24737, 24891), (29533, 29570)], '.'), (17368, 17436, 'ENST00000619216', 'group 2', [(17368, 17436)], '.')] >>> gtf = parse.GTF("{0}/test/GRCh38.84.gtf.gz".format(dirname(parse.__file__))) >>> gtf.findOverlaps("1", 1, 20000) [(11868, 14409, 'ENST00000456328', 'group 1', [(11868, 14409)], '.'), (12009, 13670, 'ENST00000450305', 'group 1', [(12009, 13670)], '.'), (14403, 29570, 'ENST00000488147', 'group 1', [(14403, 29570)], '.'), (17368, 17436, 'ENST00000619216', 'group 2', [(17368, 17436)], '.')] >>> gtf.findOverlaps("1", 12000, 20000, trimOverlap=True) [(12009, 13670, 'ENST00000450305', 'group 1', [(12009, 13670)], '.'), (14403, 29570, 'ENST00000488147', 'group 1', [(14403, 29570)], '.'), (17368, 17436, 'ENST00000619216', 'group 2', [(17368, 17436)], '.')] >>> gtf.findOverlaps("1", 1, 20000, numericGroups=True, includeStrand=True) [(11868, 14409, 'ENST00000456328', 0, [(11868, 14409)], '+', '.'), (12009, 13670, 'ENST00000450305', 0, [(12009, 13670)], '+', '.'), (14403, 29570, 'ENST00000488147', 0, [(14403, 29570)], '-', '.'), (17368, 17436, 'ENST00000619216', 1, [(17368, 17436)], '-', '.')] """ def firstNonComment(self, fp): """ Skip lines at the beginning of a file starting with #, browser, or track. Returns a tuple of the first non-comment line and the column holding the group label (if it exists) """ line = getNext(fp) labelColumn = None try: while line.startswith("#") or line.startswith('track') or line.startswith('browser'): if labelColumn is None: labelColumn = getLabel(line) line = getNext(fp) except: sys.stderr.write("Warning, {0} was empty\n".format(self.filename)) return None return line, labelColumn def inferType(self, fp, line, labelColumn=None): """ Attempt to infer a file type from a single line. This is largely based on the number of columns plus looking for "gene_id". """ subtract = 0 if labelColumn is not None: subtract = 1 cols = line.split("\t") if len(cols) - subtract < 3: raise RuntimeError('{0} does not seem to be a recognized file type!'.format(self.filename)) elif len(cols) - subtract == 3: return 'BED3' elif len(cols) - subtract < 6: if self.verbose: sys.stderr.write("Warning, {0} has an abnormal number of fields. Assuming BED3 format.\n".format(self.filename)) return 'BED3' elif len(cols) - subtract == 6: return 'BED6' elif len(cols) and seemsLikeGTF(cols): return 'GTF' elif len(cols) - subtract == 12: return 'BED12' elif len(cols) - subtract < 12: if self.verbose: sys.stderr.write("Warning, {0} has an abnormal format. Assuming BED6 format.\n".format(self.filename)) return 'BED6' else: if self.verbose: sys.stderr.write("Warning, {0} has an abnormal format. Assuming BED12 format.\n".format(self.filename)) return 'BED12' def mungeChromosome(self, chrom, append=True): """ Return the chromosome name, possibly munged to match one already found in the chromosome dictionary """ if chrom in self.chroms: return chrom # chrM <-> MT and chr1 <-> 1 conversions if chrom == "MT" and "chrM" in self.chroms: chrom = "chrM" elif chrom == "chrM" and "MT" in self.chroms: chrom = "MT" elif chrom.startswith("chr") and len(chrom) > 3 and chrom[3:] in self.chroms: chrom = chrom[3:] elif "chr" + chrom in self.chroms: chrom = "chr" + chrom if append: self.chroms.append(chrom) return chrom def parseBEDcore(self, line, ncols): """ Returns True if the entry was added, otherwise False >>> from deeptoolsintervals import parse >>> from os.path import dirname >>> gtf = parse.GTF("{0}/test/GRCh38.84.bed12.bz2".format(dirname(parse.__file__)), keepExons=True, labels=["foo"]) >>> gtf.findOverlaps("1", 1, 20000) [(11868, 14409, 'ENST00000456328.2', 'foo', [(11868, 12227), (12612, 12721), (13220, 14409)], 0.0), (12009, 13670, 'ENST00000450305.2', 'foo', [(12009, 12057), (12178, 12227), (12612, 12697), (12974, 13052), (13220, 13374), (13452, 13670)], 0.0), (14403, 29570, 'ENST00000488147.1', 'foo', [(14403, 14501), (15004, 15038), (15795, 15947), (16606, 16765), (16857, 17055), (17232, 17368), (17605, 17742), (17914, 18061), (18267, 18366), (24737, 24891), (29533, 29570)], 0.0), (17368, 17436, 'ENST00000619216.1', 'foo', [(17368, 17436)], 0.0)] """ strand = 3 cols = line.split("\t") name = "{0}:{1}-{2}".format(cols[0], cols[1], cols[2]) if int(cols[1]) < 0: cols[1] = 0 if int(cols[1]) >= int(cols[2]): sys.stderr.write("Warning: {0}:{1}-{2} is an invalid BED interval! Ignoring it.\n".format(cols[0], cols[1], cols[2])) return # BED6/BED12: set name and strand score = '.' if ncols > 3: name = cols[3] if cols[5] == '+': strand = 0 elif cols[5] == '-': strand = 1 score = cols[4] # Ensure that the name is unique name = findRandomLabel(self.exons[self.labelIdx], name) self.tree.addEntry(self.mungeChromosome(cols[0]), int(cols[1]), int(cols[2]), name, strand, self.labelIdx, score) if ncols != 12 or self.keepExons is False: self.exons[self.labelIdx][name] = [(int(cols[1]), int(cols[2]))] else: assert(len(cols) == 12) self.exons[self.labelIdx][name] = parseExonBounds(int(cols[1]), int(cols[2]), int(cols[9]), cols[10], cols[11]) def parseBED(self, fp, line, ncols=3, labelColumn=None): """ parse a BED file. The default group label is the file name. fp: A python file pointer line: The first line ncols: The number of columns to care about >>> from deeptoolsintervals import parse >>> from os.path import dirname, basename >>> gtf = parse.GTF("{0}/test/GRCh38.84.bed6".format(dirname(parse.__file__)), keepExons=True) >>> gtf.findOverlaps("1", 1, 20000) [(11868, 14409, 'ENST00000456328.2', 'group 1', [(11868, 14409)], 0.0), (12009, 13670, 'ENST00000450305.2', 'group 1', [(12009, 13670)], 0.0), (14403, 29570, 'ENST00000488147.1', 'group 1', [(14403, 29570)], 0.0), (17368, 17436, 'ENST00000619216.1', 'group 1', [(17368, 17436)], 0.0)] >>> gtf = parse.GTF("{0}/test/GRCh38.84.bed".format(dirname(parse.__file__)), keepExons=True, labels=["foo", "bar", "quux", "sniggly"]) >>> gtf.findOverlaps("1", 1, 20000) [(11868, 14409, '1:11868-14409', 'foo', [(11868, 14409)], '.'), (12009, 13670, '1:12009-13670', 'foo', [(12009, 13670)], '.'), (14403, 29570, '1:14403-29570', 'foo', [(14403, 29570)], '.'), (17368, 17436, '1:17368-17436', 'foo', [(17368, 17436)], '.')] Test having a header in one file, but not another: >>> gtf = parse.GTF(["{0}/test/GRCh38.84.labels.bed".format(dirname(parse.__file__)), "{0}/test/GRCh38.84.bed2".format(dirname(parse.__file__))]) >>> overlaps = gtf.findOverlaps("1", 1, 30000000) >>> labels = dict() >>> for o in overlaps: ... if basename(o[3]) not in labels: ... labels[basename(o[3])] = 0 ... labels[basename(o[3])] += 1 >>> assert(labels['group 1'] == 4) >>> assert(labels['group 2'] == 9) >>> assert(labels['group 3'] == 7) >>> assert(labels['group 4'] == 1) >>> assert(labels['group 1_r1'] == 4) >>> assert(labels['group2'] == 9) >>> assert(labels['group 3'] == 7) >>> assert(labels['GRCh38.84.bed2'] == 1) >>> gtf = parse.GTF(["{0}/test/GRCh38.84.bed2".format(dirname(parse.__file__)), "{0}/test/GRCh38.84.labels.bed".format(dirname(parse.__file__))]) >>> overlaps = gtf.findOverlaps("1", 1, 30000000) >>> labels = dict() >>> for o in overlaps: ... if basename(o[3]) not in labels: ... labels[basename(o[3])] = 0 ... labels[basename(o[3])] += 1 >>> assert(labels['group 1'] == 8) >>> assert(labels['group 2'] == 9) >>> assert(labels['group 3'] == 14) >>> assert(labels['group 4'] == 1) >>> assert(labels['group2'] == 9) >>> assert(labels['GRCh38.84.bed2'] == 1) """ groupLabelsFound = 0 groupEntries = 0 # Handle the first line if labelColumn is not None: cols = line.split("\t") label = cols.pop(labelColumn) line = "\t".join(cols) if label in self.labels: self.labelIdx = self.labels.index(label) else: self.labels.append(label) self.exons.append(dict()) self.labelIdx = len(self.labels) - 1 else: self.exons.append(dict()) self.parseBEDcore(line, ncols) groupEntries = 1 # iterate over the remaining lines for line in fp: if not isinstance(line, str): line = line.decode('ascii') line = line.strip() if len(line) == 0: # Apparently this happens, some people seem to like trying to break things continue if line.startswith("#") and labelColumn is None: # If there was a previous group AND it had no entries then remove it if groupLabelsFound > 0: if groupEntries == 0: sys.stderr.write("Warning, the '{0}' group had no valid entries! Removing it.\n".format(self.labels[self.labelIdx])) del self.labels[-1] groupLabelsFound -= 1 self.labelIdx -= 1 label = line[1:].strip() if len(label): # Guard against duplicate group labels self.labels.append(findRandomLabel(self.labels, label)) else: # I'm sure someone will try an empty label... self.labels.append(findRandomLabel(self.labels, os.path.basename(self.filename))) self.labelIdx += 1 self.exons.append(dict()) groupLabelsFound += 1 groupEntries = 0 elif line.startswith("#") and labelColumn is not None: continue else: if labelColumn is not None: cols = line.split("\t") label = cols.pop(labelColumn) line = "\t".join(cols) if label in self.labels: self.labelIdx = self.labels.index(label) else: self.labels.append(label) self.exons.append(dict()) self.labelIdx = len(self.labels) - 1 self.parseBEDcore(line, ncols) if labelColumn is None: groupEntries += 1 if groupEntries > 0 and labelColumn is None: if self.defaultGroup is not None: self.labels.append(findRandomLabel(self.labels, self.defaultGroup)) else: self.labels.append(findRandomLabel(self.labels, os.path.basename(self.filename))) # Reset self.labelIdx self.labelIdx = len(self.labels) def parseGTFtranscript(self, cols, label): """ Parse and add a transcript entry """ if int(cols[3]) - 1 < 0: sys.stderr.write("Warning: Invalid start in '{0}', skipping\n".format("\t".join(cols))) return if len(cols) < 9: sys.stderr.write("Warning: non-GTF line encountered! {0}\n".format("\t".join(cols))) return s = next(csv.reader([cols[8]], delimiter=' ')) if "deepTools_group" in s and s[-1] != "deepTools_group": label = s[s.index("deepTools_group") + 1].rstrip(";") elif self.defaultGroup is not None: label = self.defaultGroup if self.transcript_id_designator not in s or s[-1] == self.transcript_id_designator: sys.stderr.write("Warning: {0} is malformed!\n".format("\t".join(cols))) return if int(cols[3]) > int(cols[4]) or int(cols[3]) < 1: sys.stderr.write("Warning: {0}:{1}-{2} is an invalid GTF interval! Ignoring it.\n".format(cols[0], cols[3], cols[4])) return strand = 3 if cols[6] == '+': strand = 0 elif cols[6] == '-': strand = 1 score = cols[5] # Get the label index if label not in self.labels: self.labels.append(label) self.exons.append(dict()) self.labelIdx = self.labels.index(label) # Ensure unique names within GTF files name = s[s.index(self.transcript_id_designator) + 1].rstrip(";") if name in self.exons[self.labelIdx]: sys.stderr.write("Warning: {0} occurs more than once! Only using the first instance.\n".format(name)) self.transcriptIDduplicated.append(name) return chrom = self.mungeChromosome(cols[0]) self.tree.addEntry(chrom, int(cols[3]) - 1, int(cols[4]), name, strand, self.labelIdx, score) # Exon bounds placeholder self.exons[self.labelIdx][name] = [] def parseGTFexon(self, cols): """ Parse an exon entry and add it to the transcript hash """ if int(cols[3]) - 1 < 0: sys.stderr.write("Warning: Invalid start in '{0}', skipping\n".format("\t".join(cols))) return s = next(csv.reader([cols[8]], delimiter=' ')) if self.transcript_id_designator not in s or s[-1] == self.transcript_id_designator: sys.stderr.write("Warning: {0} is malformed!\n".format("\t".join(cols))) return name = s[s.index(self.transcript_id_designator) + 1].rstrip(";") if name in self.transcriptIDduplicated: return if name not in self.exons[self.labelIdx]: self.exons[self.labelIdx][name] = [] self.exons[self.labelIdx][name].append((int(cols[3]) - 1, int(cols[4]))) def parseGTF(self, fp, line): """ parse a GTF file. Note that a single label will be used for every entry in a file that isn't explicitly labeled with a deepTools_group key:values pair in the last column fp: A python file pointer line: The first non-comment line >>> from deeptoolsintervals import parse >>> from os.path import dirname, basename >>> gtf = parse.GTF(["{0}/test/GRCh38.84.gtf.gz".format(dirname(parse.__file__)), "{0}/test/GRCh38.84.2.gtf.gz".format(dirname(parse.__file__))], keepExons=True) >>> overlaps = gtf.findOverlaps("1", 1, 20000000) >>> labels = dict() >>> for o in overlaps: ... if basename(o[3]) not in labels: ... labels[basename(o[3])] = 0 ... labels[basename(o[3])] += 1 >>> assert(labels['GRCh38.84.gtf.gz'] == 17) >>> assert(labels['GRCh38.84.2.gtf.gz'] == 6) >>> assert(labels['group 1'] == 5) >>> assert(labels['group 2'] == 3) Test GTF and a BED file >>> gtf = parse.GTF(["{0}/test/GRCh38.84.gtf.gz".format(dirname(parse.__file__)), "{0}/test/GRCh38.84.bed".format(dirname(parse.__file__))]) >>> overlaps = gtf.findOverlaps("1", 1, 20000000) >>> labels = dict() >>> for o in overlaps: ... if basename(o[3]) not in labels: ... labels[basename(o[3])] = 0 ... labels[basename(o[3])] += 1 >>> assert(labels['GRCh38.84.gtf.gz'] == 17) >>> assert(labels['group 1'] == 3) >>> assert(labels['group 2'] == 1) >>> assert(labels['group 1_r1'] == 4) >>> assert(labels['group2'] == 9) >>> assert(labels['group 3'] == 7) >>> assert(labels['GRCh38.84.bed'] == 1) >>> gtf = parse.GTF(["{0}/test/GRCh38.84.bed".format(dirname(parse.__file__)), "{0}/test/GRCh38.84.gtf.gz".format(dirname(parse.__file__))]) >>> overlaps = gtf.findOverlaps("1", 1, 20000000) >>> labels = dict() >>> for o in overlaps: ... if basename(o[3]) not in labels: ... labels[basename(o[3])] = 0 ... labels[basename(o[3])] += 1 >>> assert(labels['GRCh38.84.gtf.gz'] == 17) >>> assert(labels['group 1'] == 7) >>> assert(labels['group 2'] == 1) >>> assert(labels['group2'] == 9) >>> assert(labels['group 3'] == 7) >>> assert(labels['GRCh38.84.bed'] == 1) """ file_label = findRandomLabel(self.labels, os.path.basename(self.filename)) # Handle the first line cols = line.split("\t") if cols[2].lower() == self.transcriptID.lower(): self.parseGTFtranscript(cols, file_label) elif cols[2].lower() == self.exonID.lower(): self.parseGTFexon(cols) # Handle the remaining lines for line in fp: if not isinstance(line, str): line = line.decode('ascii') if not line.startswith('#'): cols = line.split("\t") if len(cols) == 0: continue if cols[2].lower() == self.transcriptID.lower(): self.parseGTFtranscript(cols, file_label) elif cols[2].lower() == self.exonID.lower() and self.keepExons is True: self.parseGTFexon(cols) # Reset self.labelIdx self.labelIdx = len(self.labels) def __init__(self, fnames, exonID="exon", transcriptID="transcript", keepExons=False, labels=[], transcript_id_designator="transcript_id", defaultGroup=None, verbose=False): """ Driver function to actually parse files. The steps are as follows: 1) skip to the first non-comment line 2) Infer the type from that 3) Call a type-specific processing function accordingly * These call the underlying C code for storage * These handle chromsome name conversions (python-level) * These handle labels (python-level, with a C-level numeric attribute) 4) Sanity checking (do the number of labels make sense?) Required inputs are as follows: fnames: A list of (possibly compressed with gzip or bzip2) GTF or BED files. Optional input is: exonID: For GTF files, the feature column (column 3) label for exons, or whatever else should be stored as exons. The default is 'exon', though one could use 'CDS' instead. transcriptID: As above, but for transcripts. The default is 'transcript_id'. keepExons: For BED12 and GTF files, exons are ignored by default. labels: A list of group labels. transcript_id_designator: For gtf files, this is the key used in a searching for the transcript ID. If one sets transcriptID to 'gene', then transcript_id_designator would need to be changed to 'gene_id' or 'gene_name' to extract the gene ID/name from the attributes. defaultGroup: The default group name. If None, the file name is used. verbose: Whether to produce warning messages (default: False) """ self.fname = [] self.filename = "" self.chroms = [] self.exons = [] self.labels = [] self.transcriptIDduplicated = [] self.tree = tree.initTree() self.labelIdx = 0 self.transcript_id_designator = transcript_id_designator self.exonID = exonID self.transcriptID = transcriptID self.keepExons = keepExons self.defaultGroup = defaultGroup self.verbose = verbose if labels != []: self.already_input_labels = True if not isinstance(fnames, list): fnames = [fnames] # Load the files for fname in fnames: self.filename = fname fp = openPossiblyCompressed(fname) line, labelColumn = self.firstNonComment(fp) if line is None: # This will only ever happen if a file is empty or just has a header/comment continue line = line.strip() ftype = self.inferType(fp, line, labelColumn) if ftype == 'GTF': self.parseGTF(fp, line) elif ftype == 'BED3': self.parseBED(fp, line, 3, labelColumn) elif ftype == 'BED6': self.parseBED(fp, line, 6, labelColumn) else: self.parseBED(fp, line, 12, labelColumn) fp.close() # Sanity check if self.tree.countEntries() == 0: raise RuntimeError("None of the input BED/GTF files had valid regions") # Replace labels if len(labels) > 0: if len(labels) != len(self.labels): raise RuntimeError("The number of labels found ({0}) does not match the number input ({1})!".format(self.labels, labels)) else: self.labels = labels # vine -> tree self.tree.finish() # findOverlaps() def findOverlaps(self, chrom, start, end, strand=".", matchType=0, strandType=0, trimOverlap=False, numericGroups=False, includeStrand=False): """ Given a chromosome and start/end coordinates with an optional strand, return a list of tuples comprised of: * start * end * name * label * [(exon start, exon end), ...] * strand (optional) If there are no overlaps, return None. This function allows stranded searching, though the default is to ignore strand! The non-obvious options are defined in gtf.h: matchType: 0, GTF_MATCH_ANY 1, GTF_MATCH_EXACT 2, GTF_MATCH_CONTAIN 3, GTF_MATCH_WITHIN 4, GTF_MATCH_START 5, GTF_MATCH_END strandType: 0, GTF_IGNORE_STRAND 1, GTF_SAME_STRAND 2, GTF_OPPOSITE_STRAND 3, GTF_EXACT_SAME_STRAND trimOverlap: If true, this removes overlaps from the 5' end that extend beyond the range requested. This is useful in cases where a function calling this does is first dividing the genome into large bins. In that case, 'trimOverlap=True' can be used to ensure that a given interval is never seen more than once. numericGroups: Whether to return group labels or simply the numeric index. The latter is more useful when these are passed to a function whose output will be sorted according to group. includeStrand: Whether to include the strand in the output. The default is False >>> from deeptoolsintervals import parse >>> from os.path import dirname, basename >>> gtf = parse.GTF(["{0}/test/GRCh38.84.bed6".format(dirname(parse.__file__)), "{0}/test/GRCh38.84.bed2".format(dirname(parse.__file__))], keepExons=True) >>> overlaps = gtf.findOverlaps("1", 0, 3000000) >>> labels = dict() >>> for o in overlaps: ... if basename(o[3]) not in labels: ... labels[basename(o[3])] = 0 ... labels[basename(o[3])] += 1 >>> assert(labels['GRCh38.84.bed2'] == 1) >>> assert(labels['GRCh38.84.bed6'] == 15) >>> assert(labels['group2'] == 9) >>> assert(labels['group 3'] == 7) >>> assert(labels['group 1'] == 6) >>> assert(labels['group 1_r1'] == 4) """ chrom = self.mungeChromosome(chrom, append=False) if not chrom: return None # Ensure that this is a tree and has entries, otherwise if self.tree.countEntries() == 0: return None if not self.tree.isTree(): raise RuntimeError('The GTFtree is actually a vine! There must have been an error during creation (this shouldn\'t happen)...') # Convert the strand to a number if strand == '+': strand = 1 elif strand == '-': strand = 2 else: strand = 0 overlaps = self.tree.findOverlaps(chrom, start, end, strand, matchType, strandType, "transcript_id", includeStrand) if overlaps is None: return None for i, o in enumerate(overlaps): if o[2] not in self.exons[o[3]] or len(self.exons[o[3]][o[2]]) == 0: exons = [(o[0], o[1])] else: exons = sorted(self.exons[o[3]][o[2]]) if numericGroups: overlaps[i] = (o[0], o[1], o[2], o[3], exons) else: overlaps[i] = (o[0], o[1], o[2], self.labels[o[3]], exons) if includeStrand: overlaps[i] = overlaps[i] + (str(o[-2].decode("ascii")),) # Add the score overlaps[i] = overlaps[i] + (o[-1],) # Ensure that the intervals are sorted by their 5'-most bound. This enables trimming overlaps = sorted(overlaps) if trimOverlap: while True: if len(overlaps) > 0: if overlaps[0][0] < start: del overlaps[0] else: break else: overlaps = [] break return overlaps deepTools-2.5.0/scripts/0000750000201600010240000000000013067415120014303 5ustar ryanbioinfodeepTools-2.5.0/scripts/mappabilityBigWig_to_unmappableBed.sh0000750000201600010240000000032212757050137023574 0ustar ryanbioinfo#!/usr/bin/sh /package/UCSCTools/bigWigToBedGraph $1 _temp.bed cat _temp.bed | perl -lane '$id+=1; if($F[3]<1) { print "$F[0]\t$F[1]\t$F[2]\tunmap_$id\t0"}' | /package/BEDTools/bin/mergeBed > $2 rm _temp.bed deepTools-2.5.0/scripts/split_bed_into_multiple_files.py0000750000201600010240000000146613066414335022770 0ustar ryanbioinfo#!/usr/bin/env python # -*- coding: utf-8 -*- """ This script is use to split a bed file into smaller beds following the convention that I introduced in which a # indicates a group in the bed file Each bed group is saved under a different name corresponding to the name of the group Useful to split the results of heatmapper when the clustering option is used. :Authors: fidel.ramirez@gmail.com """ import sys i = 0 tempArray = [] for line in sys.stdin: if line[0] == '#': clusterName = line[1:].strip() tempArray.append("#" + clusterName + "\n") open(clusterName + ".bed", 'w').write("".join(tempArray)) tempArray = [] continue tempArray.append(line) if len(tempArray) > 0: clusterName = "no_name" open(clusterName + ".bed", 'w').write("".join(tempArray)) deepTools-2.5.0/CHANGES.txt0000640000201600010240000004353213067414642014445 0ustar ryanbioinfo2.5.0 * Fix a bug where using regions with the same name in multiple BED files in computeMatrix caused downstream problems in plotHeatmap/plotProfile (issue #477). * If computeMatrix/plotHeatmap/plotProfile is asked to sort the output matrix, it now does so by ignoring NaN values. Previously, any row with an NaN was placed at the top of the output (issue #447). * Fixed issue #471 * Various Galaxy wrapper fixes * There is now a `--rowCenter` option in `plotPCA`, which can be used to make each row of the matrix used in the PCA to have a mean of 0. This can be useful in cases where there's extreme region-based depth variation that is shared between all samples. This was issue #477. * The --Offset option is now available in `plotEnrichment`. This was issue #481. * The maximum coverage allowed while calculating the Jensen-Shannon distance in `plotFingerprint` has been increased to 2 million and an informational message containing the number of bins above this value is printed to the standard output. * `bamCoverage` now respects the `--scaleFactor` argument even if not other normalization is performed (issue #482). * The `--minFragmentLength` and `--maxFragmentLength` options now respect single-end reads. For SE reads, these parameters refer to the number of aligned bases (i.e., splicing is ignored). This was issue #489. * `--yMin` and `--yMax` can now be lists of values in `plotHeatmap`. This was issue #487. Note that the plots are not perfectly aligned if you do this. 2.4.3 * Fixed incorrect label ordering in the `plotCorrelation` command with the `--outFileCorMatrix` options. * Fixed bug #491, which involved python 3 and bamCoverage. 2.4.2 * Fixed an issue where `computeMatrix reference-point --referencePoint center` would break if 1-base regions were used. This was bug #456. * `plotCorrelation` with `--outFileCorMatrix` now works with `--labels` again (thanks to @sklasfeld for supplying the patch). * `bigwigCompare` and `bamCompare` can now return the average (mean) of two input files (issue #467). 2.4.1 * Setting --zMin to the same value as --zMax, whether intentionally or because the --zMax value computed by deepTools happens to be now larger than the desired value, will result in the maximum value in the dataset being used (internally, --zMax gets set to None). * Scale factor is now set to 1 in bamCoverage if no normalization is used. The fact that this wasn't being done previously was a bug. * Fixed a bug (#451) affecting BED files with a `deepTools_group` column that caused a problem with `--sortRegions keep` in computeMatrix. * Fixed a bug where some matrices produced with `computeMatrixOperations cbind` would result in the right-most samples sometimes getting squished due to having ticks outside of their graph bounds. Ticks are now scaled if they don't match the data range (issue #452). * In plotFingerprint, the number of reads per-bin are no longer used. Instead, the sum of the per-base coverage (or signal if bigWig input is used) is used. This leads to more similar metrics produced by us and others regarding things like Jensen-Shannon metrics. For those just interested in the plots, there's little effective change here. 2.4.0 * The --Offset option to bamCoverage can now take two values, which can be used to specify a range within each alignment of bases to use. As an example, `--Offset 5 -1` will use ignore the first 4 bases of an alignment (accounting for orientation) and use only the 5th through last base. This can be useful for things like ATACseq (see #370). * Read extension can now be used in conjunction with --Offset in bamCoverage. * plotFingerprint can now output quality metrics, including the Jensen-Shannon distance if a reference sample is specified (see #328). Additionally, various statistics from CHANCE can be produced. * Switched from using the 'twobitreader' python module to our new custom 'py2bit' module for accessing 2bit files. This fixes the performance regression seen in computeGCBias starting in version 2.3.0 (#383). * `bigwigCompare`, `computeMatrix`, and `multiBigwigSummary` can read signal files hosted on [deepBlue](http://deepblue.mpi-inf.mpg.de/). * Fixed a minor bug in `deeptools`, where the `--version` option was ignored (see #404). * Text in SVG and PDF files is now actual text and not a path (see #403). * The `--maxFragmentLength` option in bamCoverage now alters the `maxPairedFragmentLength` that is otherwise hard-coded (see #410). * Added the `computeMatrixOperations` tools, which can be used to sort/reorder/subset/filter/combine the output of `computeMatrix`. * `computeMatrix --sortRegions` has a new `keep` option, which is the default. This mimics the behavior in deepTools prior to 2.3.0 where the output order matched the input order. This is, of course, a bit slower, so if the order doesn't matter then use `no`. * Fixed issue #435, where `plotHeatmap --sortRegions region_length` would crash with an error. * Output bedGraph files are now sorted (#439). * Values stored in bedGraph files (and therefore placed into bigWig files) now use python's "general" format with 6 digits of precision. This tends to produce slightly larger files, but with less loss for values near 0 (see #438). * Corrected how computeGCBias determines the lambda parameter, which should only really affect very atypical experiments (i.e., correctGCBias would have crashed is this greatly affected you). 2.3.6 * multiBamSummary will now not automatically append .npz to the output file name if it's not present. This was bug #436 * Fixed a bug with plotHeatmap where --yMin and --yMax didn't work 2.3.5 * Various Galaxy wrapper fixes (e.g., issue #415 and #417) * Fixed issue #413, wherein the --nanAfterEnd option sometimes causes computeMatrix to throw an error. * Fixed issue #416, wherein --outRawCounts in multiBamSummary and multiBigwigSummary would cause an error if python3 was being used. 2.3.4 * Fixed bug #405, which dealt with the SES normalization in bamCompare (it was producing an error and terminating the program). * Fixed bug #407, which dealt with multiBamSummary or multiBigwigSummary bins and saving the raw data. This was causing an error and the program to terminate. 2.3.3 * Fixed a bug wherein proper pairs where being incorrectly called improper pairs, thereby causing slightly incorrect read extension. 2.3.2 * The deeptoolsinterval module was modified to speed up plotEnrichment, which was taking forever to finish. 2.3.1 * This release has no real code changes, the 2.3.0 release on pypi was missing files. 2.3.0 * Modified how normalization is done when filtering is used. Previously, the filtering wasn't taken into account when computing the total number of alignments. That is now being done. Note that this uses sampling and will try to sample at least 100000 alignments and see what fraction of them are filtered. The total number of aligned reads is then scaled accordingly (#309). * Modified how normalization is done when a blacklist is used. Previously, the number of alignments overlapping a blacklisted region was subtracted from the total number of alignments in the file. This decreased things a bit too much, since only alignments falling completely within a blacklisted region are actually excluded completely (#312). * BED12 and GTF files can now be used as input (issue #71). Additionally, multiBamSummary, multiBigwigSummary and computeMatrix now have a --metagene option, which allows summarization over concatenated exons, rather than include introns as well (this has always been the default). This was issue #76. * Read extension is handled more accurately, such that if a read originates outside of a bin or BED/GTF region that it will typically be included if the --extendReads option is used and the extension would put it in a given bin/region. * deepTools now uses a custom interval-tree implementation that allows including metadata, such as gene/transcript IDs, along with intervals. For those interested, the code for this available separately (https://github.com/dpryan79/deeptools_intervals) with the original C-only implementation here: https://github.com/dpryan79/libGTF. * The API for the countReadsPerBin, getScorePerBigWigBin, and mapReduce modules has changed slightly (this was needed to support the --metagene option). Anyone using these in their own programs is encouraged to look at the modified API before upgrading. * Added the `plotEnrichment` function (this was issue #329). * There is now a `subsetMatrix` script available that can be used to subset the output of computeMatrix. This is useful for preparing plots that only contain a subset of samples/region groups. Note that this isn't installed by default. * The Galaxy wrappers were updated to include the ability to exclude blacklisted regions. * Most functions (both at the command line and within Galaxy) that process BAM files can now filter by fragment length (--minFragmentLength and --maxFragmentLength). By default there's no filtering performed. The primary purpose of this is to facilitate ATACseq analysis, where fragment length determines whether one is processing mono-/di-/poly-nucleosome fragments. This was issue #336. * bamPEFragmentSize now has --logScale and --maxFragmentLength options, which allow you to plot frequencies on the log scale and set the max plotted fragment length, respectively. This was issue #337. * --blackListFileName now accepts multiple files. * bamPEFragmentSize now supports multiple input files. * If the sequence has been removed from BAM files, SE reads no longer cause an error in bamCoverage if --normalizeTo1x is specified. In general, the code that looks at read length now checks the CIGAR string if there's no sequence available in a BAM file (for both PE and SE datasets). This was issue #369. * bamCoverage now respects the --filterRNAstrand option when computing scaling factors. This was issue #353. * computeMatrix and plotHeatmap can now sort using only a subset of samples * There is now an --Offset option to bamCoverage, which allows having the signal at a single base. This is useful for things like RiboSeq or GROseq, where the goal is to get focal peaks at single bases/codons/etc. * The --MNase option to `bamCoverage` now respects --minFragmentLength and --maxFragmentLength, with defaults set to 130 and 200. 2.2.4 * Fix the incorrectly oriented dendrogram in plotCorrelation (issue #350). Relatedly, we're bumping the minimum version of scipy required to one where this is correct. 2.2.3 * Fixed issue #334, where computeGCBias wasn't properly handling the black list option. 2.2.2 * Fixed labels when hierarchical clustering is used (they were off by one previously). * Fixed a bug wherein bamCompare couldn't work with a blacklist * Fixed yet another change in pysam, though at least in this case is was fixing a previous problem 2.2.1 * Fixed a bug introduced in version 2.2.0 wherein sometimes a pre-2.2.0 produced matrix file could no longer be used with plotHeatmap or plotProfile (this only happened when --outFileNameData was then used). * Finally suppressed all of the runtime warnings that numpy likes to randomly throw. * Worked around an undocumented change in pysam-0.9.0 that tended to break things. 2.2.0 * plotFingerprint now iterates through line styles as well as colors. This allows up to 35 samples per plot without repeating (not that that many would ever be recommended). This was issue #80. * Fixed a number of Galaxy wrappers, which were rendered incorrectly due to including a section title of "Background". * A number of image file handles were previously not explicitly closed, which caused occasional completion of a plot* program but without the files actually being there. This only happened on some NFS mount points. * The Galaxy wrappers now support the `--outFileNameData` option on plotProfile and plotHeatmap. * Added support for blacklist regions. These can be supplied as a BED file and the regions will largely be skipped in processing (they'll also be ignored during normalization). This is very useful to skip regions known to attract excess signal. This was issue #101. * Modified plotPCA to include the actual eigenvalues rather than rescaled ones. Also, plotPCA can now output the underlying values (issue #231). * Regions within each feature body can now be unscaled when using `computeMatrix`. Thus, if you're interested in unscaled signal around the TSS/TES then you can now use the `--unscaled5prime` and `--unscaled3prime` options. This was issue #108. * bamCoverage now has a `--filterRNAstrand` option, that will produce coverage for only a single strand. Note that the strand referred to is the DNA strand and not sense/anti-sense. * Issues with plotHeatmap x-axis labels were fixed (issue #301). 2.1.1 * Fixed a how the --hclust option was handled in plotHeatmap/plotProfile. This gets around a quirk in scipy. * A bug involving processing comment lines in BED files was corrected (issue #288) * The Galaxy wrappers are now automatically tested with each modification. * plotCoverage and plotFingerprint in Galaxy now accept 1 or more BAM files rather than at least 2 files. 2.1.0 * Updates to many of the Galaxy wrappers and associated documentation. * A bug was fixed in how chromosome names were dealt with in bigWig files. If you ever received errors due to illegal intervals then that should now be fixed. This was issue #250 * plotProfile now has an --outFileNameData option for saving the underlying data in a text format. * correctGCBias ensures that the resulting BAM file will pass picard/HTSJDK's validation if the input file did (issue #248) * The default bin size was changed to 10, which is typically a bit more useful * The --regionsLabel option to plotProfile and plotHeatmap now accepts a space-separated list, in line with --samplesLabel * BAM files that have had their sequences stripped no longer cause an error * bamPEFragmentSize now has -bs and -n options to allow adjusting the number of alignments sampled. Note that the default value is auto-adjusted if the sampling is too sparse. * bamPEFragmentSize now accepts single-end files. * The --hclust option to plotProfile and plotHeatmap continues even if one of the groups is too small for plotting (matplotlib will produce a warning that you can ignore). This was issue #280. 2.0.1 * A critical bug that prevented plotPCA from running was fixed. * multiBamCoverage was renamed to multiBamSummary, to be in better alignment with multiBigwigSummary. * computeGCBias and correctGCBias are now more tolerant of chromosome name mismatches. * multiBigwigSummary and multiBamSummary can accept a single bigWig/BAM input file, though one should use the --outRawCounts argument. 2.0.0 * Documentation improved and migrated to http://deeptools.readthedocs.org The API to use deepTools modules is now part of the documentation and includes a tutorial. * Allow multiple bigwig files in computeMatrix that can be clustered together * computeMatrix now accepts multiple bed files. Each bed file is considered as a group. Labels are automatically added based on the file names. * When computing read coverage now splited reads are understood. This is convenient for computing the coverage of for RNA-seq data. * New quality control tool 'plotCoverage' to plot the coverage over base pairs for multiple samples * renaming of --missingDataAsZero to --skipNonCovered regions for clarity in bamCoverage and bamCompare * New analysis tool plotPCA that visualizes the results from principal component analysis * New option in bamCoverage `--MNase` that will compute the read coverage only considering 2 base pairs at the center of the fragment. * Make read extension optional. Remove the need to specify a default fragment length for most of the tools. Now, when read extension is enabled and the bam files contain paired en data, the mean fragment length is automatically calculated by sampling the read pairs in the bam file. The --doNotExtendPairedEnds and --fragmentLentgh parameters are no longer used and the new --extendReads parameter was added. * Dramatically improved bigwig related tools by using the new pyBigWig module. Eliminated the requirement for the UCSC program `bigWigInfo` * renamed heatmapper to plotHeatmap and profiler to plotProfile * added hierarchical clustering, besides k-means to plotProfile and plotHeatmap * improved plotting features for plotProfile when using 'overlapped_lines' and 'heatmap' plot types * Resolved an error introduced by numpy version 1.10 in computeMatrix * plotting of correlations (from bamCorrelate or bigwigCorrelate) was separated from the computation of the underlying data. A new tool, plotCorrelation was added. This tool can plot correlations as heatmaps or as scatter plots and includes options to adjust a large array of visual features. * Fixed issue with bed intervals in bigwigCorrelate and bamCorrelate and a user specified region. * Correlation coefficients can be computed even if the data contains NaNs * Allow computeMatrix to read files with DOS newline characters * Added option --skipChromosomes to bigwigCorrelate, for example to skip all 'random' chromosomes. bigwigCorrelate now also considers chromosomes as identical when their names between samples differ with the prefix 'chr'. E.g. chr1 vs. 1 * For bamCoverage and bamCompare, behaviour of scaleFactor was updated such that now, if given in combination with the normalization options (normalize to 1x or normalize using RPKM) the given scaleFactor will multiply the scale factor computed for the normalization methods. * Fixed problem with read pairs labelled as proper pairs by the aligner but that were actually not proper pairs, for example because the mates did not face each other. deepTools adds further checks to determine if a read pair is a proper pair. * Added titles to QC plots (#74) * Added --samFlagInclude and --samFlagExclude parameters. This is useful to for example only include forward reads * In deeptools2 most of the core code was rewriting to facilitate API usage and for optimization. deepTools-2.5.0/LICENSE.txt0000640000201600010240000010451312757050135014452 0ustar ryanbioinfo GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007 Copyright (C) 2007 Free Software Foundation, Inc. Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The GNU General Public License is a free, copyleft license for software and other kinds of works. The licenses for most software and other practical works are designed to take away your freedom to share and change the works. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change all versions of a program--to make sure it remains free software for all its users. We, the Free Software Foundation, use the GNU General Public License for most of our software; it applies also to any other work released this way by its authors. You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for them if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs, and that you know you can do these things. To protect your rights, we need to prevent others from denying you these rights or asking you to surrender the rights. Therefore, you have certain responsibilities if you distribute copies of the software, or if you modify it: responsibilities to respect the freedom of others. For example, if you distribute copies of such a program, whether gratis or for a fee, you must pass on to the recipients the same freedoms that you received. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. Developers that use the GNU GPL protect your rights with two steps: (1) assert copyright on the software, and (2) offer you this License giving you legal permission to copy, distribute and/or modify it. For the developers' and authors' protection, the GPL clearly explains that there is no warranty for this free software. For both users' and authors' sake, the GPL requires that modified versions be marked as changed, so that their problems will not be attributed erroneously to authors of previous versions. Some devices are designed to deny users access to install or run modified versions of the software inside them, although the manufacturer can do so. This is fundamentally incompatible with the aim of protecting users' freedom to change the software. The systematic pattern of such abuse occurs in the area of products for individuals to use, which is precisely where it is most unacceptable. Therefore, we have designed this version of the GPL to prohibit the practice for those products. If such problems arise substantially in other domains, we stand ready to extend this provision to those domains in future versions of the GPL, as needed to protect the freedom of users. Finally, every program is threatened constantly by software patents. States should not allow patents to restrict development and use of software on general-purpose computers, but in those that do, we wish to avoid the special danger that patents applied to a free program could make it effectively proprietary. To prevent this, the GPL assures that patents cannot be used to render the program non-free. The precise terms and conditions for copying, distribution and modification follow. TERMS AND CONDITIONS 0. Definitions. "This License" refers to version 3 of the GNU General Public License. "Copyright" also means copyright-like laws that apply to other kinds of works, such as semiconductor masks. "The Program" refers to any copyrightable work licensed under this License. Each licensee is addressed as "you". "Licensees" and "recipients" may be individuals or organizations. To "modify" a work means to copy from or adapt all or part of the work in a fashion requiring copyright permission, other than the making of an exact copy. The resulting work is called a "modified version" of the earlier work or a work "based on" the earlier work. A "covered work" means either the unmodified Program or a work based on the Program. To "propagate" a work means to do anything with it that, without permission, would make you directly or secondarily liable for infringement under applicable copyright law, except executing it on a computer or modifying a private copy. Propagation includes copying, distribution (with or without modification), making available to the public, and in some countries other activities as well. To "convey" a work means any kind of propagation that enables other parties to make or receive copies. Mere interaction with a user through a computer network, with no transfer of a copy, is not conveying. An interactive user interface displays "Appropriate Legal Notices" to the extent that it includes a convenient and prominently visible feature that (1) displays an appropriate copyright notice, and (2) tells the user that there is no warranty for the work (except to the extent that warranties are provided), that licensees may convey the work under this License, and how to view a copy of this License. If the interface presents a list of user commands or options, such as a menu, a prominent item in the list meets this criterion. 1. Source Code. The "source code" for a work means the preferred form of the work for making modifications to it. "Object code" means any non-source form of a work. A "Standard Interface" means an interface that either is an official standard defined by a recognized standards body, or, in the case of interfaces specified for a particular programming language, one that is widely used among developers working in that language. The "System Libraries" of an executable work include anything, other than the work as a whole, that (a) is included in the normal form of packaging a Major Component, but which is not part of that Major Component, and (b) serves only to enable use of the work with that Major Component, or to implement a Standard Interface for which an implementation is available to the public in source code form. A "Major Component", in this context, means a major essential component (kernel, window system, and so on) of the specific operating system (if any) on which the executable work runs, or a compiler used to produce the work, or an object code interpreter used to run it. The "Corresponding Source" for a work in object code form means all the source code needed to generate, install, and (for an executable work) run the object code and to modify the work, including scripts to control those activities. However, it does not include the work's System Libraries, or general-purpose tools or generally available free programs which are used unmodified in performing those activities but which are not part of the work. For example, Corresponding Source includes interface definition files associated with source files for the work, and the source code for shared libraries and dynamically linked subprograms that the work is specifically designed to require, such as by intimate data communication or control flow between those subprograms and other parts of the work. The Corresponding Source need not include anything that users can regenerate automatically from other parts of the Corresponding Source. The Corresponding Source for a work in source code form is that same work. 2. Basic Permissions. All rights granted under this License are granted for the term of copyright on the Program, and are irrevocable provided the stated conditions are met. This License explicitly affirms your unlimited permission to run the unmodified Program. The output from running a covered work is covered by this License only if the output, given its content, constitutes a covered work. This License acknowledges your rights of fair use or other equivalent, as provided by copyright law. You may make, run and propagate covered works that you do not convey, without conditions so long as your license otherwise remains in force. You may convey covered works to others for the sole purpose of having them make modifications exclusively for you, or provide you with facilities for running those works, provided that you comply with the terms of this License in conveying all material for which you do not control copyright. Those thus making or running the covered works for you must do so exclusively on your behalf, under your direction and control, on terms that prohibit them from making any copies of your copyrighted material outside their relationship with you. Conveying under any other circumstances is permitted solely under the conditions stated below. Sublicensing is not allowed; section 10 makes it unnecessary. 3. Protecting Users' Legal Rights From Anti-Circumvention Law. No covered work shall be deemed part of an effective technological measure under any applicable law fulfilling obligations under article 11 of the WIPO copyright treaty adopted on 20 December 1996, or similar laws prohibiting or restricting circumvention of such measures. When you convey a covered work, you waive any legal power to forbid circumvention of technological measures to the extent such circumvention is effected by exercising rights under this License with respect to the covered work, and you disclaim any intention to limit operation or modification of the work as a means of enforcing, against the work's users, your or third parties' legal rights to forbid circumvention of technological measures. 4. Conveying Verbatim Copies. You may convey verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice; keep intact all notices stating that this License and any non-permissive terms added in accord with section 7 apply to the code; keep intact all notices of the absence of any warranty; and give all recipients a copy of this License along with the Program. You may charge any price or no price for each copy that you convey, and you may offer support or warranty protection for a fee. 5. Conveying Modified Source Versions. You may convey a work based on the Program, or the modifications to produce it from the Program, in the form of source code under the terms of section 4, provided that you also meet all of these conditions: a) The work must carry prominent notices stating that you modified it, and giving a relevant date. b) The work must carry prominent notices stating that it is released under this License and any conditions added under section 7. This requirement modifies the requirement in section 4 to "keep intact all notices". c) You must license the entire work, as a whole, under this License to anyone who comes into possession of a copy. This License will therefore apply, along with any applicable section 7 additional terms, to the whole of the work, and all its parts, regardless of how they are packaged. This License gives no permission to license the work in any other way, but it does not invalidate such permission if you have separately received it. d) If the work has interactive user interfaces, each must display Appropriate Legal Notices; however, if the Program has interactive interfaces that do not display Appropriate Legal Notices, your work need not make them do so. A compilation of a covered work with other separate and independent works, which are not by their nature extensions of the covered work, and which are not combined with it such as to form a larger program, in or on a volume of a storage or distribution medium, is called an "aggregate" if the compilation and its resulting copyright are not used to limit the access or legal rights of the compilation's users beyond what the individual works permit. Inclusion of a covered work in an aggregate does not cause this License to apply to the other parts of the aggregate. 6. Conveying Non-Source Forms. You may convey a covered work in object code form under the terms of sections 4 and 5, provided that you also convey the machine-readable Corresponding Source under the terms of this License, in one of these ways: a) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by the Corresponding Source fixed on a durable physical medium customarily used for software interchange. b) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by a written offer, valid for at least three years and valid for as long as you offer spare parts or customer support for that product model, to give anyone who possesses the object code either (1) a copy of the Corresponding Source for all the software in the product that is covered by this License, on a durable physical medium customarily used for software interchange, for a price no more than your reasonable cost of physically performing this conveying of source, or (2) access to copy the Corresponding Source from a network server at no charge. c) Convey individual copies of the object code with a copy of the written offer to provide the Corresponding Source. This alternative is allowed only occasionally and noncommercially, and only if you received the object code with such an offer, in accord with subsection 6b. d) Convey the object code by offering access from a designated place (gratis or for a charge), and offer equivalent access to the Corresponding Source in the same way through the same place at no further charge. You need not require recipients to copy the Corresponding Source along with the object code. If the place to copy the object code is a network server, the Corresponding Source may be on a different server (operated by you or a third party) that supports equivalent copying facilities, provided you maintain clear directions next to the object code saying where to find the Corresponding Source. Regardless of what server hosts the Corresponding Source, you remain obligated to ensure that it is available for as long as needed to satisfy these requirements. e) Convey the object code using peer-to-peer transmission, provided you inform other peers where the object code and Corresponding Source of the work are being offered to the general public at no charge under subsection 6d. A separable portion of the object code, whose source code is excluded from the Corresponding Source as a System Library, need not be included in conveying the object code work. A "User Product" is either (1) a "consumer product", which means any tangible personal property which is normally used for personal, family, or household purposes, or (2) anything designed or sold for incorporation into a dwelling. In determining whether a product is a consumer product, doubtful cases shall be resolved in favor of coverage. For a particular product received by a particular user, "normally used" refers to a typical or common use of that class of product, regardless of the status of the particular user or of the way in which the particular user actually uses, or expects or is expected to use, the product. A product is a consumer product regardless of whether the product has substantial commercial, industrial or non-consumer uses, unless such uses represent the only significant mode of use of the product. "Installation Information" for a User Product means any methods, procedures, authorization keys, or other information required to install and execute modified versions of a covered work in that User Product from a modified version of its Corresponding Source. The information must suffice to ensure that the continued functioning of the modified object code is in no case prevented or interfered with solely because modification has been made. If you convey an object code work under this section in, or with, or specifically for use in, a User Product, and the conveying occurs as part of a transaction in which the right of possession and use of the User Product is transferred to the recipient in perpetuity or for a fixed term (regardless of how the transaction is characterized), the Corresponding Source conveyed under this section must be accompanied by the Installation Information. But this requirement does not apply if neither you nor any third party retains the ability to install modified object code on the User Product (for example, the work has been installed in ROM). The requirement to provide Installation Information does not include a requirement to continue to provide support service, warranty, or updates for a work that has been modified or installed by the recipient, or for the User Product in which it has been modified or installed. Access to a network may be denied when the modification itself materially and adversely affects the operation of the network or violates the rules and protocols for communication across the network. Corresponding Source conveyed, and Installation Information provided, in accord with this section must be in a format that is publicly documented (and with an implementation available to the public in source code form), and must require no special password or key for unpacking, reading or copying. 7. Additional Terms. "Additional permissions" are terms that supplement the terms of this License by making exceptions from one or more of its conditions. Additional permissions that are applicable to the entire Program shall be treated as though they were included in this License, to the extent that they are valid under applicable law. If additional permissions apply only to part of the Program, that part may be used separately under those permissions, but the entire Program remains governed by this License without regard to the additional permissions. When you convey a copy of a covered work, you may at your option remove any additional permissions from that copy, or from any part of it. (Additional permissions may be written to require their own removal in certain cases when you modify the work.) You may place additional permissions on material, added by you to a covered work, for which you have or can give appropriate copyright permission. Notwithstanding any other provision of this License, for material you add to a covered work, you may (if authorized by the copyright holders of that material) supplement the terms of this License with terms: a) Disclaiming warranty or limiting liability differently from the terms of sections 15 and 16 of this License; or b) Requiring preservation of specified reasonable legal notices or author attributions in that material or in the Appropriate Legal Notices displayed by works containing it; or c) Prohibiting misrepresentation of the origin of that material, or requiring that modified versions of such material be marked in reasonable ways as different from the original version; or d) Limiting the use for publicity purposes of names of licensors or authors of the material; or e) Declining to grant rights under trademark law for use of some trade names, trademarks, or service marks; or f) Requiring indemnification of licensors and authors of that material by anyone who conveys the material (or modified versions of it) with contractual assumptions of liability to the recipient, for any liability that these contractual assumptions directly impose on those licensors and authors. All other non-permissive additional terms are considered "further restrictions" within the meaning of section 10. If the Program as you received it, or any part of it, contains a notice stating that it is governed by this License along with a term that is a further restriction, you may remove that term. If a license document contains a further restriction but permits relicensing or conveying under this License, you may add to a covered work material governed by the terms of that license document, provided that the further restriction does not survive such relicensing or conveying. If you add terms to a covered work in accord with this section, you must place, in the relevant source files, a statement of the additional terms that apply to those files, or a notice indicating where to find the applicable terms. Additional terms, permissive or non-permissive, may be stated in the form of a separately written license, or stated as exceptions; the above requirements apply either way. 8. Termination. You may not propagate or modify a covered work except as expressly provided under this License. Any attempt otherwise to propagate or modify it is void, and will automatically terminate your rights under this License (including any patent licenses granted under the third paragraph of section 11). However, if you cease all violation of this License, then your license from a particular copyright holder is reinstated (a) provisionally, unless and until the copyright holder explicitly and finally terminates your license, and (b) permanently, if the copyright holder fails to notify you of the violation by some reasonable means prior to 60 days after the cessation. Moreover, your license from a particular copyright holder is reinstated permanently if the copyright holder notifies you of the violation by some reasonable means, this is the first time you have received notice of violation of this License (for any work) from that copyright holder, and you cure the violation prior to 30 days after your receipt of the notice. Termination of your rights under this section does not terminate the licenses of parties who have received copies or rights from you under this License. If your rights have been terminated and not permanently reinstated, you do not qualify to receive new licenses for the same material under section 10. 9. Acceptance Not Required for Having Copies. You are not required to accept this License in order to receive or run a copy of the Program. Ancillary propagation of a covered work occurring solely as a consequence of using peer-to-peer transmission to receive a copy likewise does not require acceptance. However, nothing other than this License grants you permission to propagate or modify any covered work. These actions infringe copyright if you do not accept this License. Therefore, by modifying or propagating a covered work, you indicate your acceptance of this License to do so. 10. Automatic Licensing of Downstream Recipients. Each time you convey a covered work, the recipient automatically receives a license from the original licensors, to run, modify and propagate that work, subject to this License. You are not responsible for enforcing compliance by third parties with this License. An "entity transaction" is a transaction transferring control of an organization, or substantially all assets of one, or subdividing an organization, or merging organizations. If propagation of a covered work results from an entity transaction, each party to that transaction who receives a copy of the work also receives whatever licenses to the work the party's predecessor in interest had or could give under the previous paragraph, plus a right to possession of the Corresponding Source of the work from the predecessor in interest, if the predecessor has it or can get it with reasonable efforts. You may not impose any further restrictions on the exercise of the rights granted or affirmed under this License. For example, you may not impose a license fee, royalty, or other charge for exercise of rights granted under this License, and you may not initiate litigation (including a cross-claim or counterclaim in a lawsuit) alleging that any patent claim is infringed by making, using, selling, offering for sale, or importing the Program or any portion of it. 11. Patents. A "contributor" is a copyright holder who authorizes use under this License of the Program or a work on which the Program is based. The work thus licensed is called the contributor's "contributor version". A contributor's "essential patent claims" are all patent claims owned or controlled by the contributor, whether already acquired or hereafter acquired, that would be infringed by some manner, permitted by this License, of making, using, or selling its contributor version, but do not include claims that would be infringed only as a consequence of further modification of the contributor version. For purposes of this definition, "control" includes the right to grant patent sublicenses in a manner consistent with the requirements of this License. Each contributor grants you a non-exclusive, worldwide, royalty-free patent license under the contributor's essential patent claims, to make, use, sell, offer for sale, import and otherwise run, modify and propagate the contents of its contributor version. In the following three paragraphs, a "patent license" is any express agreement or commitment, however denominated, not to enforce a patent (such as an express permission to practice a patent or covenant not to sue for patent infringement). To "grant" such a patent license to a party means to make such an agreement or commitment not to enforce a patent against the party. If you convey a covered work, knowingly relying on a patent license, and the Corresponding Source of the work is not available for anyone to copy, free of charge and under the terms of this License, through a publicly available network server or other readily accessible means, then you must either (1) cause the Corresponding Source to be so available, or (2) arrange to deprive yourself of the benefit of the patent license for this particular work, or (3) arrange, in a manner consistent with the requirements of this License, to extend the patent license to downstream recipients. "Knowingly relying" means you have actual knowledge that, but for the patent license, your conveying the covered work in a country, or your recipient's use of the covered work in a country, would infringe one or more identifiable patents in that country that you have reason to believe are valid. If, pursuant to or in connection with a single transaction or arrangement, you convey, or propagate by procuring conveyance of, a covered work, and grant a patent license to some of the parties receiving the covered work authorizing them to use, propagate, modify or convey a specific copy of the covered work, then the patent license you grant is automatically extended to all recipients of the covered work and works based on it. A patent license is "discriminatory" if it does not include within the scope of its coverage, prohibits the exercise of, or is conditioned on the non-exercise of one or more of the rights that are specifically granted under this License. You may not convey a covered work if you are a party to an arrangement with a third party that is in the business of distributing software, under which you make payment to the third party based on the extent of your activity of conveying the work, and under which the third party grants, to any of the parties who would receive the covered work from you, a discriminatory patent license (a) in connection with copies of the covered work conveyed by you (or copies made from those copies), or (b) primarily for and in connection with specific products or compilations that contain the covered work, unless you entered into that arrangement, or that patent license was granted, prior to 28 March 2007. Nothing in this License shall be construed as excluding or limiting any implied license or other defenses to infringement that may otherwise be available to you under applicable patent law. 12. No Surrender of Others' Freedom. If conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot convey a covered work so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not convey it at all. For example, if you agree to terms that obligate you to collect a royalty for further conveying from those to whom you convey the Program, the only way you could satisfy both those terms and this License would be to refrain entirely from conveying the Program. 13. Use with the GNU Affero General Public License. Notwithstanding any other provision of this License, you have permission to link or combine any covered work with a work licensed under version 3 of the GNU Affero General Public License into a single combined work, and to convey the resulting work. The terms of this License will continue to apply to the part which is the covered work, but the special requirements of the GNU Affero General Public License, section 13, concerning interaction through a network will apply to the combination as such. 14. Revised Versions of this License. The Free Software Foundation may publish revised and/or new versions of the GNU General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies that a certain numbered version of the GNU General Public License "or any later version" applies to it, you have the option of following the terms and conditions either of that numbered version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of the GNU General Public License, you may choose any version ever published by the Free Software Foundation. If the Program specifies that a proxy can decide which future versions of the GNU General Public License can be used, that proxy's public statement of acceptance of a version permanently authorizes you to choose that version for the Program. Later license versions may give you additional or different permissions. However, no additional obligations are imposed on any author or copyright holder as a result of your choosing to follow a later version. 15. Disclaimer of Warranty. THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 16. Limitation of Liability. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 17. Interpretation of Sections 15 and 16. If the disclaimer of warranty and limitation of liability provided above cannot be given local legal effect according to their terms, reviewing courts shall apply local law that most closely approximates an absolute waiver of all civil liability in connection with the Program, unless a warranty or assumption of liability accompanies a copy of the Program in return for a fee. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively state the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . Also add information on how to contact you by electronic and paper mail. If the program does terminal interaction, make it output a short notice like this when it starts in an interactive mode: Copyright (C) This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, your program's commands might be different; for a GUI interface, you would use an "about box". You should also get your employer (if you work as a programmer) or school, if any, to sign a "copyright disclaimer" for the program, if necessary. For more information on this, and how to apply and follow the GNU GPL, see . The GNU General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. But first, please read . deepTools-2.5.0/MANIFEST.in0000750000201600010240000000066112757050135014366 0ustar ryanbioinfoinclude *.txt include README.md include deeptools/config/deeptools.cfg exclude examples/* exclude deepTools.egg-info/* include scripts/* include deeptools/test/test_data/* include deeptools/test/test_heatmapper/* include deeptools/test/test_plotCoverage/* include deeptools/test/test_corrGC/* include deeptoolsintervals/tree.* include deeptoolsintervals/tree/*.c include deeptoolsintervals/tree/*.h include deeptoolsintervals/test/* deepTools-2.5.0/README.md0000640000201600010240000001063713067414676014122 0ustar ryanbioinfo# deepTools [![Build Status](https://travis-ci.org/fidelram/deepTools.svg?branch=master)](https://travis-ci.org/fidelram/deepTools) [![Documentation Status](https://readthedocs.org/projects/deeptools/badge/)](http://deeptools.readthedocs.org/) [![PyPI version](https://badge.fury.io/py/deeptools.svg)](https://badge.fury.io/py/deeptools) [![bioconda-badge](https://img.shields.io/badge/install%20with-bioconda-brightgreen.svg?style=flat-square)](http://bioconda.github.io) ## User-friendly tools for exploring deep-sequencing data deepTools addresses the challenge of handling the large amounts of data that are now routinely generated from DNA sequencing centers. deepTools contains useful modules to process the mapped reads data for multiple quality checks, creating **normalized coverage files** in standard bedGraph and bigWig file formats, that allow comparison between different files (for example, treatment and control). Finally, using such normalized and standardized files, deepTools can create many publication-ready **visualizations** to identify enrichments and for functional annotations of the genome. For support, questions, or feature requests contact: deeptools@googlegroups.com ### Citation: Ramírez F, Ryan DP, Grüning B, Bhardwaj V, Kilpert F, Richter AS, Heyne S, Dündar F, Manke T. [deepTools2: a next generation web server for deep-sequencing data analysis.](https://nar.oxfordjournals.org/content/early/2016/04/12/nar.gkw257.abstract) Nucleic Acids Research. 2016 Apr 13:gkw257. ### Documentation: Our [documentation](http://deeptools.readthedocs.org/) contains more details on the [individual tool scopes and usages](http://deeptools.readthedocs.org/en/latest/content/list_of_tools.html) and an [introduction to our deepTools Galaxy web server](http://deeptools.readthedocs.org/en/latest/content/help_galaxy_intro.html) including [step-by-step protocols](http://deeptools.readthedocs.org/en/latest/content/example_usage.html). >Please see also the [FAQ](http://deeptools.readthedocs.org/en/latest/content/help_faq.html), which we update regularly. Our [Gallery](http://deeptools.readthedocs.org/en/latest/content/example_gallery.html) may give you some more ideas about the scope of deepTools. >For more specific **troubleshooting, feedback, and tool suggestions**, contact us via deeptools@googlegroups.com. ------------------------------------------------------------------------------------------------------------------- ### Installation deepTools are available for: * Command line usage (via pip/anaconda/github) * Integration into Galaxy servers (via toolshed/API/web-browser) There are many easy ways to install deepTools. Details can be found [here](https://deeptools.readthedocs.io/en/latest/content/installation.html) **Install by cloning this repository:** You can install any one of the deepTools branches on command line (linux/mac) by cloning this git repository : $ git clone https://github.com/fidelram/deepTools $ cd deepTools $ python setup.py install By default, the script will install the python library and executable codes globally, which means you need to be root or administrator of the machine to complete the installation. If you need to provide a nonstandard install prefix, or any other nonstandard options, you can provide many command line options to the install script. $ python setup.py --help For example, to install under a specific location use: $ python setup.py install --prefix To install into your home directory, use: $ python setup.py install --user ### Galaxy Installation deepTools can be easily integrated into [Galaxy](http://galaxyproject.org). Please see the [installation instructions in our documentation](http://deeptools.readthedocs.io/en/latest/content/installation.html#galaxy-installation) for further details. **Note:** From version 2.3 onwards, deepTools support **python3**. In case of any problems running with python3/python2, contact our user group : deeptools@googlegroups.com. ------------------------------------ This tool suite is developed by the [Bioinformatics Facility](http://www1.ie-freiburg.mpg.de/bioinformaticsfac) at the [Max Planck Institute for Immunobiology and Epigenetics, Freiburg](http://www1.ie-freiburg.mpg.de/). [Documentation](http://deeptools.readthedocs.org/en/latest/index.html) | [deepTools Galaxy](http://deeptools.ie-freiburg.mpg.de) | [FAQ](http://deeptools.readthedocs.org/en/latest/content/help_faq.html) deepTools-2.5.0/README.rst0000640000201600010240000000251413067414642014316 0ustar ryanbioinfo====================================================================== deepTools ====================================================================== User-friendly tools for exploring deep-sequencing data ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ deepTools addresses the challenge of handling the large amounts of data that are now routinely generated from DNA sequencing centers. deepTools contains useful modules to process the mapped reads data for multiple quality checks, creating **normalized coverage files** in standard bedGraph and bigWig file formats, that allow comparison between different files (for example, treatment and control). Finally, using such normalized and standardized files, deepTools can create many publication-ready **visualizations** to identify enrichments and for functional annotations of the genome. For support, questions, or feature requests contact: deeptools@googlegroups.com For further documentation, please see our `read the docs page `__. Citation: ^^^^^^^^^ Ramírez F, Ryan DP, Grüning B, Bhardwaj V, Kilpert F, Richter AS, Heyne S, Dündar F, Manke T. `deepTools2: a next generation web server for deep-sequencing data analysis. `__ Nucleic Acids Research. 2016 Apr 13:gkw257. deepTools-2.5.0/requirements.txt0000640000201600010240000000014613006372704016105 0ustar ryanbioinfonumpy>=1.9.0 scipy>=0.17.0 matplotlib>=1.4.0 pysam>=0.8.2 py2bit>=0.2.0 numpydoc>=0.5 pyBigWig>=0.2.1 deepTools-2.5.0/setup.cfg0000640000201600010240000000004613067415120014436 0ustar ryanbioinfo[egg_info] tag_build = tag_date = 0 deepTools-2.5.0/PKG-INFO0000640000201600010240000000412313067420377013724 0ustar ryanbioinfoMetadata-Version: 1.1 Name: deepTools Version: 2.5.0 Summary: Useful tools for exploring deep sequencing data Home-page: http://pypi.python.org/pypi/deepTools/ Author: Fidel Ramirez, Devon P Ryan, Björn Grüning, Friederike Dündar, Sarah Diehl, Vivek Bhardwaj, Fabian Kilpert, Andreas S Richter, Steffen Heyne, Thomas Manke Author-email: deeptools@googlegroups.com License: LICENSE.txt Description: ====================================================================== deepTools ====================================================================== User-friendly tools for exploring deep-sequencing data ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ deepTools addresses the challenge of handling the large amounts of data that are now routinely generated from DNA sequencing centers. deepTools contains useful modules to process the mapped reads data for multiple quality checks, creating **normalized coverage files** in standard bedGraph and bigWig file formats, that allow comparison between different files (for example, treatment and control). Finally, using such normalized and standardized files, deepTools can create many publication-ready **visualizations** to identify enrichments and for functional annotations of the genome. For support, questions, or feature requests contact: deeptools@googlegroups.com For further documentation, please see our `read the docs page `__. Citation: ^^^^^^^^^ Ramírez F, Ryan DP, Grüning B, Bhardwaj V, Kilpert F, Richter AS, Heyne S, Dündar F, Manke T. `deepTools2: a next generation web server for deep-sequencing data analysis. `__ Nucleic Acids Research. 2016 Apr 13:gkw257. Platform: UNKNOWN Classifier: Intended Audience :: Science/Research Classifier: Topic :: Scientific/Engineering :: Bio-Informatics deepTools-2.5.0/setup.py0000750000201600010240000001221213067420417014334 0ustar ryanbioinfo# -*- coding: utf-8 -*- import os import sys import subprocess import re from distutils import sysconfig import glob from setuptools import setup, Extension, find_packages from setuptools.command.sdist import sdist as _sdist from setuptools.command.install import install as _install VERSION_PY = """ # This file is originally generated from Git information by running 'setup.py # version'. Distribution tarballs contain a pre-generated copy of this file. __version__ = '%s' """ srcs = [x for x in glob.glob("deeptoolsintervals/tree/*.c")] libs = ["z"] additional_libs = [sysconfig.get_config_var("LIBDIR"), sysconfig.get_config_var("LIBPL")] module1 = Extension('deeptoolsintervals.tree', sources=srcs, libraries=libs, library_dirs=additional_libs, include_dirs=[sysconfig.get_config_var("INCLUDEPY")]) def update_version_py(): if not os.path.isdir(".git"): print("This does not appear to be a Git repository.") return try: p = subprocess.Popen(["git", "describe", "--tags", "--always"], stdout=subprocess.PIPE) except EnvironmentError: print("unable to run git, leaving deeptools/_version.py alone") return stdout = p.communicate()[0] if p.returncode != 0: print("unable to run git, leaving deeptools/_version.py alone") return ver = stdout.decode().strip().replace("-g", "-") f = open("deeptools/_version.py", "w") f.write(VERSION_PY % ver) f.close() print("set deeptools/_version.py to '%s'" % ver) def get_version(): try: f = open("deeptools/_version.py") except EnvironmentError: return None for line in f.readlines(): mo = re.match("__version__ = '([^']+)'", line) if mo: ver = mo.group(1) return ver return None class sdist(_sdist): def run(self): update_version_py() self.distribution.metadata.version = get_version() return _sdist.run(self) class install(_install): def run(self): update_version_py() self.distribution.metadata.version = get_version() _install.run(self) return if os.environ.get('DEEP_TOOLS_NO_CONFIG', False): return self.config_file = self.install_platlib + \ "/deeptools/config/deeptools.cfg" def checkProgramIsInstalled(self, program, args, where_to_download, affected_tools): try: subprocess.Popen([program, args], stderr=subprocess.PIPE, stdout=subprocess.PIPE) return True except EnvironmentError: # handle file not found error. # the config file is installed in: msg = "\n**{0} not found. This " \ "program is needed for the following "\ "tools to work properly:\n"\ " {1}\n"\ "{0} can be downloaded from here:\n " \ " {2}\n".format(program, affected_tools, where_to_download) sys.stderr.write(msg) except Exception as e: sys.stderr.write("Error: {}".format(e)) def openREADME(): """ This is only needed because README.rst is UTF-8 encoded and that won't work under python3 iff sys.getfilesystemencoding() returns 'ascii' Since open() doesn't accept an encoding in python2... """ try: f = open("README.rst", encoding="utf-8") except: f = open("README.rst") foo = f.read() f.close() return foo setup( name='deepTools', version=get_version(), author='Fidel Ramirez, Devon P Ryan, Björn Grüning, Friederike Dündar, Sarah Diehl,' ' Vivek Bhardwaj, Fabian Kilpert, Andreas S Richter, Steffen Heyne, Thomas Manke', author_email='deeptools@googlegroups.com', packages=find_packages(), scripts=['bin/bamCompare', 'bin/bamCoverage', 'bin/multiBamSummary', 'bin/plotHeatmap', 'bin/plotFingerprint', 'bin/estimateScaleFactor', 'bin/bamPEFragmentSize', 'bin/computeMatrix', 'bin/plotProfile', 'bin/computeGCBias', 'bin/correctGCBias', 'bin/multiBigwigSummary', 'bin/bigwigCompare', 'bin/plotCoverage', 'bin/plotPCA', 'bin/plotCorrelation', 'bin/plotEnrichment', 'bin/deeptools', 'bin/computeMatrixOperations'], include_package_data=True, package_data={'': ['config/deeptools.cfg']}, url='http://pypi.python.org/pypi/deepTools/', license='LICENSE.txt', description='Useful tools for exploring deep sequencing data ', long_description=openREADME(), classifiers=[ 'Intended Audience :: Science/Research', 'Topic :: Scientific/Engineering :: Bio-Informatics'], install_requires=[ "numpy >= 1.9.0", "scipy >= 0.17.0", "matplotlib >= 1.4.0", "pysam >= 0.8.2", "numpydoc >=0.5", "pyBigWig >=0.2.1", "py2bit >= 0.2.0" ], zip_safe=False, ext_modules=[module1], cmdclass={'sdist': sdist, 'install': install} )