diff --git a/.github/workflows/maturin_builds.yml b/.github/workflows/maturin_builds.yml new file mode 100644 index 0000000000..c202b5cdb0 --- /dev/null +++ b/.github/workflows/maturin_builds.yml @@ -0,0 +1,172 @@ +name: maturin builds + +on: + push: + pull_request: + +permissions: + contents: read + +jobs: + # linux: + # runs-on: ${{ matrix.platform.runner }} + # strategy: + # matrix: + # platform: + # - runner: ubuntu-latest + # target: x86_64 + # manylinux: 2_28 + # - runner: ubuntu-latest + # target: x86 + # manylinux: 2_28 + # #- runner: ubuntu-latest + # # target: aarch64 + # #- runner: ubuntu-latest + # # target: armv7 + # #- runner: ubuntu-latest + # # target: s390x + # #- runner: ubuntu-latest + # # target: ppc64le + # steps: + # - uses: actions/checkout@v4 + # - uses: actions/setup-python@v5 + # with: + # python-version: 3.x + # - name: Build wheels + # uses: PyO3/maturin-action@v1 + # with: + # target: ${{ matrix.platform.target }} + # manylinux: ${{ matrix.platform.manylinux }} + # args: --release --out dist --find-interpreter + # sccache: 'true' + # - name: Upload wheels + # uses: actions/upload-artifact@v4 + # with: + # name: wheels-linux-${{ matrix.platform.target }} + # path: dist + + # musllinux: + # runs-on: ${{ matrix.platform.runner }} + # strategy: + # matrix: + # platform: + # - runner: ubuntu-latest + # target: x86_64 + # - runner: ubuntu-latest + # target: x86 + # - runner: ubuntu-latest + # target: aarch64 + # - runner: ubuntu-latest + # target: armv7 + # steps: + # - uses: actions/checkout@v4 + # - uses: actions/setup-python@v5 + # with: + # python-version: 3.x + # - name: Build wheels + # uses: PyO3/maturin-action@v1 + # with: + # target: ${{ matrix.platform.target }} + # args: --release --out dist --find-interpreter + # sccache: 'true' + # manylinux: musllinux_1_2 + # - name: Upload wheels + # uses: actions/upload-artifact@v4 + # with: + # name: wheels-musllinux-${{ matrix.platform.target }} + # path: dist + + # windows: + # runs-on: ${{ matrix.platform.runner }} + # strategy: + # matrix: + # platform: + # - runner: windows-latest + # target: x64 + # - runner: windows-latest + # target: x86 + # steps: + # - uses: actions/checkout@v4 + # - uses: actions/setup-python@v5 + # with: + # python-version: 3.x + # architecture: ${{ matrix.platform.target }} + # - name: Build wheels + # uses: PyO3/maturin-action@v1 + # with: + # target: ${{ matrix.platform.target }} + # args: --release --out dist --find-interpreter + # sccache: 'true' + # - name: Upload wheels + # uses: actions/upload-artifact@v4 + # with: + # name: wheels-windows-${{ matrix.platform.target }} + # path: dist + + macos: + runs-on: ${{ matrix.platform.runner }} + strategy: + matrix: + platform: + - runner: macos-latest + target: x86_64 + - runner: macos-latest + target: aarch64 + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-python@v5 + with: + python-version: 3.x + - name: Build wheels + uses: PyO3/maturin-action@v1 + with: + target: ${{ matrix.platform.target }} + args: --release --out dist --find-interpreter + sccache: 'true' + - name: Upload wheels + uses: actions/upload-artifact@v4 + with: + name: wheels-macos-${{ matrix.platform.target }} + path: dist + + sdist: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - name: Build sdist + uses: PyO3/maturin-action@v1 + with: + command: sdist + args: --out dist + - name: Upload sdist + uses: actions/upload-artifact@v4 + with: + name: wheels-sdist + path: dist + + # release: + # name: Release + # runs-on: ubuntu-latest + # if: ${{ startsWith(github.ref, 'refs/tags/') || github.event_name == 'workflow_dispatch' }} + # needs: [linux, musllinux, windows, macos, sdist] + # permissions: + # # Use to sign the release artifacts + # id-token: write + # # Used to upload release artifacts + # contents: write + # # Used to generate artifact attestation + # attestations: write + # steps: + # - uses: actions/download-artifact@v4 + # - name: Generate artifact attestation + # uses: actions/attest-build-provenance@v1 + # with: + # subject-path: 'wheels-*/*' + # - name: Publish to PyPI + # if: "startsWith(github.ref, 'refs/tags/')" + # uses: PyO3/maturin-action@v1 + # env: + # MATURIN_PYPI_TOKEN: ${{ secrets.PYPI_API_TOKEN }} + # with: + # command: upload + # args: --non-interactive --skip-existing wheels-*/* diff --git a/.readthedocs.yaml b/.readthedocs.yaml index d95161e3dc..0ade7e87fd 100644 --- a/.readthedocs.yaml +++ b/.readthedocs.yaml @@ -4,6 +4,9 @@ build: os: ubuntu-22.04 tools: python: "3.12" + rust: "1.82" + apt_packages: + - clang sphinx: configuration: docs/conf.py diff --git a/Cargo.toml b/Cargo.toml index b86ce2230c..d319cb2898 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -9,14 +9,13 @@ name = "hp" crate-type = ["cdylib"] [dependencies] -pyo3 = { version = "0.22.5", features = ["extension-module"] } -rust-htslib = "0.47.0" +pyo3 = { version = "0.23.4", features = ["extension-module"] } +rust-htslib = "0.49.0" rayon = "1.10.0" -itertools = "0.12.1" +itertools = "0.14.0" bigtools = "0.5.3" tokio = "*" flate2 = "*" tempfile = "*" ndarray = "0.16.1" -npyz = "*" -zip = "*" \ No newline at end of file +ndarray-npy = "*" \ No newline at end of file diff --git a/deeptools4.0.0_changes.md b/deeptools4.0.0_changes.md index 37ea18f016..cd2e3b2adc 100644 --- a/deeptools4.0.0_changes.md +++ b/deeptools4.0.0_changes.md @@ -33,6 +33,9 @@ - unmapped reads to unfiltered_out +## multiBamSummary + - npz output has labels encoded as u8s, no longer strings. + # Todo - AlignmentSieve: Shift, Bed, Optimization. diff --git a/docs/index.rst b/docs/index.rst index 1d739da733..4eac3e9ee3 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -21,6 +21,17 @@ currently available. If the file names in the figure mean nothing to you, please make sure to check our :doc:`content/help_glossary`. +deepTools 4.0.0 +--------------- +As of deepTools 4.0.0, quite big changes have been made to the computation backend (which is now written in `rust `_). +The main idea behind this change is to make some tools faster and more robust. +Useability of the tools are not affected. But note that the output (read precision) might be slightly different than before. + + - :doc:`content/tools/bamCoverage` + - :doc:`content/tools/bamCompare` + - :doc:`content/tools/computeMatrix` + - :doc:`content/tools/multiBamSummary` + Contents: --------- diff --git a/galaxy/wrapper/bamCompare.xml b/galaxy/wrapper/bamCompare.xml index df806a41f7..6e654af427 100644 --- a/galaxy/wrapper/bamCompare.xml +++ b/galaxy/wrapper/bamCompare.xml @@ -184,7 +184,6 @@ - @@ -195,11 +194,91 @@ - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + \ No newline at end of file diff --git a/galaxy/wrapper/bamCoverage.xml b/galaxy/wrapper/bamCoverage.xml index a87cc319df..36b6b200cb 100644 --- a/galaxy/wrapper/bamCoverage.xml +++ b/galaxy/wrapper/bamCoverage.xml @@ -158,6 +158,39 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -223,6 +256,18 @@ + + + + + + + + + + + + - + \ No newline at end of file diff --git a/galaxy/wrapper/deepTools_macros.xml b/galaxy/wrapper/deepTools_macros.xml index e6c3d83aff..caa86a3100 100755 --- a/galaxy/wrapper/deepTools_macros.xml +++ b/galaxy/wrapper/deepTools_macros.xml @@ -5,7 +5,7 @@ 23.2 - deeptools + samtools diff --git a/galaxy/wrapper/test-data/coverage_filtered.bg b/galaxy/wrapper/test-data/coverage_filtered.bg new file mode 100644 index 0000000000..4448c0afb8 --- /dev/null +++ b/galaxy/wrapper/test-data/coverage_filtered.bg @@ -0,0 +1,19 @@ +3R 0 50 0.295172 +3R 50 100 0.885515 +3R 100 150 2.21379 +3R 150 250 4.87034 +3R 250 300 3.0993 +3R 300 350 2.36137 +3R 350 400 2.21379 +3R 400 450 3.54206 +3R 450 500 4.13241 +3R 500 550 2.0662 +3R 550 600 2.50896 +3R 600 650 4.57516 +3R 650 700 3.24689 +3R 700 750 3.39448 +3R 750 800 3.83723 +3R 900 950 1.91862 +3R 950 1000 1.32827 +3R 1000 1050 0.73793 +3R 1050 1500 0 diff --git a/galaxy/wrapper/test-data/coverage_filtering.bam b/galaxy/wrapper/test-data/coverage_filtering.bam new file mode 100644 index 0000000000..9d9b932638 Binary files /dev/null and b/galaxy/wrapper/test-data/coverage_filtering.bam differ diff --git a/galaxy/wrapper/test-data/coverage_filtering.blacklist.bed b/galaxy/wrapper/test-data/coverage_filtering.blacklist.bed new file mode 100644 index 0000000000..27dec186c0 --- /dev/null +++ b/galaxy/wrapper/test-data/coverage_filtering.blacklist.bed @@ -0,0 +1 @@ +3R 800 900 diff --git a/galaxy/wrapper/test-data/testA.bam b/galaxy/wrapper/test-data/testA.bam new file mode 100644 index 0000000000..c4cbca9454 Binary files /dev/null and b/galaxy/wrapper/test-data/testA.bam differ diff --git a/galaxy/wrapper/test-data/testA.cram b/galaxy/wrapper/test-data/testA.cram new file mode 100644 index 0000000000..3bb661682e Binary files /dev/null and b/galaxy/wrapper/test-data/testA.cram differ diff --git a/galaxy/wrapper/test-data/testB.bam b/galaxy/wrapper/test-data/testB.bam new file mode 100644 index 0000000000..f1ac616b78 Binary files /dev/null and b/galaxy/wrapper/test-data/testB.bam differ diff --git a/galaxy/wrapper/test-data/testB.cram b/galaxy/wrapper/test-data/testB.cram new file mode 100644 index 0000000000..3a3a5f8ab0 Binary files /dev/null and b/galaxy/wrapper/test-data/testB.cram differ diff --git a/pydeeptools/deeptools/cm.py b/pydeeptools/deeptools/cm.py deleted file mode 100644 index 47bcf16285..0000000000 --- a/pydeeptools/deeptools/cm.py +++ /dev/null @@ -1,1088 +0,0 @@ -#!/usr/bin/env python - -# This file comes from the seaborn project and is under a BSD license: - -# Copyright (c) 2012-2019, Michael L. Waskom -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are met: -# -# * Redistributions of source code must retain the above copyright notice, this -# list of conditions and the following disclaimer. -# -# * Redistributions in binary form must reproduce the above copyright notice, -# this list of conditions and the following disclaimer in the documentation -# and/or other materials provided with the distribution. -# -# * Neither the name of the project nor the names of its -# contributors may be used to endorse or promote products derived from -# this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE -# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -from matplotlib import colors, colormaps as mpl_cm - - -_rocket_lut = [ - [0.01060815, 0.01808215, 0.10018654], - [0.01428972, 0.02048237, 0.10374486], - [0.01831941, 0.0229766, 0.10738511], - [0.02275049, 0.02554464, 0.11108639], - [0.02759119, 0.02818316, 0.11483751], - [0.03285175, 0.03088792, 0.11863035], - [0.03853466, 0.03365771, 0.12245873], - [0.04447016, 0.03648425, 0.12631831], - [0.05032105, 0.03936808, 0.13020508], - [0.05611171, 0.04224835, 0.13411624], - [0.0618531, 0.04504866, 0.13804929], - [0.06755457, 0.04778179, 0.14200206], - [0.0732236, 0.05045047, 0.14597263], - [0.0788708, 0.05305461, 0.14995981], - [0.08450105, 0.05559631, 0.15396203], - [0.09011319, 0.05808059, 0.15797687], - [0.09572396, 0.06050127, 0.16200507], - [0.10132312, 0.06286782, 0.16604287], - [0.10692823, 0.06517224, 0.17009175], - [0.1125315, 0.06742194, 0.17414848], - [0.11813947, 0.06961499, 0.17821272], - [0.12375803, 0.07174938, 0.18228425], - [0.12938228, 0.07383015, 0.18636053], - [0.13501631, 0.07585609, 0.19044109], - [0.14066867, 0.0778224, 0.19452676], - [0.14633406, 0.07973393, 0.1986151], - [0.15201338, 0.08159108, 0.20270523], - [0.15770877, 0.08339312, 0.20679668], - [0.16342174, 0.0851396, 0.21088893], - [0.16915387, 0.08682996, 0.21498104], - [0.17489524, 0.08848235, 0.2190294], - [0.18065495, 0.09009031, 0.22303512], - [0.18643324, 0.09165431, 0.22699705], - [0.19223028, 0.09317479, 0.23091409], - [0.19804623, 0.09465217, 0.23478512], - [0.20388117, 0.09608689, 0.23860907], - [0.20973515, 0.09747934, 0.24238489], - [0.21560818, 0.09882993, 0.24611154], - [0.22150014, 0.10013944, 0.2497868], - [0.22741085, 0.10140876, 0.25340813], - [0.23334047, 0.10263737, 0.25697736], - [0.23928891, 0.10382562, 0.2604936], - [0.24525608, 0.10497384, 0.26395596], - [0.25124182, 0.10608236, 0.26736359], - [0.25724602, 0.10715148, 0.27071569], - [0.26326851, 0.1081815, 0.27401148], - [0.26930915, 0.1091727, 0.2772502], - [0.27536766, 0.11012568, 0.28043021], - [0.28144375, 0.11104133, 0.2835489], - [0.2875374, 0.11191896, 0.28660853], - [0.29364846, 0.11275876, 0.2896085], - [0.29977678, 0.11356089, 0.29254823], - [0.30592213, 0.11432553, 0.29542718], - [0.31208435, 0.11505284, 0.29824485], - [0.31826327, 0.1157429, 0.30100076], - [0.32445869, 0.11639585, 0.30369448], - [0.33067031, 0.11701189, 0.30632563], - [0.33689808, 0.11759095, 0.3088938], - [0.34314168, 0.11813362, 0.31139721], - [0.34940101, 0.11863987, 0.3138355], - [0.355676, 0.11910909, 0.31620996], - [0.36196644, 0.1195413, 0.31852037], - [0.36827206, 0.11993653, 0.32076656], - [0.37459292, 0.12029443, 0.32294825], - [0.38092887, 0.12061482, 0.32506528], - [0.38727975, 0.12089756, 0.3271175], - [0.39364518, 0.12114272, 0.32910494], - [0.40002537, 0.12134964, 0.33102734], - [0.40642019, 0.12151801, 0.33288464], - [0.41282936, 0.12164769, 0.33467689], - [0.41925278, 0.12173833, 0.33640407], - [0.42569057, 0.12178916, 0.33806605], - [0.43214263, 0.12179973, 0.33966284], - [0.43860848, 0.12177004, 0.34119475], - [0.44508855, 0.12169883, 0.34266151], - [0.45158266, 0.12158557, 0.34406324], - [0.45809049, 0.12142996, 0.34540024], - [0.46461238, 0.12123063, 0.34667231], - [0.47114798, 0.12098721, 0.34787978], - [0.47769736, 0.12069864, 0.34902273], - [0.48426077, 0.12036349, 0.35010104], - [0.49083761, 0.11998161, 0.35111537], - [0.49742847, 0.11955087, 0.35206533], - [0.50403286, 0.11907081, 0.35295152], - [0.51065109, 0.11853959, 0.35377385], - [0.51728314, 0.1179558, 0.35453252], - [0.52392883, 0.11731817, 0.35522789], - [0.53058853, 0.11662445, 0.35585982], - [0.53726173, 0.11587369, 0.35642903], - [0.54394898, 0.11506307, 0.35693521], - [0.5506426, 0.11420757, 0.35737863], - [0.55734473, 0.11330456, 0.35775059], - [0.56405586, 0.11235265, 0.35804813], - [0.57077365, 0.11135597, 0.35827146], - [0.5774991, 0.11031233, 0.35841679], - [0.58422945, 0.10922707, 0.35848469], - [0.59096382, 0.10810205, 0.35847347], - [0.59770215, 0.10693774, 0.35838029], - [0.60444226, 0.10573912, 0.35820487], - [0.61118304, 0.10450943, 0.35794557], - [0.61792306, 0.10325288, 0.35760108], - [0.62466162, 0.10197244, 0.35716891], - [0.63139686, 0.10067417, 0.35664819], - [0.63812122, 0.09938212, 0.35603757], - [0.64483795, 0.0980891, 0.35533555], - [0.65154562, 0.09680192, 0.35454107], - [0.65824241, 0.09552918, 0.3536529], - [0.66492652, 0.09428017, 0.3526697], - [0.67159578, 0.09306598, 0.35159077], - [0.67824099, 0.09192342, 0.3504148], - [0.684863, 0.09085633, 0.34914061], - [0.69146268, 0.0898675, 0.34776864], - [0.69803757, 0.08897226, 0.3462986], - [0.70457834, 0.0882129, 0.34473046], - [0.71108138, 0.08761223, 0.3430635], - [0.7175507, 0.08716212, 0.34129974], - [0.72398193, 0.08688725, 0.33943958], - [0.73035829, 0.0868623, 0.33748452], - [0.73669146, 0.08704683, 0.33543669], - [0.74297501, 0.08747196, 0.33329799], - [0.74919318, 0.08820542, 0.33107204], - [0.75535825, 0.08919792, 0.32876184], - [0.76145589, 0.09050716, 0.32637117], - [0.76748424, 0.09213602, 0.32390525], - [0.77344838, 0.09405684, 0.32136808], - [0.77932641, 0.09634794, 0.31876642], - [0.78513609, 0.09892473, 0.31610488], - [0.79085854, 0.10184672, 0.313391], - [0.7965014, 0.10506637, 0.31063031], - [0.80205987, 0.10858333, 0.30783], - [0.80752799, 0.11239964, 0.30499738], - [0.81291606, 0.11645784, 0.30213802], - [0.81820481, 0.12080606, 0.29926105], - [0.82341472, 0.12535343, 0.2963705], - [0.82852822, 0.13014118, 0.29347474], - [0.83355779, 0.13511035, 0.29057852], - [0.83850183, 0.14025098, 0.2876878], - [0.84335441, 0.14556683, 0.28480819], - [0.84813096, 0.15099892, 0.281943], - [0.85281737, 0.15657772, 0.27909826], - [0.85742602, 0.1622583, 0.27627462], - [0.86196552, 0.16801239, 0.27346473], - [0.86641628, 0.17387796, 0.27070818], - [0.87079129, 0.17982114, 0.26797378], - [0.87507281, 0.18587368, 0.26529697], - [0.87925878, 0.19203259, 0.26268136], - [0.8833417, 0.19830556, 0.26014181], - [0.88731387, 0.20469941, 0.25769539], - [0.89116859, 0.21121788, 0.2553592], - [0.89490337, 0.21785614, 0.25314362], - [0.8985026, 0.22463251, 0.25108745], - [0.90197527, 0.23152063, 0.24918223], - [0.90530097, 0.23854541, 0.24748098], - [0.90848638, 0.24568473, 0.24598324], - [0.911533, 0.25292623, 0.24470258], - [0.9144225, 0.26028902, 0.24369359], - [0.91717106, 0.26773821, 0.24294137], - [0.91978131, 0.27526191, 0.24245973], - [0.92223947, 0.28287251, 0.24229568], - [0.92456587, 0.29053388, 0.24242622], - [0.92676657, 0.29823282, 0.24285536], - [0.92882964, 0.30598085, 0.24362274], - [0.93078135, 0.31373977, 0.24468803], - [0.93262051, 0.3215093, 0.24606461], - [0.93435067, 0.32928362, 0.24775328], - [0.93599076, 0.33703942, 0.24972157], - [0.93752831, 0.34479177, 0.25199928], - [0.93899289, 0.35250734, 0.25452808], - [0.94036561, 0.36020899, 0.25734661], - [0.94167588, 0.36786594, 0.2603949], - [0.94291042, 0.37549479, 0.26369821], - [0.94408513, 0.3830811, 0.26722004], - [0.94520419, 0.39062329, 0.27094924], - [0.94625977, 0.39813168, 0.27489742], - [0.94727016, 0.4055909, 0.27902322], - [0.94823505, 0.41300424, 0.28332283], - [0.94914549, 0.42038251, 0.28780969], - [0.95001704, 0.42771398, 0.29244728], - [0.95085121, 0.43500005, 0.29722817], - [0.95165009, 0.44224144, 0.30214494], - [0.9524044, 0.44944853, 0.3072105], - [0.95312556, 0.45661389, 0.31239776], - [0.95381595, 0.46373781, 0.31769923], - [0.95447591, 0.47082238, 0.32310953], - [0.95510255, 0.47787236, 0.32862553], - [0.95569679, 0.48489115, 0.33421404], - [0.95626788, 0.49187351, 0.33985601], - [0.95681685, 0.49882008, 0.34555431], - [0.9573439, 0.50573243, 0.35130912], - [0.95784842, 0.51261283, 0.35711942], - [0.95833051, 0.51946267, 0.36298589], - [0.95879054, 0.52628305, 0.36890904], - [0.95922872, 0.53307513, 0.3748895], - [0.95964538, 0.53983991, 0.38092784], - [0.96004345, 0.54657593, 0.3870292], - [0.96042097, 0.55328624, 0.39319057], - [0.96077819, 0.55997184, 0.39941173], - [0.9611152, 0.5666337, 0.40569343], - [0.96143273, 0.57327231, 0.41203603], - [0.96173392, 0.57988594, 0.41844491], - [0.96201757, 0.58647675, 0.42491751], - [0.96228344, 0.59304598, 0.43145271], - [0.96253168, 0.5995944, 0.43805131], - [0.96276513, 0.60612062, 0.44471698], - [0.96298491, 0.6126247, 0.45145074], - [0.96318967, 0.61910879, 0.45824902], - [0.96337949, 0.6255736, 0.46511271], - [0.96355923, 0.63201624, 0.47204746], - [0.96372785, 0.63843852, 0.47905028], - [0.96388426, 0.64484214, 0.4861196], - [0.96403203, 0.65122535, 0.4932578], - [0.96417332, 0.65758729, 0.50046894], - [0.9643063, 0.66393045, 0.5077467], - [0.96443322, 0.67025402, 0.51509334], - [0.96455845, 0.67655564, 0.52251447], - [0.96467922, 0.68283846, 0.53000231], - [0.96479861, 0.68910113, 0.53756026], - [0.96492035, 0.69534192, 0.5451917], - [0.96504223, 0.7015636, 0.5528892], - [0.96516917, 0.70776351, 0.5606593], - [0.96530224, 0.71394212, 0.56849894], - [0.96544032, 0.72010124, 0.57640375], - [0.96559206, 0.72623592, 0.58438387], - [0.96575293, 0.73235058, 0.59242739], - [0.96592829, 0.73844258, 0.60053991], - [0.96612013, 0.74451182, 0.60871954], - [0.96632832, 0.75055966, 0.61696136], - [0.96656022, 0.75658231, 0.62527295], - [0.96681185, 0.76258381, 0.63364277], - [0.96709183, 0.76855969, 0.64207921], - [0.96739773, 0.77451297, 0.65057302], - [0.96773482, 0.78044149, 0.65912731], - [0.96810471, 0.78634563, 0.66773889], - [0.96850919, 0.79222565, 0.6764046], - [0.96893132, 0.79809112, 0.68512266], - [0.96935926, 0.80395415, 0.69383201], - [0.9698028, 0.80981139, 0.70252255], - [0.97025511, 0.81566605, 0.71120296], - [0.97071849, 0.82151775, 0.71987163], - [0.97120159, 0.82736371, 0.72851999], - [0.97169389, 0.83320847, 0.73716071], - [0.97220061, 0.83905052, 0.74578903], - [0.97272597, 0.84488881, 0.75440141], - [0.97327085, 0.85072354, 0.76299805], - [0.97383206, 0.85655639, 0.77158353], - [0.97441222, 0.86238689, 0.78015619], - [0.97501782, 0.86821321, 0.78871034], - [0.97564391, 0.87403763, 0.79725261], - [0.97628674, 0.87986189, 0.8057883], - [0.97696114, 0.88568129, 0.81430324], - [0.97765722, 0.89149971, 0.82280948], - [0.97837585, 0.89731727, 0.83130786], - [0.97912374, 0.90313207, 0.83979337], - [0.979891, 0.90894778, 0.84827858], - [0.98067764, 0.91476465, 0.85676611], - [0.98137749, 0.92061729, 0.86536915] -] - - -_mako_lut = [ - [0.04503935, 0.01482344, 0.02092227], - [0.04933018, 0.01709292, 0.02535719], - [0.05356262, 0.01950702, 0.03018802], - [0.05774337, 0.02205989, 0.03545515], - [0.06188095, 0.02474764, 0.04115287], - [0.06598247, 0.0275665, 0.04691409], - [0.07005374, 0.03051278, 0.05264306], - [0.07409947, 0.03358324, 0.05834631], - [0.07812339, 0.03677446, 0.06403249], - [0.08212852, 0.0400833, 0.06970862], - [0.08611731, 0.04339148, 0.07538208], - [0.09009161, 0.04664706, 0.08105568], - [0.09405308, 0.04985685, 0.08673591], - [0.09800301, 0.05302279, 0.09242646], - [0.10194255, 0.05614641, 0.09813162], - [0.10587261, 0.05922941, 0.103854], - [0.1097942, 0.06227277, 0.10959847], - [0.11370826, 0.06527747, 0.11536893], - [0.11761516, 0.06824548, 0.12116393], - [0.12151575, 0.07117741, 0.12698763], - [0.12541095, 0.07407363, 0.1328442], - [0.12930083, 0.07693611, 0.13873064], - [0.13317849, 0.07976988, 0.14465095], - [0.13701138, 0.08259683, 0.15060265], - [0.14079223, 0.08542126, 0.15659379], - [0.14452486, 0.08824175, 0.16262484], - [0.14820351, 0.09106304, 0.16869476], - [0.15183185, 0.09388372, 0.17480366], - [0.15540398, 0.09670855, 0.18094993], - [0.15892417, 0.09953561, 0.18713384], - [0.16238588, 0.10236998, 0.19335329], - [0.16579435, 0.10520905, 0.19960847], - [0.16914226, 0.10805832, 0.20589698], - [0.17243586, 0.11091443, 0.21221911], - [0.17566717, 0.11378321, 0.21857219], - [0.17884322, 0.11666074, 0.2249565], - [0.18195582, 0.11955283, 0.23136943], - [0.18501213, 0.12245547, 0.23781116], - [0.18800459, 0.12537395, 0.24427914], - [0.19093944, 0.1283047, 0.25077369], - [0.19381092, 0.13125179, 0.25729255], - [0.19662307, 0.13421303, 0.26383543], - [0.19937337, 0.13719028, 0.27040111], - [0.20206187, 0.14018372, 0.27698891], - [0.20469116, 0.14319196, 0.28359861], - [0.20725547, 0.14621882, 0.29022775], - [0.20976258, 0.14925954, 0.29687795], - [0.21220409, 0.15231929, 0.30354703], - [0.21458611, 0.15539445, 0.31023563], - [0.21690827, 0.15848519, 0.31694355], - [0.21916481, 0.16159489, 0.32366939], - [0.2213631, 0.16471913, 0.33041431], - [0.22349947, 0.1678599, 0.33717781], - [0.2255714, 0.1710185, 0.34395925], - [0.22758415, 0.17419169, 0.35075983], - [0.22953569, 0.17738041, 0.35757941], - [0.23142077, 0.18058733, 0.3644173], - [0.2332454, 0.18380872, 0.37127514], - [0.2350092, 0.18704459, 0.3781528], - [0.23670785, 0.190297, 0.38504973], - [0.23834119, 0.19356547, 0.39196711], - [0.23991189, 0.19684817, 0.39890581], - [0.24141903, 0.20014508, 0.4058667], - [0.24286214, 0.20345642, 0.4128484], - [0.24423453, 0.20678459, 0.41985299], - [0.24554109, 0.21012669, 0.42688124], - [0.2467815, 0.21348266, 0.43393244], - [0.24795393, 0.21685249, 0.4410088], - [0.24905614, 0.22023618, 0.448113], - [0.25007383, 0.22365053, 0.45519562], - [0.25098926, 0.22710664, 0.46223892], - [0.25179696, 0.23060342, 0.46925447], - [0.25249346, 0.23414353, 0.47623196], - [0.25307401, 0.23772973, 0.48316271], - [0.25353152, 0.24136961, 0.49001976], - [0.25386167, 0.24506548, 0.49679407], - [0.25406082, 0.2488164, 0.50348932], - [0.25412435, 0.25262843, 0.51007843], - [0.25404842, 0.25650743, 0.51653282], - [0.25383134, 0.26044852, 0.52286845], - [0.2534705, 0.26446165, 0.52903422], - [0.25296722, 0.2685428, 0.53503572], - [0.2523226, 0.27269346, 0.54085315], - [0.25153974, 0.27691629, 0.54645752], - [0.25062402, 0.28120467, 0.55185939], - [0.24958205, 0.28556371, 0.55701246], - [0.24842386, 0.28998148, 0.56194601], - [0.24715928, 0.29446327, 0.56660884], - [0.24580099, 0.29899398, 0.57104399], - [0.24436202, 0.30357852, 0.57519929], - [0.24285591, 0.30819938, 0.57913247], - [0.24129828, 0.31286235, 0.58278615], - [0.23970131, 0.3175495, 0.5862272], - [0.23807973, 0.32226344, 0.58941872], - [0.23644557, 0.32699241, 0.59240198], - [0.2348113, 0.33173196, 0.59518282], - [0.23318874, 0.33648036, 0.59775543], - [0.2315855, 0.34122763, 0.60016456], - [0.23001121, 0.34597357, 0.60240251], - [0.2284748, 0.35071512, 0.6044784], - [0.22698081, 0.35544612, 0.60642528], - [0.22553305, 0.36016515, 0.60825252], - [0.22413977, 0.36487341, 0.60994938], - [0.22280246, 0.36956728, 0.61154118], - [0.22152555, 0.37424409, 0.61304472], - [0.22030752, 0.37890437, 0.61446646], - [0.2191538, 0.38354668, 0.61581561], - [0.21806257, 0.38817169, 0.61709794], - [0.21703799, 0.39277882, 0.61831922], - [0.21607792, 0.39736958, 0.61948028], - [0.21518463, 0.40194196, 0.62059763], - [0.21435467, 0.40649717, 0.62167507], - [0.21358663, 0.41103579, 0.62271724], - [0.21288172, 0.41555771, 0.62373011], - [0.21223835, 0.42006355, 0.62471794], - [0.21165312, 0.42455441, 0.62568371], - [0.21112526, 0.42903064, 0.6266318], - [0.21065161, 0.43349321, 0.62756504], - [0.21023306, 0.43794288, 0.62848279], - [0.20985996, 0.44238227, 0.62938329], - [0.20951045, 0.44680966, 0.63030696], - [0.20916709, 0.45122981, 0.63124483], - [0.20882976, 0.45564335, 0.63219599], - [0.20849798, 0.46005094, 0.63315928], - [0.20817199, 0.46445309, 0.63413391], - [0.20785149, 0.46885041, 0.63511876], - [0.20753716, 0.47324327, 0.63611321], - [0.20722876, 0.47763224, 0.63711608], - [0.20692679, 0.48201774, 0.63812656], - [0.20663156, 0.48640018, 0.63914367], - [0.20634336, 0.49078002, 0.64016638], - [0.20606303, 0.49515755, 0.6411939], - [0.20578999, 0.49953341, 0.64222457], - [0.20552612, 0.50390766, 0.64325811], - [0.20527189, 0.50828072, 0.64429331], - [0.20502868, 0.51265277, 0.64532947], - [0.20479718, 0.51702417, 0.64636539], - [0.20457804, 0.52139527, 0.64739979], - [0.20437304, 0.52576622, 0.64843198], - [0.20418396, 0.53013715, 0.64946117], - [0.20401238, 0.53450825, 0.65048638], - [0.20385896, 0.53887991, 0.65150606], - [0.20372653, 0.54325208, 0.65251978], - [0.20361709, 0.5476249, 0.6535266], - [0.20353258, 0.55199854, 0.65452542], - [0.20347472, 0.55637318, 0.655515], - [0.20344718, 0.56074869, 0.65649508], - [0.20345161, 0.56512531, 0.65746419], - [0.20349089, 0.56950304, 0.65842151], - [0.20356842, 0.57388184, 0.65936642], - [0.20368663, 0.57826181, 0.66029768], - [0.20384884, 0.58264293, 0.6612145], - [0.20405904, 0.58702506, 0.66211645], - [0.20431921, 0.59140842, 0.66300179], - [0.20463464, 0.59579264, 0.66387079], - [0.20500731, 0.60017798, 0.66472159], - [0.20544449, 0.60456387, 0.66555409], - [0.20596097, 0.60894927, 0.66636568], - [0.20654832, 0.61333521, 0.66715744], - [0.20721003, 0.61772167, 0.66792838], - [0.20795035, 0.62210845, 0.66867802], - [0.20877302, 0.62649546, 0.66940555], - [0.20968223, 0.63088252, 0.6701105], - [0.21068163, 0.63526951, 0.67079211], - [0.21177544, 0.63965621, 0.67145005], - [0.21298582, 0.64404072, 0.67208182], - [0.21430361, 0.64842404, 0.67268861], - [0.21572716, 0.65280655, 0.67326978], - [0.21726052, 0.65718791, 0.6738255], - [0.21890636, 0.66156803, 0.67435491], - [0.220668, 0.66594665, 0.67485792], - [0.22255447, 0.67032297, 0.67533374], - [0.22458372, 0.67469531, 0.67578061], - [0.22673713, 0.67906542, 0.67620044], - [0.22901625, 0.6834332, 0.67659251], - [0.23142316, 0.68779836, 0.67695703], - [0.23395924, 0.69216072, 0.67729378], - [0.23663857, 0.69651881, 0.67760151], - [0.23946645, 0.70087194, 0.67788018], - [0.24242624, 0.70522162, 0.67813088], - [0.24549008, 0.70957083, 0.67835215], - [0.24863372, 0.71392166, 0.67854868], - [0.25187832, 0.71827158, 0.67872193], - [0.25524083, 0.72261873, 0.67887024], - [0.25870947, 0.72696469, 0.67898912], - [0.26229238, 0.73130855, 0.67907645], - [0.26604085, 0.73564353, 0.67914062], - [0.26993099, 0.73997282, 0.67917264], - [0.27397488, 0.74429484, 0.67917096], - [0.27822463, 0.74860229, 0.67914468], - [0.28264201, 0.75290034, 0.67907959], - [0.2873016, 0.75717817, 0.67899164], - [0.29215894, 0.76144162, 0.67886578], - [0.29729823, 0.76567816, 0.67871894], - [0.30268199, 0.76989232, 0.67853896], - [0.30835665, 0.77407636, 0.67833512], - [0.31435139, 0.77822478, 0.67811118], - [0.3206671, 0.78233575, 0.67786729], - [0.32733158, 0.78640315, 0.67761027], - [0.33437168, 0.79042043, 0.67734882], - [0.34182112, 0.79437948, 0.67709394], - [0.34968889, 0.79827511, 0.67685638], - [0.35799244, 0.80210037, 0.67664969], - [0.36675371, 0.80584651, 0.67649539], - [0.3759816, 0.80950627, 0.67641393], - [0.38566792, 0.81307432, 0.67642947], - [0.39579804, 0.81654592, 0.67656899], - [0.40634556, 0.81991799, 0.67686215], - [0.41730243, 0.82318339, 0.67735255], - [0.4285828, 0.82635051, 0.6780564], - [0.44012728, 0.82942353, 0.67900049], - [0.45189421, 0.83240398, 0.68021733], - [0.46378379, 0.83530763, 0.6817062], - [0.47573199, 0.83814472, 0.68347352], - [0.48769865, 0.84092197, 0.68552698], - [0.49962354, 0.84365379, 0.68783929], - [0.5114027, 0.8463718, 0.69029789], - [0.52301693, 0.84908401, 0.69288545], - [0.53447549, 0.85179048, 0.69561066], - [0.54578602, 0.8544913, 0.69848331], - [0.55695565, 0.85718723, 0.70150427], - [0.56798832, 0.85987893, 0.70468261], - [0.57888639, 0.86256715, 0.70802931], - [0.5896541, 0.8652532, 0.71154204], - [0.60028928, 0.86793835, 0.71523675], - [0.61079441, 0.87062438, 0.71910895], - [0.62116633, 0.87331311, 0.72317003], - [0.63140509, 0.87600675, 0.72741689], - [0.64150735, 0.87870746, 0.73185717], - [0.65147219, 0.8814179, 0.73648495], - [0.66129632, 0.8841403, 0.74130658], - [0.67097934, 0.88687758, 0.74631123], - [0.68051833, 0.88963189, 0.75150483], - [0.68991419, 0.89240612, 0.75687187], - [0.69916533, 0.89520211, 0.76241714], - [0.70827373, 0.89802257, 0.76812286], - [0.71723995, 0.90086891, 0.77399039], - [0.72606665, 0.90374337, 0.7800041], - [0.73475675, 0.90664718, 0.78615802], - [0.74331358, 0.90958151, 0.79244474], - [0.75174143, 0.91254787, 0.79884925], - [0.76004473, 0.91554656, 0.80536823], - [0.76827704, 0.91856549, 0.81196513], - [0.77647029, 0.921603, 0.81855729], - [0.78462009, 0.92466151, 0.82514119], - [0.79273542, 0.92773848, 0.83172131], - [0.8008109, 0.93083672, 0.83829355], - [0.80885107, 0.93395528, 0.84485982], - [0.81685878, 0.9370938, 0.85142101], - [0.82483206, 0.94025378, 0.8579751], - [0.83277661, 0.94343371, 0.86452477], - [0.84069127, 0.94663473, 0.87106853], - [0.84857662, 0.9498573, 0.8776059], - [0.8564431, 0.95309792, 0.88414253], - [0.86429066, 0.95635719, 0.89067759], - [0.87218969, 0.95960708, 0.89725384] -] - - -_vlag_lut = [ - [0.13850039, 0.41331206, 0.74052025], - [0.15077609, 0.41762684, 0.73970427], - [0.16235219, 0.4219191, 0.7389667], - [0.1733322, 0.42619024, 0.73832537], - [0.18382538, 0.43044226, 0.73776764], - [0.19394034, 0.4346772, 0.73725867], - [0.20367115, 0.43889576, 0.73685314], - [0.21313625, 0.44310003, 0.73648045], - [0.22231173, 0.44729079, 0.73619681], - [0.23125148, 0.45146945, 0.73597803], - [0.23998101, 0.45563715, 0.7358223], - [0.24853358, 0.45979489, 0.73571524], - [0.25691416, 0.4639437, 0.73566943], - [0.26513894, 0.46808455, 0.73568319], - [0.27322194, 0.47221835, 0.73575497], - [0.28117543, 0.47634598, 0.73588332], - [0.28901021, 0.48046826, 0.73606686], - [0.2967358, 0.48458597, 0.73630433], - [0.30436071, 0.48869986, 0.73659451], - [0.3118955, 0.49281055, 0.73693255], - [0.31935389, 0.49691847, 0.73730851], - [0.32672701, 0.5010247, 0.73774013], - [0.33402607, 0.50512971, 0.73821941], - [0.34125337, 0.50923419, 0.73874905], - [0.34840921, 0.51333892, 0.73933402], - [0.35551826, 0.51744353, 0.73994642], - [0.3625676, 0.52154929, 0.74060763], - [0.36956356, 0.52565656, 0.74131327], - [0.37649902, 0.52976642, 0.74207698], - [0.38340273, 0.53387791, 0.74286286], - [0.39025859, 0.53799253, 0.7436962], - [0.39706821, 0.54211081, 0.744578], - [0.40384046, 0.54623277, 0.74549872], - [0.41058241, 0.55035849, 0.74645094], - [0.41728385, 0.55448919, 0.74745174], - [0.42395178, 0.55862494, 0.74849357], - [0.4305964, 0.56276546, 0.74956387], - [0.4372044, 0.56691228, 0.75068412], - [0.4437909, 0.57106468, 0.75183427], - [0.45035117, 0.5752235, 0.75302312], - [0.45687824, 0.57938983, 0.75426297], - [0.46339713, 0.58356191, 0.75551816], - [0.46988778, 0.58774195, 0.75682037], - [0.47635605, 0.59192986, 0.75816245], - [0.48281101, 0.5961252, 0.75953212], - [0.4892374, 0.60032986, 0.76095418], - [0.49566225, 0.60454154, 0.76238852], - [0.50206137, 0.60876307, 0.76387371], - [0.50845128, 0.61299312, 0.76538551], - [0.5148258, 0.61723272, 0.76693475], - [0.52118385, 0.62148236, 0.76852436], - [0.52753571, 0.62574126, 0.77013939], - [0.53386831, 0.63001125, 0.77180152], - [0.54020159, 0.63429038, 0.7734803], - [0.54651272, 0.63858165, 0.77521306], - [0.55282975, 0.64288207, 0.77695608], - [0.55912585, 0.64719519, 0.77875327], - [0.56542599, 0.65151828, 0.78056551], - [0.57170924, 0.65585426, 0.78242747], - [0.57799572, 0.6602009, 0.78430751], - [0.58426817, 0.66456073, 0.78623458], - [0.590544, 0.66893178, 0.78818117], - [0.59680758, 0.67331643, 0.79017369], - [0.60307553, 0.67771273, 0.79218572], - [0.60934065, 0.68212194, 0.79422987], - [0.61559495, 0.68654548, 0.7963202], - [0.62185554, 0.69098125, 0.79842918], - [0.62810662, 0.69543176, 0.80058381], - [0.63436425, 0.69989499, 0.80275812], - [0.64061445, 0.70437326, 0.80497621], - [0.6468706, 0.70886488, 0.80721641], - [0.65312213, 0.7133717, 0.80949719], - [0.65937818, 0.71789261, 0.81180392], - [0.66563334, 0.72242871, 0.81414642], - [0.67189155, 0.72697967, 0.81651872], - [0.67815314, 0.73154569, 0.81892097], - [0.68441395, 0.73612771, 0.82136094], - [0.69068321, 0.74072452, 0.82382353], - [0.69694776, 0.7453385, 0.82633199], - [0.70322431, 0.74996721, 0.8288583], - [0.70949595, 0.75461368, 0.83143221], - [0.7157774, 0.75927574, 0.83402904], - [0.72206299, 0.76395461, 0.83665922], - [0.72835227, 0.76865061, 0.8393242], - [0.73465238, 0.7733628, 0.84201224], - [0.74094862, 0.77809393, 0.84474951], - [0.74725683, 0.78284158, 0.84750915], - [0.75357103, 0.78760701, 0.85030217], - [0.75988961, 0.79239077, 0.85313207], - [0.76621987, 0.79719185, 0.85598668], - [0.77255045, 0.8020125, 0.85888658], - [0.77889241, 0.80685102, 0.86181298], - [0.78524572, 0.81170768, 0.86476656], - [0.79159841, 0.81658489, 0.86776906], - [0.79796459, 0.82148036, 0.8707962], - [0.80434168, 0.82639479, 0.87385315], - [0.8107221, 0.83132983, 0.87695392], - [0.81711301, 0.8362844, 0.88008641], - [0.82351479, 0.84125863, 0.88325045], - [0.82992772, 0.84625263, 0.88644594], - [0.83634359, 0.85126806, 0.8896878], - [0.84277295, 0.85630293, 0.89295721], - [0.84921192, 0.86135782, 0.89626076], - [0.85566206, 0.866432, 0.89959467], - [0.86211514, 0.87152627, 0.90297183], - [0.86857483, 0.87663856, 0.90638248], - [0.87504231, 0.88176648, 0.90981938], - [0.88151194, 0.88690782, 0.91328493], - [0.88797938, 0.89205857, 0.91677544], - [0.89443865, 0.89721298, 0.9202854], - [0.90088204, 0.90236294, 0.92380601], - [0.90729768, 0.90749778, 0.92732797], - [0.91367037, 0.91260329, 0.93083814], - [0.91998105, 0.91766106, 0.93431861], - [0.92620596, 0.92264789, 0.93774647], - [0.93231683, 0.9275351, 0.94109192], - [0.93827772, 0.9322888, 0.94432312], - [0.94404755, 0.93686925, 0.94740137], - [0.94958284, 0.94123072, 0.95027696], - [0.95482682, 0.9453245, 0.95291103], - [0.9597248, 0.94909728, 0.95525103], - [0.96422552, 0.95249273, 0.95723271], - [0.96826161, 0.95545812, 0.95882188], - [0.97178458, 0.95793984, 0.95995705], - [0.97474105, 0.95989142, 0.96059997], - [0.97708604, 0.96127366, 0.96071853], - [0.97877855, 0.96205832, 0.96030095], - [0.97978484, 0.96222949, 0.95935496], - [0.9805997, 0.96155216, 0.95813083], - [0.98152619, 0.95993719, 0.95639322], - [0.9819726, 0.95766608, 0.95399269], - [0.98191855, 0.9547873, 0.95098107], - [0.98138514, 0.95134771, 0.94740644], - [0.98040845, 0.94739906, 0.94332125], - [0.97902107, 0.94300131, 0.93878672], - [0.97729348, 0.93820409, 0.93385135], - [0.9752533, 0.933073, 0.92858252], - [0.97297834, 0.92765261, 0.92302309], - [0.97049104, 0.92200317, 0.91723505], - [0.96784372, 0.91616744, 0.91126063], - [0.96507281, 0.91018664, 0.90514124], - [0.96222034, 0.90409203, 0.89890756], - [0.9593079, 0.89791478, 0.89259122], - [0.95635626, 0.89167908, 0.88621654], - [0.95338303, 0.88540373, 0.87980238], - [0.95040174, 0.87910333, 0.87336339], - [0.94742246, 0.87278899, 0.86691076], - [0.94445249, 0.86646893, 0.86045277], - [0.94150476, 0.86014606, 0.85399191], - [0.93857394, 0.85382798, 0.84753642], - [0.93566206, 0.84751766, 0.84108935], - [0.93277194, 0.8412164, 0.83465197], - [0.92990106, 0.83492672, 0.82822708], - [0.92704736, 0.82865028, 0.82181656], - [0.92422703, 0.82238092, 0.81541333], - [0.92142581, 0.81612448, 0.80902415], - [0.91864501, 0.80988032, 0.80264838], - [0.91587578, 0.80365187, 0.79629001], - [0.9131367, 0.79743115, 0.78994], - [0.91041602, 0.79122265, 0.78360361], - [0.90771071, 0.78502727, 0.77728196], - [0.90501581, 0.77884674, 0.7709771], - [0.90235365, 0.77267117, 0.76467793], - [0.8997019, 0.76650962, 0.75839484], - [0.89705346, 0.76036481, 0.752131], - [0.89444021, 0.75422253, 0.74587047], - [0.89183355, 0.74809474, 0.73962689], - [0.88923216, 0.74198168, 0.73340061], - [0.88665892, 0.73587283, 0.72717995], - [0.88408839, 0.72977904, 0.72097718], - [0.88153537, 0.72369332, 0.71478461], - [0.87899389, 0.7176179, 0.70860487], - [0.87645157, 0.71155805, 0.7024439], - [0.8739399, 0.70549893, 0.6962854], - [0.87142626, 0.6994551, 0.69014561], - [0.8689268, 0.69341868, 0.68401597], - [0.86643562, 0.687392, 0.67789917], - [0.86394434, 0.68137863, 0.67179927], - [0.86147586, 0.67536728, 0.665704], - [0.85899928, 0.66937226, 0.6596292], - [0.85654668, 0.66337773, 0.6535577], - [0.85408818, 0.65739772, 0.64750494], - [0.85164413, 0.65142189, 0.64145983], - [0.84920091, 0.6454565, 0.63542932], - [0.84676427, 0.63949827, 0.62941], - [0.84433231, 0.63354773, 0.62340261], - [0.84190106, 0.62760645, 0.61740899], - [0.83947935, 0.62166951, 0.61142404], - [0.8370538, 0.61574332, 0.60545478], - [0.83463975, 0.60981951, 0.59949247], - [0.83221877, 0.60390724, 0.593547], - [0.82980985, 0.59799607, 0.58760751], - [0.82740268, 0.59209095, 0.58167944], - [0.82498638, 0.5861973, 0.57576866], - [0.82258181, 0.5803034, 0.56986307], - [0.82016611, 0.57442123, 0.56397539], - [0.81776305, 0.56853725, 0.55809173], - [0.81534551, 0.56266602, 0.55222741], - [0.81294293, 0.55679056, 0.5463651], - [0.81052113, 0.55092973, 0.54052443], - [0.80811509, 0.54506305, 0.53468464], - [0.80568952, 0.53921036, 0.52886622], - [0.80327506, 0.53335335, 0.52305077], - [0.80084727, 0.52750583, 0.51725256], - [0.79842217, 0.5216578, 0.51146173], - [0.79599382, 0.51581223, 0.50568155], - [0.79355781, 0.50997127, 0.49991444], - [0.79112596, 0.50412707, 0.49415289], - [0.78867442, 0.49829386, 0.48841129], - [0.7862306, 0.49245398, 0.48267247], - [0.7837687, 0.48662309, 0.47695216], - [0.78130809, 0.4807883, 0.47123805], - [0.77884467, 0.47495151, 0.46553236], - [0.77636283, 0.46912235, 0.45984473], - [0.77388383, 0.46328617, 0.45416141], - [0.77138912, 0.45745466, 0.44849398], - [0.76888874, 0.45162042, 0.44283573], - [0.76638802, 0.44577901, 0.43718292], - [0.76386116, 0.43994762, 0.43155211], - [0.76133542, 0.43410655, 0.42592523], - [0.75880631, 0.42825801, 0.42030488], - [0.75624913, 0.42241905, 0.41470727], - [0.7536919, 0.41656866, 0.40911347], - [0.75112748, 0.41071104, 0.40352792], - [0.74854331, 0.40485474, 0.3979589], - [0.74594723, 0.39899309, 0.39240088], - [0.74334332, 0.39312199, 0.38685075], - [0.74073277, 0.38723941, 0.3813074], - [0.73809409, 0.38136133, 0.37578553], - [0.73544692, 0.37547129, 0.37027123], - [0.73278943, 0.36956954, 0.36476549], - [0.73011829, 0.36365761, 0.35927038], - [0.72743485, 0.35773314, 0.35378465], - [0.72472722, 0.35180504, 0.34831662], - [0.72200473, 0.34586421, 0.34285937], - [0.71927052, 0.33990649, 0.33741033], - [0.71652049, 0.33393396, 0.33197219], - [0.71375362, 0.32794602, 0.32654545], - [0.71096951, 0.32194148, 0.32113016], - [0.70816772, 0.31591904, 0.31572637], - [0.70534784, 0.30987734, 0.31033414], - [0.70250944, 0.30381489, 0.30495353], - [0.69965211, 0.2977301, 0.2995846], - [0.6967754, 0.29162126, 0.29422741], - [0.69388446, 0.28548074, 0.28887769], - [0.69097561, 0.2793096, 0.28353795], - [0.68803513, 0.27311993, 0.27821876], - [0.6850794, 0.26689144, 0.27290694], - [0.682108, 0.26062114, 0.26760246], - [0.67911013, 0.2543177, 0.26231367], - [0.67609393, 0.24796818, 0.25703372], - [0.67305921, 0.24156846, 0.25176238], - [0.67000176, 0.23511902, 0.24650278], - [0.66693423, 0.22859879, 0.24124404], - [0.6638441, 0.22201742, 0.2359961], - [0.66080672, 0.21526712, 0.23069468] -] - - -_icefire_lut = [ - [0.73936227, 0.90443867, 0.85757238], - [0.72888063, 0.89639109, 0.85488394], - [0.71834255, 0.88842162, 0.8521605], - [0.70773866, 0.88052939, 0.849422], - [0.69706215, 0.87271313, 0.84668315], - [0.68629021, 0.86497329, 0.84398721], - [0.67543654, 0.85730617, 0.84130969], - [0.66448539, 0.84971123, 0.83868005], - [0.65342679, 0.84218728, 0.83611512], - [0.64231804, 0.83471867, 0.83358584], - [0.63117745, 0.827294, 0.83113431], - [0.62000484, 0.81991069, 0.82876741], - [0.60879435, 0.81256797, 0.82648905], - [0.59754118, 0.80526458, 0.82430414], - [0.58624247, 0.79799884, 0.82221573], - [0.57489525, 0.7907688, 0.82022901], - [0.56349779, 0.78357215, 0.81834861], - [0.55204294, 0.77640827, 0.81657563], - [0.54052516, 0.76927562, 0.81491462], - [0.52894085, 0.76217215, 0.81336913], - [0.51728854, 0.75509528, 0.81194156], - [0.50555676, 0.74804469, 0.81063503], - [0.49373871, 0.7410187, 0.80945242], - [0.48183174, 0.73401449, 0.80839675], - [0.46982587, 0.72703075, 0.80747097], - [0.45770893, 0.72006648, 0.80667756], - [0.44547249, 0.71311941, 0.80601991], - [0.43318643, 0.70617126, 0.80549278], - [0.42110294, 0.69916972, 0.80506683], - [0.40925101, 0.69211059, 0.80473246], - [0.3976693, 0.68498786, 0.80448272], - [0.38632002, 0.67781125, 0.80431024], - [0.37523981, 0.67057537, 0.80420832], - [0.36442578, 0.66328229, 0.80417474], - [0.35385939, 0.65593699, 0.80420591], - [0.34358916, 0.64853177, 0.8043], - [0.33355526, 0.64107876, 0.80445484], - [0.32383062, 0.63356578, 0.80467091], - [0.31434372, 0.62600624, 0.8049475], - [0.30516161, 0.618389, 0.80528692], - [0.29623491, 0.61072284, 0.80569021], - [0.28759072, 0.60300319, 0.80616055], - [0.27923924, 0.59522877, 0.80669803], - [0.27114651, 0.5874047, 0.80730545], - [0.26337153, 0.57952055, 0.80799113], - [0.25588696, 0.57157984, 0.80875922], - [0.248686, 0.56358255, 0.80961366], - [0.24180668, 0.55552289, 0.81055123], - [0.23526251, 0.54739477, 0.8115939], - [0.22921445, 0.53918506, 0.81267292], - [0.22397687, 0.53086094, 0.8137141], - [0.21977058, 0.52241482, 0.81457651], - [0.21658989, 0.51384321, 0.81528511], - [0.21452772, 0.50514155, 0.81577278], - [0.21372783, 0.49630865, 0.81589566], - [0.21409503, 0.48734861, 0.81566163], - [0.2157176, 0.47827123, 0.81487615], - [0.21842857, 0.46909168, 0.81351614], - [0.22211705, 0.45983212, 0.81146983], - [0.22665681, 0.45052233, 0.80860217], - [0.23176013, 0.44119137, 0.80494325], - [0.23727775, 0.43187704, 0.80038017], - [0.24298285, 0.42261123, 0.79493267], - [0.24865068, 0.41341842, 0.78869164], - [0.25423116, 0.40433127, 0.78155831], - [0.25950239, 0.39535521, 0.77376848], - [0.2644736, 0.38651212, 0.76524809], - [0.26901584, 0.37779582, 0.75621942], - [0.27318141, 0.36922056, 0.746605], - [0.27690355, 0.3607736, 0.73659374], - [0.28023585, 0.35244234, 0.72622103], - [0.28306009, 0.34438449, 0.71500731], - [0.28535896, 0.33660243, 0.70303975], - [0.28708711, 0.32912157, 0.69034504], - [0.28816354, 0.32200604, 0.67684067], - [0.28862749, 0.31519824, 0.66278813], - [0.28847904, 0.30869064, 0.6482815], - [0.28770912, 0.30250126, 0.63331265], - [0.28640325, 0.29655509, 0.61811374], - [0.28458943, 0.29082155, 0.60280913], - [0.28233561, 0.28527482, 0.58742866], - [0.27967038, 0.2798938, 0.57204225], - [0.27665361, 0.27465357, 0.55667809], - [0.27332564, 0.2695165, 0.54145387], - [0.26973851, 0.26447054, 0.52634916], - [0.2659204, 0.25949691, 0.511417], - [0.26190145, 0.25458123, 0.49668768], - [0.2577151, 0.24971691, 0.48214874], - [0.25337618, 0.24490494, 0.46778758], - [0.24890842, 0.24013332, 0.45363816], - [0.24433654, 0.23539226, 0.4397245], - [0.23967922, 0.23067729, 0.4260591], - [0.23495608, 0.22598894, 0.41262952], - [0.23018113, 0.22132414, 0.39945577], - [0.22534609, 0.21670847, 0.38645794], - [0.22048761, 0.21211723, 0.37372555], - [0.2156198, 0.20755389, 0.36125301], - [0.21074637, 0.20302717, 0.34903192], - [0.20586893, 0.19855368, 0.33701661], - [0.20101757, 0.19411573, 0.32529173], - [0.19619947, 0.18972425, 0.31383846], - [0.19140726, 0.18540157, 0.30260777], - [0.1866769, 0.1811332, 0.29166583], - [0.18201285, 0.17694992, 0.28088776], - [0.17745228, 0.17282141, 0.27044211], - [0.17300684, 0.16876921, 0.26024893], - [0.16868273, 0.16479861, 0.25034479], - [0.16448691, 0.16091728, 0.24075373], - [0.16043195, 0.15714351, 0.23141745], - [0.15652427, 0.15348248, 0.22238175], - [0.15277065, 0.14994111, 0.21368395], - [0.14918274, 0.14653431, 0.20529486], - [0.14577095, 0.14327403, 0.19720829], - [0.14254381, 0.14016944, 0.18944326], - [0.13951035, 0.13723063, 0.18201072], - [0.13667798, 0.13446606, 0.17493774], - [0.13405762, 0.13188822, 0.16820842], - [0.13165767, 0.12950667, 0.16183275], - [0.12948748, 0.12733187, 0.15580631], - [0.12755435, 0.1253723, 0.15014098], - [0.12586516, 0.12363617, 0.1448459], - [0.12442647, 0.12213143, 0.13992571], - [0.12324241, 0.12086419, 0.13539995], - [0.12232067, 0.11984278, 0.13124644], - [0.12166209, 0.11907077, 0.12749671], - [0.12126982, 0.11855309, 0.12415079], - [0.12114244, 0.11829179, 0.1212385], - [0.12127766, 0.11828837, 0.11878534], - [0.12284806, 0.1179729, 0.11772022], - [0.12619498, 0.11721796, 0.11770203], - [0.129968, 0.11663788, 0.11792377], - [0.13410011, 0.11625146, 0.11839138], - [0.13855459, 0.11606618, 0.11910584], - [0.14333775, 0.11607038, 0.1200606], - [0.148417, 0.11626929, 0.12125453], - [0.15377389, 0.11666192, 0.12268364], - [0.15941427, 0.11723486, 0.12433911], - [0.16533376, 0.11797856, 0.12621303], - [0.17152547, 0.11888403, 0.12829735], - [0.17797765, 0.11994436, 0.13058435], - [0.18468769, 0.12114722, 0.13306426], - [0.19165663, 0.12247737, 0.13572616], - [0.19884415, 0.12394381, 0.1385669], - [0.20627181, 0.12551883, 0.14157124], - [0.21394877, 0.12718055, 0.14472604], - [0.22184572, 0.12893119, 0.14802579], - [0.22994394, 0.13076731, 0.15146314], - [0.23823937, 0.13267611, 0.15502793], - [0.24676041, 0.13462172, 0.15870321], - [0.25546457, 0.13661751, 0.16248722], - [0.26433628, 0.13865956, 0.16637301], - [0.27341345, 0.14070412, 0.17034221], - [0.28264773, 0.14277192, 0.1743957], - [0.29202272, 0.14486161, 0.17852793], - [0.30159648, 0.14691224, 0.1827169], - [0.31129002, 0.14897583, 0.18695213], - [0.32111555, 0.15103351, 0.19119629], - [0.33107961, 0.1530674, 0.19543758], - [0.34119892, 0.15504762, 0.1996803], - [0.35142388, 0.15701131, 0.20389086], - [0.36178937, 0.1589124, 0.20807639], - [0.37229381, 0.16073993, 0.21223189], - [0.38288348, 0.16254006, 0.2163249], - [0.39359592, 0.16426336, 0.22036577], - [0.40444332, 0.16588767, 0.22434027], - [0.41537995, 0.16745325, 0.2282297], - [0.42640867, 0.16894939, 0.23202755], - [0.43754706, 0.17034847, 0.23572899], - [0.44878564, 0.1716535, 0.23932344], - [0.4601126, 0.17287365, 0.24278607], - [0.47151732, 0.17401641, 0.24610337], - [0.48300689, 0.17506676, 0.2492737], - [0.49458302, 0.17601892, 0.25227688], - [0.50623876, 0.17687777, 0.255096], - [0.5179623, 0.17765528, 0.2577162], - [0.52975234, 0.17835232, 0.2601134], - [0.54159776, 0.17898292, 0.26226847], - [0.55348804, 0.17956232, 0.26416003], - [0.56541729, 0.18010175, 0.26575971], - [0.57736669, 0.180631, 0.26704888], - [0.58932081, 0.18117827, 0.26800409], - [0.60127582, 0.18175888, 0.26858488], - [0.61319563, 0.1824336, 0.2687872], - [0.62506376, 0.18324015, 0.26858301], - [0.63681202, 0.18430173, 0.26795276], - [0.64842603, 0.18565472, 0.26689463], - [0.65988195, 0.18734638, 0.26543435], - [0.67111966, 0.18948885, 0.26357955], - [0.68209194, 0.19216636, 0.26137175], - [0.69281185, 0.19535326, 0.25887063], - [0.70335022, 0.19891271, 0.25617971], - [0.71375229, 0.20276438, 0.25331365], - [0.72401436, 0.20691287, 0.25027366], - [0.73407638, 0.21145051, 0.24710661], - [0.74396983, 0.21631913, 0.24380715], - [0.75361506, 0.22163653, 0.24043996], - [0.7630579, 0.22731637, 0.23700095], - [0.77222228, 0.23346231, 0.23356628], - [0.78115441, 0.23998404, 0.23013825], - [0.78979746, 0.24694858, 0.22678822], - [0.79819286, 0.25427223, 0.22352658], - [0.80630444, 0.26198807, 0.22040877], - [0.81417437, 0.27001406, 0.21744645], - [0.82177364, 0.27837336, 0.21468316], - [0.82915955, 0.28696963, 0.21210766], - [0.83628628, 0.2958499, 0.20977813], - [0.84322168, 0.30491136, 0.20766435], - [0.84995458, 0.31415945, 0.2057863], - [0.85648867, 0.32358058, 0.20415327], - [0.86286243, 0.33312058, 0.20274969], - [0.86908321, 0.34276705, 0.20157271], - [0.87512876, 0.3525416, 0.20064949], - [0.88100349, 0.36243385, 0.19999078], - [0.8866469, 0.37249496, 0.1997976], - [0.89203964, 0.38273475, 0.20013431], - [0.89713496, 0.39318156, 0.20121514], - [0.90195099, 0.40380687, 0.20301555], - [0.90648379, 0.41460191, 0.20558847], - [0.9106967, 0.42557857, 0.20918529], - [0.91463791, 0.43668557, 0.21367954], - [0.91830723, 0.44790913, 0.21916352], - [0.92171507, 0.45922856, 0.22568002], - [0.92491786, 0.4705936, 0.23308207], - [0.92790792, 0.48200153, 0.24145932], - [0.93073701, 0.49341219, 0.25065486], - [0.93343918, 0.5048017, 0.26056148], - [0.93602064, 0.51616486, 0.27118485], - [0.93850535, 0.52748892, 0.28242464], - [0.94092933, 0.53875462, 0.29416042], - [0.94330011, 0.5499628, 0.30634189], - [0.94563159, 0.56110987, 0.31891624], - [0.94792955, 0.57219822, 0.33184256], - [0.95020929, 0.5832232, 0.34508419], - [0.95247324, 0.59419035, 0.35859866], - [0.95471709, 0.60510869, 0.37236035], - [0.95698411, 0.61595766, 0.38629631], - [0.95923863, 0.62676473, 0.40043317], - [0.9615041, 0.6375203, 0.41474106], - [0.96371553, 0.64826619, 0.42928335], - [0.96591497, 0.65899621, 0.44380444], - [0.96809871, 0.66971662, 0.45830232], - [0.9702495, 0.6804394, 0.47280492], - [0.9723881, 0.69115622, 0.48729272], - [0.97450723, 0.70187358, 0.50178034], - [0.9766108, 0.712592, 0.51626837], - [0.97871716, 0.72330511, 0.53074053], - [0.98082222, 0.73401769, 0.54520694], - [0.9829001, 0.74474445, 0.5597019], - [0.98497466, 0.75547635, 0.57420239], - [0.98705581, 0.76621129, 0.58870185], - [0.98913325, 0.77695637, 0.60321626], - [0.99119918, 0.78771716, 0.61775821], - [0.9932672, 0.79848979, 0.63231691], - [0.99535958, 0.80926704, 0.64687278], - [0.99740544, 0.82008078, 0.66150571], - [0.9992197, 0.83100723, 0.6764127] -] - - -_luts = [_rocket_lut, _mako_lut, _vlag_lut, _icefire_lut] -_names = ["rocket", "mako", "vlag", "icefire"] - -for _lut, _name in zip(_luts, _names): - - _cmap = colors.ListedColormap(_lut, _name) - locals()[_name] = _cmap - - _cmap_r = colors.ListedColormap(_lut[::-1], _name + "_r") - locals()[_name + "_r"] = _cmap_r - - mpl_cm.register(_cmap, name=_name) - mpl_cm.register(_cmap_r, name=_name + "_r") diff --git a/pydeeptools/deeptools/correlation.py b/pydeeptools/deeptools/correlation.py index 56b8d91d2f..b722d3a00f 100755 --- a/pydeeptools/deeptools/correlation.py +++ b/pydeeptools/deeptools/correlation.py @@ -92,8 +92,11 @@ def load_matrix(self, matrix_file): "and plotting\n".format(num_nam)) self.matrix = np.ma.compress_rows(np.ma.masked_invalid(self.matrix)) - - self.labels = list(map(toString, _ma['labels'])) + # Since deeptools 4.0 the labels are encoded and would need to be decoded. + if _ma['labels'].dtype == np.uint8: + self.labels = [bytes(x).decode('utf-8').rstrip('\x00') for x in _ma['labels']] + else: + self.labels = list(map(toString, _ma['labels'])) assert len(self.labels) == self.matrix.shape[1], "ERROR, length of labels is not equal " \ "to length of matrix samples" diff --git a/pydeeptools/deeptools/heatmapper_utilities.py b/pydeeptools/deeptools/heatmapper_utilities.py index e63dfb0226..de7696cafe 100644 --- a/pydeeptools/deeptools/heatmapper_utilities.py +++ b/pydeeptools/deeptools/heatmapper_utilities.py @@ -3,7 +3,6 @@ matplotlib.use('Agg') matplotlib.rcParams['pdf.fonttype'] = 42 matplotlib.rcParams['svg.fonttype'] = 'none' -from deeptools import cm # noqa: F401 import matplotlib.colors as pltcolors import plotly.graph_objs as go diff --git a/pydeeptools/deeptools/multiBamSummary2.py b/pydeeptools/deeptools/multiBamSummary2.py index a42eeff8fb..5f08390e4a 100644 --- a/pydeeptools/deeptools/multiBamSummary2.py +++ b/pydeeptools/deeptools/multiBamSummary2.py @@ -206,9 +206,11 @@ def process_args(args=None): args.labels = smartLabels(args.bamfiles) else: args.labels = [os.path.basename(x) for x in args.bamfiles] - + if not args.outFileName: + print("Please provide an output file name.") + exit(0) if not args.BED: - args.BED = "None" + args.BED = [] if not args.region: args.region = [] if not args.blackListFileName: @@ -268,73 +270,3 @@ def main(args=None): args.exonID, args.transcript_id_designator ) - - # if 'BED' in args: - # bed_regions = args.BED - # else: - # bed_regions = None - - # if len(args.bamfiles) == 1 and not (args.outRawCounts or args.scalingFactors): - # sys.stderr.write("You've input a single BAM file and not specified " - # "--outRawCounts or --scalingFactors. 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, - # genomeChunkSize=args.genomeChunkSize, - # 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... - # if args.outFileName: - # f = open(args.outFileName, "wb") - # np.savez_compressed(f, - # matrix=num_reads_per_bin, - # labels=args.labels) - # f.close() - - # if args.scalingFactors: - # f = open(args.scalingFactors, 'w') - # f.write("sample\tscalingFactor\n") - # scalingFactors = countR.estimateSizeFactors(num_reads_per_bin) - # for sample, scalingFactor in zip(args.labels, scalingFactors): - # f.write("{}\t{:6.4f}\n".format(sample, scalingFactor)) - # 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() diff --git a/pydeeptools/deeptools/parserCommon.py b/pydeeptools/deeptools/parserCommon.py index 9849d9c431..ac676d9e1d 100755 --- a/pydeeptools/deeptools/parserCommon.py +++ b/pydeeptools/deeptools/parserCommon.py @@ -660,7 +660,7 @@ def heatmapperOptionalArgs(mode=['heatmap', 'profile'][0]): 'notation.') import matplotlib.pyplot as plt - color_options = "', '".join([x for x in plt.colormaps() if not x.endswith('_r')]) + color_options = "', '".join([x for x in plt.colormaps()]) optional.add_argument( '--colorMap', diff --git a/pydeeptools/deeptools/plotCorrelation.py b/pydeeptools/deeptools/plotCorrelation.py index 988cf559e2..b686b00072 100644 --- a/pydeeptools/deeptools/plotCorrelation.py +++ b/pydeeptools/deeptools/plotCorrelation.py @@ -8,7 +8,6 @@ matplotlib.use('Agg') matplotlib.rcParams['pdf.fonttype'] = 42 matplotlib.rcParams['svg.fonttype'] = 'none' -from deeptools import cm # noqa: F401 import matplotlib.pyplot as plt from importlib.metadata import version from deeptools.correlation import Correlation diff --git a/pydeeptools/deeptools/plotCoverage.py b/pydeeptools/deeptools/plotCoverage.py index 464375c7a3..63f461201a 100755 --- a/pydeeptools/deeptools/plotCoverage.py +++ b/pydeeptools/deeptools/plotCoverage.py @@ -10,7 +10,6 @@ matplotlib.use('Agg') matplotlib.rcParams['pdf.fonttype'] = 42 matplotlib.rcParams['svg.fonttype'] = 'none' -from deeptools import cm # noqa: F401 import matplotlib.pyplot as plt import plotly.offline as py import plotly.graph_objs as go diff --git a/pydeeptools/deeptools/plotEnrichment.py b/pydeeptools/deeptools/plotEnrichment.py index bbd53f90d5..9ac68c21a4 100755 --- a/pydeeptools/deeptools/plotEnrichment.py +++ b/pydeeptools/deeptools/plotEnrichment.py @@ -8,7 +8,6 @@ matplotlib.use('Agg') matplotlib.rcParams['pdf.fonttype'] = 42 matplotlib.rcParams['svg.fonttype'] = 'none' -from deeptools import cm # noqa: F401 import matplotlib.pyplot as plt import matplotlib.gridspec as gridspec diff --git a/pydeeptools/deeptools/plotFingerprint.py b/pydeeptools/deeptools/plotFingerprint.py index 0cb4aaf743..89a0210236 100755 --- a/pydeeptools/deeptools/plotFingerprint.py +++ b/pydeeptools/deeptools/plotFingerprint.py @@ -2,8 +2,15 @@ # -*- coding: utf-8 -*- import sys +<<<<<<< HEAD import argparse import numpy as np +======= +import matplotlib +matplotlib.use('Agg') +matplotlib.rcParams['pdf.fonttype'] = 42 +matplotlib.rcParams['svg.fonttype'] = 'none' +>>>>>>> 4.0.0 import matplotlib.pyplot as plt from scipy import interpolate from scipy.stats import poisson diff --git a/pydeeptools/deeptools/plotHeatmap.py b/pydeeptools/deeptools/plotHeatmap.py index a2149f8299..c2f1a3dbb4 100755 --- a/pydeeptools/deeptools/plotHeatmap.py +++ b/pydeeptools/deeptools/plotHeatmap.py @@ -19,7 +19,6 @@ import plotly.graph_objs as go # own modules -from deeptools import cm # noqa: F401 from deeptools import parserCommon from deeptools import heatmapper from deeptools.heatmapper_utilities import plot_single, plotly_single diff --git a/pydeeptools/deeptools/plotPCA.py b/pydeeptools/deeptools/plotPCA.py index bc17ed32b1..3417486d8b 100644 --- a/pydeeptools/deeptools/plotPCA.py +++ b/pydeeptools/deeptools/plotPCA.py @@ -7,7 +7,6 @@ matplotlib.use('Agg') matplotlib.rcParams['pdf.fonttype'] = 42 matplotlib.rcParams['svg.fonttype'] = 'none' -from deeptools import cm # noqa: F401 from importlib.metadata import version from deeptools.correlation import Correlation from deeptools.parserCommon import writableFile diff --git a/pydeeptools/deeptools/plotProfile.py b/pydeeptools/deeptools/plotProfile.py index 7497875f20..35b0a5684b 100755 --- a/pydeeptools/deeptools/plotProfile.py +++ b/pydeeptools/deeptools/plotProfile.py @@ -11,7 +11,6 @@ matplotlib.use('Agg') matplotlib.rcParams['pdf.fonttype'] = 42 matplotlib.rcParams['svg.fonttype'] = 'none' -import deeptools.cm # noqa: F401 import matplotlib.pyplot as plt from matplotlib.font_manager import FontProperties from matplotlib import colors as pltcolors diff --git a/pydeeptools/deeptools/test/test_alignmentseive.py b/pydeeptools/deeptools/test/test_alignmentseive.py new file mode 100644 index 0000000000..39e36c1321 --- /dev/null +++ b/pydeeptools/deeptools/test/test_alignmentseive.py @@ -0,0 +1,83 @@ +import deeptools.alignmentSieve as aln_seive + +import os.path +from os import unlink + +ROOT = os.path.dirname(os.path.abspath(__file__)) + "/test_data/" +BAMFILE_IN = ROOT + "paired_chr2L.bam" +CRAMFILE_IN = ROOT + "paired_chr2L.cram" +FILTER_METRICS_FILE = ROOT + "alignmentSieve.txt" +BED_OUT = ROOT + "alignmentSieve.bed" +BAMFILE_OUT = ROOT + "alignmentSieve.bam" +BAMFILE_OUT2 = ROOT + "alignmentSieve2.bam" +BAMFILE_OUT3 = ROOT + "alignmentSieve3.bam" + + +def test_minimum_mapping_quality_filter_metric(): + """ + Test minimal command line args for alignement sieve + """ + outfile = '/tmp/test_bam.bam' + filter_metric_file = '/tmp/test_metrics.txt' + args = "--bam {} -o {} --minMappingQuality 10 --filterMetrics {}".format(BAMFILE_IN, outfile, filter_metric_file).split() + aln_seive.main(args) + + _foo = open(filter_metric_file, "r") + resp = _foo.readlines()[2] + _foo.close() + expected = 'paired_chr2L.bam\t8440\t12644\n' + assert expected in resp, f"'{expected}' not found in '{resp}'" + + bam_file_size = os.path.getsize(BAMFILE_OUT) + expected_file_size = os.path.getsize(outfile) + size_tolerance = 5000 + size_difference = abs(bam_file_size - expected_file_size) + assert size_difference <= size_tolerance, "File size do not match" + unlink(outfile) + unlink(filter_metric_file) + + +def test_with_bed_output_along_with_shifts(): + """ + Tests Alignment seive with shifts and output BED file + """ + output_bed_file = "/tmp/aln_seive.bed" + args = "--bam {} -o {} --minMappingQuality 10 --BED --shift 1 -2 3 -4".format(BAMFILE_IN, output_bed_file).split() + aln_seive.main(args) + with open(output_bed_file, "r") as _foo: + result = len(_foo.readlines()) + _expected = 4261 + assert result == _expected, "No of lines in BED files differ" + unlink(output_bed_file) + + +def test_with_bam_output_with_shifts(): + """ + Tests Alignment seive with shifts and output BAM file + """ + output_bam_file = "/tmp/aln_seive.bam" + args = "--bam {} -o {} --minMappingQuality 10 --shift 1 -2 3 -4".format(BAMFILE_IN, output_bam_file).split() + aln_seive.main(args) + + bam_file_size = os.path.getsize(BAMFILE_OUT2) + expected_file_size = os.path.getsize(output_bam_file) + size_tolerance = 5000 + size_difference = abs(bam_file_size - expected_file_size) + assert size_difference <= size_tolerance, "File sizes do not match" + unlink(output_bam_file) + + +def test_with_cram_output_with_shifts(): + """ + Tests Alignment seive with CRAM input along with shifts + """ + output_bam_file = "/tmp/aln_seive2.bam" + args = "--bam {} -o {} --minMappingQuality 10 --shift 1 -2 3 -4".format(BAMFILE_IN, output_bam_file).split() + aln_seive.main(args) + + bam_file_size = os.path.getsize(BAMFILE_OUT3) + expected_file_size = os.path.getsize(output_bam_file) + size_tolerance = 5000 + size_difference = abs(bam_file_size - expected_file_size) + assert size_difference <= size_tolerance, "File sizes do not match" + unlink(output_bam_file) diff --git a/pydeeptools/deeptools/test/test_bamPEFragmentSize.py b/pydeeptools/deeptools/test/test_bamPEFragmentSize.py new file mode 100644 index 0000000000..f06ed5da47 --- /dev/null +++ b/pydeeptools/deeptools/test/test_bamPEFragmentSize.py @@ -0,0 +1,45 @@ +import deeptools.bamPEFragmentSize +from matplotlib.testing.compare import compare_images +import os.path +import filecmp +from os import unlink +from tempfile import NamedTemporaryFile + +ROOT = os.path.dirname(os.path.abspath(__file__)) + "/test_data" + + +def test_bamPEFragmentSize_histogram(): + """ + Test histogram plot for bamPEFragmentSize + """ + outfile = '/tmp/test_histogram.png' + args = "--bamfiles {}/bowtie2_test1.bam --samplesLabel bowtie2_test1.bam --plotFileFormat png --plotTitle Test-Plot --histogram {}".format(ROOT, outfile).split() + deeptools.bamPEFragmentSize.main(args) + + res = compare_images(ROOT + '/bamPEFragmentSize_histogram_result1.png', outfile, 10) + assert res is None, res + unlink(outfile) + +def test_bamPEFragmentSize_fr_sizes(): + """ + Test fragment length information for bamPEFragmentSize + """ + out_lengths = '/tmp/test_raw_frag_lengths.txt' + out_metrics = '/tmp/test_metrics_table.txt' + args = "--bamfiles {}/bowtie2_test1.bam --outRawFragmentLengths {} --table {}".format(ROOT, out_lengths, out_metrics).split() + deeptools.bamPEFragmentSize.main(args) + + l = open(out_lengths, 'r') + l_resp = l.readlines() + l.close() + l_expected = ['241\t1', '242\t1', '251\t1'] + matches = [expected for expected in l_expected if any(expected in resp for resp in l_resp)] + assert matches == l_expected + + m = open(out_metrics, 'r') + m_resp = m.readlines()[1] + m.close() + m_expected = '3\t241.0\t241.5\t244.66666666666666\t242.0\t246.5\t251.0\t4.496912521077347\t1.0\t241.2\t241.4\t241.6\t241.8\t243.8\t245.6\t247.4\t249.2\t250.82\t3\t251.0\t251.0\t251.0\t251.0\t251.0\t251.0\t0.0\t0.0\t251.0\t251.0\t251.0\t251.0\t251.0\t251.0\t251.0\t251.0\t251.0\n' + assert m_expected in f"{m_resp}" + unlink(out_lengths) + unlink(out_metrics) \ No newline at end of file diff --git a/pydeeptools/deeptools/test/test_computeMatrix.py b/pydeeptools/deeptools/test/test_computeMatrix.py new file mode 100644 index 0000000000..b27e8ccf7f --- /dev/null +++ b/pydeeptools/deeptools/test/test_computeMatrix.py @@ -0,0 +1,61 @@ +import deeptools.computeMatrix as cm + +import os.path +from os import unlink + +ROOT = os.path.dirname(os.path.abspath(__file__)) + "/test_data/" +REGIONS_IN1 = ROOT + "computeMatrix1.bed" +REGIONS_IN2 = ROOT + "computeMatrix2.bed" +BIGWIG_IN1 = ROOT + "bamCoverage_result4.bw" +BIGWIG_IN2 = ROOT + "computeMatrix2.bw" +OUT_ARCHIEVE1 = ROOT + "computeMatrix_result1.gz" +OUT_ARCHIEVE2 = ROOT + "computeMatrix_result2.gz" +OUT_ARCHIEVE3 = ROOT + "computeMatrix_result3.gz" + +def test_compute_matrix_with_reference_point_and_advance_options_1(): + """ + Test minimal command line args compute matrix with reference based + mode along with advance options of sorting using sum and average + type bin as sum + """ + outfile = '/tmp/computematrix_1.gz' + args = "reference-point --regionsFileName {} --scoreFileName {} -o {} -bs 10 --sortUsing sum --averageTypeBins sum -b 10 -a 10".format(REGIONS_IN1, BIGWIG_IN1, outfile).split() + cm.main(args) + + archieve_file_size = os.path.getsize(OUT_ARCHIEVE1) + expected_file_size = os.path.getsize(outfile) + size_tolerance = 500 + size_difference = abs(archieve_file_size - expected_file_size) + assert size_difference <= size_tolerance, "File size do not match" + unlink(outfile) + +def test_compute_matrix_with_reference_point_and_advance_options_2(): + """ + Test minimal command line args compute matrix with reference based mode + with before and after region start length + """ + outfile = '/tmp/computematrix_2.gz' + args = "reference-point --regionsFileName {} --scoreFileName {} -o {} -bs 10 -b 10 -a 10".format(REGIONS_IN2, BIGWIG_IN2, outfile).split() + cm.main(args) + + archieve_file_size = os.path.getsize(OUT_ARCHIEVE2) + expected_file_size = os.path.getsize(outfile) + size_tolerance = 500 + size_difference = abs(archieve_file_size - expected_file_size) + assert size_difference <= size_tolerance, "File size do not match" + unlink(outfile) + +def test_compute_matrix_with_scale_regions(): + """ + Test minimal command line args compute matrix with scale regions mode + """ + outfile = '/tmp/computematrix_3.gz' + args = "scale-regions --regionsFileName {} --scoreFileName {} -o {}".format(REGIONS_IN2, BIGWIG_IN2, outfile).split() + cm.main(args) + + archieve_file_size = os.path.getsize(OUT_ARCHIEVE3) + expected_file_size = os.path.getsize(outfile) + size_tolerance = 500 + size_difference = abs(archieve_file_size - expected_file_size) + assert size_difference <= size_tolerance, "File size do not match" + unlink(outfile) \ No newline at end of file diff --git a/pydeeptools/deeptools/test/test_correctGCBias.py b/pydeeptools/deeptools/test/test_correctGCBias.py new file mode 100644 index 0000000000..766c4868de --- /dev/null +++ b/pydeeptools/deeptools/test/test_correctGCBias.py @@ -0,0 +1,26 @@ +# from unittest import TestCase + +import deeptools.correctGCBias +import deeptools.utilities +import os.path +from os import unlink +import pysam + +ROOT = os.path.dirname(os.path.abspath(__file__)) + "/test_data/" + + +def test_correctGCBias(): + """ + Test minimal command line args for correctGCBias + """ + GCbiasFreq = ROOT + 'computeGCBias_result1.tabular' + BAM = ROOT + 'paired_chr2L.bam' + GENOME = ROOT + 'sequence.2bit' + outfile = '/tmp/test_correctbias.bam' + args = "--GCbiasFrequenciesFile {} --bamfile {} --genome {} --effectiveGenomeSize 10050 --correctedFile {}".format(GCbiasFreq, BAM, GENOME, outfile).split() + deeptools.correctGCBias.main(args) + + alignment_count = pysam.AlignmentFile(outfile, "rb").count() + expected_count = 11630 + assert abs(alignment_count - expected_count) < 50 + unlink(outfile) \ No newline at end of file diff --git a/pydeeptools/deeptools/test/test_data/alignmentSieve.bam b/pydeeptools/deeptools/test/test_data/alignmentSieve.bam new file mode 100644 index 0000000000..560ab32da9 Binary files /dev/null and b/pydeeptools/deeptools/test/test_data/alignmentSieve.bam differ diff --git a/pydeeptools/deeptools/test/test_data/alignmentSieve.bed b/pydeeptools/deeptools/test/test_data/alignmentSieve.bed new file mode 100644 index 0000000000..b322bb2a75 --- /dev/null +++ b/pydeeptools/deeptools/test/test_data/alignmentSieve.bed @@ -0,0 +1,4261 @@ +chr2L 5093 5232 +chr2L 5101 5236 +chr2L 5105 5252 +chr2L 5108 5267 +chr2L 5105 5250 +chr2L 5108 5244 +chr2L 5108 5279 +chr2L 5105 5251 +chr2L 5105 5252 +chr2L 5105 5224 +chr2L 5108 5244 +chr2L 5108 5252 +chr2L 5108 5244 +chr2L 5108 5251 +chr2L 5105 5212 +chr2L 5105 5266 +chr2L 5108 5265 +chr2L 5106 5287 +chr2L 5106 5243 +chr2L 5106 5204 +chr2L 5109 5249 +chr2L 5109 5213 +chr2L 5106 5245 +chr2L 5118 5266 +chr2L 5116 5224 +chr2L 5117 5293 +chr2L 5117 5291 +chr2L 5120 5265 +chr2L 5117 5243 +chr2L 5122 5249 +chr2L 5119 5268 +chr2L 5119 5245 +chr2L 5123 5423 +chr2L 5120 5293 +chr2L 5120 5250 +chr2L 5123 5293 +chr2L 5129 5197 +chr2L 5129 5323 +chr2L 5130 5265 +chr2L 5127 5280 +chr2L 5127 5285 +chr2L 5133 5274 +chr2L 5138 5293 +chr2L 5141 5279 +chr2L 5138 5266 +chr2L 5141 5279 +chr2L 5152 5322 +chr2L 5149 5323 +chr2L 5149 5250 +chr2L 5149 5306 +chr2L 5152 5292 +chr2L 5152 5322 +chr2L 5149 5330 +chr2L 5151 5252 +chr2L 5154 5326 +chr2L 5154 5251 +chr2L 5153 5324 +chr2L 5154 5341 +chr2L 5157 5304 +chr2L 5157 5292 +chr2L 5159 5292 +chr2L 5156 5323 +chr2L 5160 5292 +chr2L 5157 5323 +chr2L 5160 5326 +chr2L 5160 5292 +chr2L 5161 5326 +chr2L 5167 5280 +chr2L 5168 5249 +chr2L 5168 5325 +chr2L 5165 5306 +chr2L 5166 5323 +chr2L 5166 5306 +chr2L 5171 5323 +chr2L 5181 5322 +chr2L 5179 5356 +chr2L 5179 5294 +chr2L 5179 5323 +chr2L 5182 5312 +chr2L 5185 5323 +chr2L 5197 5326 +chr2L 5206 5322 +chr2L 5207 5340 +chr2L 5207 5355 +chr2L 5211 5325 +chr2L 5212 5350 +chr2L 5212 5296 +chr2L 5209 5381 +chr2L 5219 5369 +chr2L 5216 5323 +chr2L 5219 5356 +chr2L 5216 5382 +chr2L 5219 5381 +chr2L 5219 5369 +chr2L 5224 5326 +chr2L 5221 5356 +chr2L 5224 5380 +chr2L 5224 5356 +chr2L 5224 5325 +chr2L 5224 5375 +chr2L 5225 5380 +chr2L 5225 5325 +chr2L 5225 5377 +chr2L 5225 5381 +chr2L 5225 5440 +chr2L 5225 5375 +chr2L 5225 5325 +chr2L 5225 5355 +chr2L 5225 5355 +chr2L 5227 5380 +chr2L 5226 5500 +chr2L 5230 5326 +chr2L 5231 5423 +chr2L 5228 5400 +chr2L 5236 5383 +chr2L 5256 5401 +chr2L 5253 5455 +chr2L 5257 5467 +chr2L 5257 5402 +chr2L 5261 5423 +chr2L 5258 5355 +chr2L 5261 5428 +chr2L 5264 5401 +chr2L 5264 5401 +chr2L 5261 5467 +chr2L 5261 5403 +chr2L 5265 5426 +chr2L 5265 5377 +chr2L 5262 5370 +chr2L 5262 5392 +chr2L 5265 5423 +chr2L 5265 5375 +chr2L 5265 5401 +chr2L 5265 5401 +chr2L 5262 5427 +chr2L 5274 5465 +chr2L 5276 5381 +chr2L 5279 5402 +chr2L 5281 5423 +chr2L 5281 5431 +chr2L 5288 5411 +chr2L 5289 5382 +chr2L 5288 5421 +chr2L 5288 5421 +chr2L 5291 5420 +chr2L 5288 5424 +chr2L 5289 5467 +chr2L 5302 5462 +chr2L 5303 5401 +chr2L 5300 5425 +chr2L 5303 5464 +chr2L 5300 5464 +chr2L 5300 5464 +chr2L 5306 5401 +chr2L 5303 5428 +chr2L 5303 5414 +chr2L 5303 5465 +chr2L 5304 5407 +chr2L 5311 5423 +chr2L 5310 5467 +chr2L 5313 5463 +chr2L 5313 5423 +chr2L 5310 5465 +chr2L 5313 5423 +chr2L 5313 5462 +chr2L 5317 5500 +chr2L 5328 5467 +chr2L 5331 5485 +chr2L 5334 5467 +chr2L 5334 5466 +chr2L 5334 5467 +chr2L 5331 5480 +chr2L 5332 5467 +chr2L 5335 5480 +chr2L 5332 5485 +chr2L 5332 5484 +chr2L 5332 5517 +chr2L 5335 5465 +chr2L 5335 5464 +chr2L 5335 5464 +chr2L 5332 5469 +chr2L 5335 5467 +chr2L 5333 5472 +chr2L 5337 5480 +chr2L 5334 5488 +chr2L 5337 5467 +chr2L 5334 5503 +chr2L 5337 5527 +chr2L 5337 5497 +chr2L 5334 5498 +chr2L 5334 5497 +chr2L 5337 5463 +chr2L 5337 5516 +chr2L 5334 5483 +chr2L 5337 5517 +chr2L 5337 5453 +chr2L 5337 5466 +chr2L 5337 5440 +chr2L 5334 5454 +chr2L 5339 5503 +chr2L 5343 5451 +chr2L 5340 5518 +chr2L 5350 5466 +chr2L 5352 5464 +chr2L 5349 5467 +chr2L 5352 5496 +chr2L 5352 5453 +chr2L 5361 5527 +chr2L 5365 5500 +chr2L 5362 5527 +chr2L 5365 5517 +chr2L 5362 5464 +chr2L 5362 5497 +chr2L 5368 5517 +chr2L 5368 5496 +chr2L 5378 5500 +chr2L 5378 5499 +chr2L 5375 5527 +chr2L 5385 5517 +chr2L 5385 5497 +chr2L 5387 5527 +chr2L 5390 5502 +chr2L 5387 5527 +chr2L 5390 5526 +chr2L 5394 5526 +chr2L 5391 5557 +chr2L 5395 5502 +chr2L 5395 5520 +chr2L 5392 5481 +chr2L 5392 5504 +chr2L 5395 5556 +chr2L 5394 5533 +chr2L 5395 5557 +chr2L 5398 5563 +chr2L 5398 5556 +chr2L 5398 5526 +chr2L 5398 5527 +chr2L 5395 5543 +chr2L 5400 5548 +chr2L 5398 5518 +chr2L 5398 5500 +chr2L 5408 5528 +chr2L 5413 5556 +chr2L 5413 5596 +chr2L 5415 5520 +chr2L 5421 5549 +chr2L 5419 5567 +chr2L 5419 5607 +chr2L 5422 5574 +chr2L 5419 5567 +chr2L 5422 5526 +chr2L 5422 5503 +chr2L 5422 5582 +chr2L 5419 5557 +chr2L 5423 5601 +chr2L 5426 5583 +chr2L 5426 5564 +chr2L 5436 5565 +chr2L 5437 5567 +chr2L 5437 5567 +chr2L 5437 5586 +chr2L 5440 5549 +chr2L 5438 5613 +chr2L 5441 5596 +chr2L 5438 5583 +chr2L 5438 5583 +chr2L 5438 5601 +chr2L 5441 5598 +chr2L 5438 5607 +chr2L 5449 5601 +chr2L 5449 5542 +chr2L 5450 5613 +chr2L 5465 5580 +chr2L 5465 5598 +chr2L 5475 5582 +chr2L 5473 5602 +chr2L 5478 5612 +chr2L 5479 5627 +chr2L 5476 5613 +chr2L 5479 5626 +chr2L 5476 5565 +chr2L 5479 5563 +chr2L 5476 5599 +chr2L 5480 5640 +chr2L 5477 5613 +chr2L 5480 5566 +chr2L 5480 5639 +chr2L 5477 5614 +chr2L 5477 5591 +chr2L 5480 5584 +chr2L 5477 5626 +chr2L 5477 5628 +chr2L 5477 5614 +chr2L 5480 5626 +chr2L 5480 5626 +chr2L 5477 5639 +chr2L 5477 5607 +chr2L 5477 5614 +chr2L 5477 5627 +chr2L 5477 5630 +chr2L 5483 5639 +chr2L 5490 5564 +chr2L 5490 5656 +chr2L 5490 5612 +chr2L 5494 5640 +chr2L 5498 5613 +chr2L 5495 5627 +chr2L 5495 5615 +chr2L 5502 5656 +chr2L 5502 5675 +chr2L 5508 5689 +chr2L 5508 5613 +chr2L 5512 5711 +chr2L 5513 5656 +chr2L 5511 5657 +chr2L 5514 5613 +chr2L 5511 5657 +chr2L 5511 5657 +chr2L 5516 5623 +chr2L 5513 5646 +chr2L 5517 5656 +chr2L 5518 5670 +chr2L 5528 5656 +chr2L 5528 5684 +chr2L 5541 5657 +chr2L 5538 5712 +chr2L 5539 5706 +chr2L 5542 5690 +chr2L 5539 5715 +chr2L 5539 5712 +chr2L 5539 5713 +chr2L 5539 5712 +chr2L 5542 5746 +chr2L 5539 5710 +chr2L 5543 5665 +chr2L 5540 5657 +chr2L 5540 5691 +chr2L 5543 5670 +chr2L 5543 5714 +chr2L 5543 5670 +chr2L 5541 5714 +chr2L 5545 5748 +chr2L 5549 5718 +chr2L 5554 5713 +chr2L 5554 5717 +chr2L 5555 5710 +chr2L 5563 5709 +chr2L 5561 5717 +chr2L 5561 5717 +chr2L 5564 5714 +chr2L 5564 5714 +chr2L 5573 5711 +chr2L 5571 5736 +chr2L 5574 5714 +chr2L 5574 5711 +chr2L 5574 5716 +chr2L 5573 5712 +chr2L 5581 5714 +chr2L 5582 5711 +chr2L 5582 5736 +chr2L 5582 5689 +chr2L 5581 5717 +chr2L 5591 5714 +chr2L 5589 5802 +chr2L 5592 5735 +chr2L 5592 5712 +chr2L 5589 5718 +chr2L 5594 5711 +chr2L 5594 5715 +chr2L 5591 5736 +chr2L 5594 5721 +chr2L 5597 5715 +chr2L 5598 5749 +chr2L 5595 5758 +chr2L 5598 5733 +chr2L 5598 5735 +chr2L 5598 5817 +chr2L 5599 5746 +chr2L 5604 5736 +chr2L 5605 5710 +chr2L 5605 5736 +chr2L 5608 5749 +chr2L 5612 5711 +chr2L 5611 5718 +chr2L 5619 5718 +chr2L 5622 5714 +chr2L 5620 5736 +chr2L 5620 5758 +chr2L 5623 5774 +chr2L 5623 5787 +chr2L 5624 5749 +chr2L 5621 5758 +chr2L 5621 5798 +chr2L 5624 5747 +chr2L 5621 5762 +chr2L 5621 5775 +chr2L 5624 5775 +chr2L 5621 5738 +chr2L 5625 5787 +chr2L 5625 5757 +chr2L 5625 5715 +chr2L 5633 5800 +chr2L 5633 5798 +chr2L 5636 5797 +chr2L 5633 5788 +chr2L 5633 5822 +chr2L 5636 5787 +chr2L 5633 5800 +chr2L 5636 5802 +chr2L 5636 5785 +chr2L 5633 5798 +chr2L 5637 5800 +chr2L 5634 5800 +chr2L 5636 5750 +chr2L 5636 5786 +chr2L 5639 5799 +chr2L 5636 5801 +chr2L 5636 5750 +chr2L 5636 5908 +chr2L 5643 5801 +chr2L 5646 5819 +chr2L 5647 5800 +chr2L 5644 5752 +chr2L 5647 5827 +chr2L 5647 5775 +chr2L 5647 5757 +chr2L 5644 5801 +chr2L 5653 5757 +chr2L 5665 5775 +chr2L 5668 5801 +chr2L 5668 5979 +chr2L 5668 5846 +chr2L 5668 5800 +chr2L 5669 5915 +chr2L 5666 5800 +chr2L 5669 5827 +chr2L 5666 5820 +chr2L 5669 5788 +chr2L 5671 5804 +chr2L 5671 5831 +chr2L 5671 5958 +chr2L 5671 5846 +chr2L 5668 5832 +chr2L 5668 5801 +chr2L 5668 5800 +chr2L 5672 5819 +chr2L 5673 5833 +chr2L 5675 5775 +chr2L 5686 5831 +chr2L 5695 5862 +chr2L 5699 5799 +chr2L 5699 5858 +chr2L 5708 5801 +chr2L 5712 5835 +chr2L 5710 5862 +chr2L 5725 5857 +chr2L 5726 5829 +chr2L 5724 5882 +chr2L 5728 5858 +chr2L 5725 5776 +chr2L 5725 5884 +chr2L 5725 5856 +chr2L 5729 5913 +chr2L 5729 5879 +chr2L 5726 5886 +chr2L 5729 5850 +chr2L 5726 5877 +chr2L 5731 5915 +chr2L 5731 5884 +chr2L 5734 5850 +chr2L 5731 5858 +chr2L 5731 5862 +chr2L 5734 5913 +chr2L 5732 5802 +chr2L 5732 5884 +chr2L 5735 5899 +chr2L 5735 5883 +chr2L 5732 5886 +chr2L 5732 5893 +chr2L 5732 5880 +chr2L 5732 5915 +chr2L 5732 5850 +chr2L 5746 5913 +chr2L 5743 5904 +chr2L 5746 5882 +chr2L 5749 5914 +chr2L 5749 5858 +chr2L 5749 5913 +chr2L 5746 5886 +chr2L 5749 5881 +chr2L 5746 5888 +chr2L 5756 5942 +chr2L 5759 5876 +chr2L 5760 5914 +chr2L 5757 5914 +chr2L 5760 5928 +chr2L 5757 5888 +chr2L 5757 5884 +chr2L 5757 5858 +chr2L 5757 5904 +chr2L 5762 5914 +chr2L 5762 5914 +chr2L 5762 5914 +chr2L 5767 5869 +chr2L 5765 5880 +chr2L 5765 5904 +chr2L 5766 5910 +chr2L 5767 5903 +chr2L 5767 5914 +chr2L 5770 5914 +chr2L 5767 5915 +chr2L 5772 5903 +chr2L 5781 5914 +chr2L 5781 5908 +chr2L 5799 5957 +chr2L 5799 5913 +chr2L 5810 5957 +chr2L 5811 5885 +chr2L 5812 5999 +chr2L 5812 5957 +chr2L 5812 5958 +chr2L 5813 5902 +chr2L 5813 5899 +chr2L 5813 5914 +chr2L 5813 5914 +chr2L 5811 5966 +chr2L 5814 5980 +chr2L 5811 5981 +chr2L 5814 5979 +chr2L 5814 5913 +chr2L 5814 5939 +chr2L 5814 5957 +chr2L 5814 5957 +chr2L 5811 5980 +chr2L 5811 5914 +chr2L 5814 5913 +chr2L 5812 5929 +chr2L 5815 5914 +chr2L 5815 5913 +chr2L 5812 5903 +chr2L 5812 5942 +chr2L 5815 5927 +chr2L 5815 5914 +chr2L 5812 5914 +chr2L 5812 5941 +chr2L 5815 5957 +chr2L 5812 6002 +chr2L 5815 5958 +chr2L 5828 5979 +chr2L 5828 5980 +chr2L 5826 6002 +chr2L 5826 6000 +chr2L 5826 6000 +chr2L 5830 5958 +chr2L 5839 5980 +chr2L 5840 5958 +chr2L 5843 6002 +chr2L 5844 5928 +chr2L 5844 5980 +chr2L 5844 5992 +chr2L 5842 6002 +chr2L 5842 5949 +chr2L 5847 5958 +chr2L 5856 5953 +chr2L 5865 6059 +chr2L 5865 6044 +chr2L 5864 5959 +chr2L 5867 5958 +chr2L 5867 6021 +chr2L 5864 6033 +chr2L 5868 6032 +chr2L 5867 5958 +chr2L 5867 6004 +chr2L 5868 6037 +chr2L 5873 6001 +chr2L 5870 5999 +chr2L 5870 5999 +chr2L 5873 6001 +chr2L 5872 6033 +chr2L 5872 6003 +chr2L 5872 5976 +chr2L 5879 6038 +chr2L 5880 6033 +chr2L 5885 6001 +chr2L 5891 5958 +chr2L 5898 6032 +chr2L 5899 6004 +chr2L 5896 6006 +chr2L 5896 6053 +chr2L 5899 6030 +chr2L 5899 6032 +chr2L 5899 6021 +chr2L 5899 6003 +chr2L 5906 6081 +chr2L 5911 6081 +chr2L 5922 6097 +chr2L 5925 6080 +chr2L 5922 6062 +chr2L 5922 6097 +chr2L 5925 6075 +chr2L 5925 6078 +chr2L 5922 6081 +chr2L 5922 6082 +chr2L 5922 6098 +chr2L 5925 6066 +chr2L 5926 6092 +chr2L 5923 6079 +chr2L 5923 6070 +chr2L 5926 6102 +chr2L 5926 6136 +chr2L 5925 6073 +chr2L 5928 6106 +chr2L 5928 6068 +chr2L 5928 6021 +chr2L 5928 6081 +chr2L 5925 6081 +chr2L 5925 6060 +chr2L 5925 6106 +chr2L 5928 6104 +chr2L 5926 6081 +chr2L 5930 6074 +chr2L 5931 6082 +chr2L 5928 6083 +chr2L 5937 6036 +chr2L 5935 6093 +chr2L 5935 6099 +chr2L 5938 6103 +chr2L 5938 6097 +chr2L 5942 6104 +chr2L 5942 6106 +chr2L 5942 6078 +chr2L 5942 6081 +chr2L 5939 6107 +chr2L 5947 6080 +chr2L 5947 6119 +chr2L 5944 6124 +chr2L 5948 6129 +chr2L 5948 6119 +chr2L 5948 6102 +chr2L 5945 6108 +chr2L 5945 6081 +chr2L 5945 6089 +chr2L 5948 6080 +chr2L 5948 6096 +chr2L 5948 6080 +chr2L 5945 6107 +chr2L 5948 6097 +chr2L 5945 6079 +chr2L 5948 6094 +chr2L 5954 6097 +chr2L 5952 6107 +chr2L 5952 6107 +chr2L 5955 6084 +chr2L 5952 6124 +chr2L 5954 6144 +chr2L 5957 6064 +chr2L 5959 6083 +chr2L 5965 6124 +chr2L 5965 6096 +chr2L 5966 6113 +chr2L 5966 6058 +chr2L 5966 6082 +chr2L 5970 6080 +chr2L 5967 6137 +chr2L 5970 6140 +chr2L 5967 6108 +chr2L 5970 6123 +chr2L 5970 6094 +chr2L 5970 6106 +chr2L 5967 6174 +chr2L 5967 6144 +chr2L 5970 6143 +chr2L 5972 6147 +chr2L 5969 6065 +chr2L 5969 6107 +chr2L 5969 6081 +chr2L 5969 6119 +chr2L 5972 6064 +chr2L 5972 6142 +chr2L 5972 6142 +chr2L 5978 6143 +chr2L 5989 6137 +chr2L 5986 6144 +chr2L 5989 6143 +chr2L 5986 6138 +chr2L 5987 6138 +chr2L 5987 6144 +chr2L 5987 6098 +chr2L 5990 6148 +chr2L 5990 6137 +chr2L 5990 6143 +chr2L 5990 6143 +chr2L 5990 6143 +chr2L 5990 6142 +chr2L 5991 6137 +chr2L 6013 6142 +chr2L 6016 6096 +chr2L 6013 6137 +chr2L 6017 6143 +chr2L 6014 6124 +chr2L 6017 6185 +chr2L 6017 6173 +chr2L 6018 6142 +chr2L 6015 6171 +chr2L 6018 6136 +chr2L 6016 6137 +chr2L 6016 6143 +chr2L 6019 6143 +chr2L 6021 6148 +chr2L 6018 6174 +chr2L 6021 6198 +chr2L 6021 6184 +chr2L 6018 6144 +chr2L 6018 6143 +chr2L 6018 6171 +chr2L 6021 6136 +chr2L 6021 6163 +chr2L 6021 6188 +chr2L 6018 6156 +chr2L 6018 6167 +chr2L 6021 6188 +chr2L 6021 6188 +chr2L 6018 6138 +chr2L 6022 6146 +chr2L 6022 6188 +chr2L 6022 6163 +chr2L 6019 6165 +chr2L 6022 6173 +chr2L 6022 6170 +chr2L 6022 6143 +chr2L 6022 6143 +chr2L 6019 6174 +chr2L 6022 6144 +chr2L 6019 6171 +chr2L 6022 6170 +chr2L 6022 6143 +chr2L 6022 6142 +chr2L 6022 6166 +chr2L 6019 6143 +chr2L 6019 6198 +chr2L 6022 6136 +chr2L 6022 6138 +chr2L 6022 6151 +chr2L 6019 6171 +chr2L 6019 6138 +chr2L 6025 6128 +chr2L 6033 6143 +chr2L 6033 6145 +chr2L 6036 6163 +chr2L 6033 6164 +chr2L 6038 6202 +chr2L 6039 6123 +chr2L 6037 6144 +chr2L 6040 6186 +chr2L 6040 6186 +chr2L 6045 6174 +chr2L 6049 6188 +chr2L 6046 6198 +chr2L 6046 6174 +chr2L 6046 6144 +chr2L 6047 6199 +chr2L 6049 6144 +chr2L 6052 6197 +chr2L 6052 6200 +chr2L 6053 6170 +chr2L 6053 6264 +chr2L 6054 6197 +chr2L 6057 6207 +chr2L 6061 6218 +chr2L 6063 6142 +chr2L 6063 6203 +chr2L 6066 6144 +chr2L 6072 6188 +chr2L 6077 6231 +chr2L 6077 6190 +chr2L 6086 6198 +chr2L 6091 6219 +chr2L 6089 6359 +chr2L 6092 6219 +chr2L 6093 6248 +chr2L 6093 6257 +chr2L 6096 6246 +chr2L 6096 6219 +chr2L 6093 6265 +chr2L 6097 6206 +chr2L 6095 6198 +chr2L 6098 6300 +chr2L 6098 6199 +chr2L 6098 6287 +chr2L 6098 6196 +chr2L 6095 6248 +chr2L 6105 6270 +chr2L 6103 6248 +chr2L 6106 6235 +chr2L 6106 6257 +chr2L 6112 6270 +chr2L 6118 6233 +chr2L 6119 6287 +chr2L 6119 6281 +chr2L 6116 6282 +chr2L 6116 6220 +chr2L 6125 6273 +chr2L 6122 6248 +chr2L 6126 6273 +chr2L 6135 6274 +chr2L 6136 6288 +chr2L 6138 6286 +chr2L 6144 6281 +chr2L 6144 6286 +chr2L 6156 6298 +chr2L 6162 6303 +chr2L 6166 6304 +chr2L 6163 6306 +chr2L 6166 6302 +chr2L 6164 6303 +chr2L 6164 6271 +chr2L 6167 6305 +chr2L 6164 6271 +chr2L 6164 6304 +chr2L 6164 6290 +chr2L 6172 6306 +chr2L 6173 6307 +chr2L 6171 6258 +chr2L 6174 6296 +chr2L 6177 6310 +chr2L 6174 6299 +chr2L 6174 6303 +chr2L 6174 6303 +chr2L 6176 6320 +chr2L 6181 6329 +chr2L 6181 6328 +chr2L 6184 6328 +chr2L 6184 6304 +chr2L 6185 6321 +chr2L 6182 6342 +chr2L 6182 6490 +chr2L 6182 6331 +chr2L 6182 6300 +chr2L 6185 6341 +chr2L 6186 6302 +chr2L 6186 6298 +chr2L 6186 6319 +chr2L 6183 6373 +chr2L 6183 6342 +chr2L 6183 6298 +chr2L 6187 6341 +chr2L 6187 6287 +chr2L 6185 6343 +chr2L 6198 6331 +chr2L 6197 6359 +chr2L 6201 6342 +chr2L 6212 6373 +chr2L 6209 6303 +chr2L 6212 6320 +chr2L 6214 6341 +chr2L 6216 6342 +chr2L 6219 6319 +chr2L 6217 6359 +chr2L 6217 6366 +chr2L 6217 6311 +chr2L 6220 6341 +chr2L 6220 6400 +chr2L 6228 6372 +chr2L 6229 6371 +chr2L 6226 6374 +chr2L 6231 6372 +chr2L 6231 6342 +chr2L 6228 6373 +chr2L 6231 6341 +chr2L 6228 6373 +chr2L 6230 6374 +chr2L 6234 6358 +chr2L 6234 6401 +chr2L 6231 6373 +chr2L 6242 6396 +chr2L 6240 6402 +chr2L 6246 6347 +chr2L 6253 6401 +chr2L 6266 6456 +chr2L 6266 6371 +chr2L 6263 6415 +chr2L 6264 6353 +chr2L 6280 6457 +chr2L 6285 6359 +chr2L 6285 6428 +chr2L 6285 6457 +chr2L 6285 6441 +chr2L 6285 6489 +chr2L 6289 6441 +chr2L 6289 6428 +chr2L 6286 6441 +chr2L 6286 6459 +chr2L 6289 6455 +chr2L 6293 6442 +chr2L 6294 6418 +chr2L 6298 6440 +chr2L 6302 6440 +chr2L 6303 6389 +chr2L 6304 6401 +chr2L 6304 6440 +chr2L 6304 6400 +chr2L 6304 6498 +chr2L 6304 6440 +chr2L 6302 6442 +chr2L 6303 6451 +chr2L 6306 6428 +chr2L 6303 6429 +chr2L 6310 6456 +chr2L 6311 6429 +chr2L 6308 6456 +chr2L 6315 6441 +chr2L 6313 6447 +chr2L 6317 6456 +chr2L 6318 6455 +chr2L 6315 6457 +chr2L 6318 6453 +chr2L 6319 6473 +chr2L 6319 6489 +chr2L 6316 6457 +chr2L 6316 6441 +chr2L 6319 6473 +chr2L 6319 6455 +chr2L 6319 6455 +chr2L 6316 6458 +chr2L 6316 6458 +chr2L 6322 6492 +chr2L 6322 6455 +chr2L 6319 6474 +chr2L 6320 6498 +chr2L 6323 6475 +chr2L 6324 6454 +chr2L 6327 6481 +chr2L 6327 6427 +chr2L 6324 6473 +chr2L 6324 6430 +chr2L 6324 6446 +chr2L 6328 6481 +chr2L 6325 6490 +chr2L 6325 6456 +chr2L 6325 6441 +chr2L 6328 6481 +chr2L 6328 6456 +chr2L 6328 6469 +chr2L 6325 6441 +chr2L 6325 6465 +chr2L 6325 6430 +chr2L 6328 6473 +chr2L 6325 6483 +chr2L 6328 6455 +chr2L 6335 6457 +chr2L 6341 6527 +chr2L 6340 6489 +chr2L 6343 6456 +chr2L 6340 6499 +chr2L 6341 6441 +chr2L 6344 6500 +chr2L 6344 6540 +chr2L 6341 6500 +chr2L 6349 6499 +chr2L 6349 6456 +chr2L 6349 6499 +chr2L 6347 6489 +chr2L 6350 6474 +chr2L 6350 6455 +chr2L 6347 6519 +chr2L 6351 6518 +chr2L 6351 6488 +chr2L 6351 6498 +chr2L 6348 6481 +chr2L 6348 6456 +chr2L 6351 6527 +chr2L 6351 6481 +chr2L 6351 6475 +chr2L 6352 6480 +chr2L 6354 6500 +chr2L 6358 6511 +chr2L 6355 6512 +chr2L 6359 6498 +chr2L 6356 6489 +chr2L 6356 6489 +chr2L 6356 6520 +chr2L 6359 6499 +chr2L 6359 6488 +chr2L 6359 6511 +chr2L 6360 6518 +chr2L 6357 6503 +chr2L 6360 6473 +chr2L 6360 6469 +chr2L 6357 6493 +chr2L 6360 6519 +chr2L 6357 6474 +chr2L 6360 6498 +chr2L 6361 6498 +chr2L 6361 6497 +chr2L 6358 6499 +chr2L 6358 6517 +chr2L 6367 6488 +chr2L 6367 6518 +chr2L 6368 6519 +chr2L 6368 6497 +chr2L 6369 6540 +chr2L 6373 6510 +chr2L 6373 6528 +chr2L 6373 6518 +chr2L 6371 6527 +chr2L 6371 6490 +chr2L 6372 6529 +chr2L 6383 6499 +chr2L 6381 6536 +chr2L 6381 6490 +chr2L 6384 6518 +chr2L 6381 6559 +chr2L 6384 6488 +chr2L 6381 6517 +chr2L 6384 6529 +chr2L 6385 6499 +chr2L 6385 6518 +chr2L 6382 6517 +chr2L 6382 6529 +chr2L 6385 6544 +chr2L 6385 6441 +chr2L 6384 6519 +chr2L 6384 6481 +chr2L 6384 6499 +chr2L 6385 6519 +chr2L 6388 6540 +chr2L 6385 6515 +chr2L 6388 6542 +chr2L 6385 6528 +chr2L 6388 6529 +chr2L 6388 6520 +chr2L 6385 6528 +chr2L 6385 6527 +chr2L 6385 6536 +chr2L 6387 6529 +chr2L 6412 6513 +chr2L 6413 6527 +chr2L 6414 6560 +chr2L 6418 6518 +chr2L 6421 6534 +chr2L 6421 6584 +chr2L 6425 6587 +chr2L 6422 6584 +chr2L 6422 6543 +chr2L 6450 6611 +chr2L 6453 6586 +chr2L 6465 6586 +chr2L 6467 6630 +chr2L 6467 6616 +chr2L 6467 6624 +chr2L 6468 6630 +chr2L 6465 6637 +chr2L 6468 6624 +chr2L 6468 6639 +chr2L 6465 6626 +chr2L 6468 6631 +chr2L 6468 6624 +chr2L 6468 6644 +chr2L 6465 6638 +chr2L 6468 6624 +chr2L 6465 6587 +chr2L 6468 6630 +chr2L 6468 6624 +chr2L 6467 6626 +chr2L 6470 6610 +chr2L 6470 6624 +chr2L 6468 6628 +chr2L 6469 6631 +chr2L 6472 6624 +chr2L 6469 6625 +chr2L 6480 6659 +chr2L 6481 6631 +chr2L 6487 6612 +chr2L 6487 6645 +chr2L 6490 6657 +chr2L 6487 6631 +chr2L 6488 6588 +chr2L 6488 6588 +chr2L 6488 6646 +chr2L 6488 6626 +chr2L 6491 6657 +chr2L 6491 6586 +chr2L 6496 6693 +chr2L 6497 6587 +chr2L 6497 6621 +chr2L 6496 6660 +chr2L 6496 6658 +chr2L 6497 6611 +chr2L 6498 6625 +chr2L 6498 6655 +chr2L 6498 6611 +chr2L 6498 6625 +chr2L 6501 6657 +chr2L 6498 6632 +chr2L 6501 6630 +chr2L 6501 6624 +chr2L 6498 6645 +chr2L 6509 6586 +chr2L 6510 6657 +chr2L 6507 6598 +chr2L 6507 6631 +chr2L 6507 6625 +chr2L 6508 6658 +chr2L 6511 6657 +chr2L 6508 6650 +chr2L 6508 6638 +chr2L 6511 6640 +chr2L 6511 6688 +chr2L 6508 6658 +chr2L 6508 6659 +chr2L 6508 6625 +chr2L 6508 6658 +chr2L 6511 6657 +chr2L 6508 6623 +chr2L 6511 6660 +chr2L 6510 6625 +chr2L 6513 6625 +chr2L 6510 6632 +chr2L 6513 6648 +chr2L 6513 6624 +chr2L 6510 6655 +chr2L 6519 6639 +chr2L 6520 6659 +chr2L 6517 6631 +chr2L 6517 6659 +chr2L 6520 6681 +chr2L 6527 6690 +chr2L 6536 6703 +chr2L 6533 6708 +chr2L 6533 6691 +chr2L 6533 6689 +chr2L 6537 6644 +chr2L 6539 6688 +chr2L 6538 6689 +chr2L 6543 6688 +chr2L 6540 6683 +chr2L 6541 6645 +chr2L 6541 6704 +chr2L 6541 6660 +chr2L 6541 6683 +chr2L 6544 6682 +chr2L 6547 6689 +chr2L 6552 6657 +chr2L 6549 6640 +chr2L 6553 6722 +chr2L 6550 6705 +chr2L 6553 6654 +chr2L 6554 6669 +chr2L 6551 6704 +chr2L 6551 6668 +chr2L 6554 6707 +chr2L 6551 6682 +chr2L 6554 6689 +chr2L 6555 6721 +chr2L 6552 6708 +chr2L 6552 6704 +chr2L 6552 6722 +chr2L 6554 6721 +chr2L 6554 6705 +chr2L 6555 6704 +chr2L 6555 6721 +chr2L 6558 6704 +chr2L 6558 6675 +chr2L 6558 6702 +chr2L 6555 6786 +chr2L 6555 6690 +chr2L 6558 6658 +chr2L 6558 6709 +chr2L 6558 6701 +chr2L 6555 6721 +chr2L 6560 6630 +chr2L 6560 6681 +chr2L 6560 6708 +chr2L 6560 6704 +chr2L 6557 6705 +chr2L 6567 6707 +chr2L 6564 6710 +chr2L 6575 6727 +chr2L 6576 6721 +chr2L 6576 6723 +chr2L 6579 6727 +chr2L 6579 6688 +chr2L 6579 6708 +chr2L 6587 6720 +chr2L 6590 6658 +chr2L 6591 6704 +chr2L 6591 6753 +chr2L 6592 6714 +chr2L 6592 6752 +chr2L 6595 6809 +chr2L 6595 6741 +chr2L 6592 6752 +chr2L 6592 6894 +chr2L 6595 6739 +chr2L 6595 6781 +chr2L 6603 6705 +chr2L 6607 6779 +chr2L 6604 6704 +chr2L 6607 6779 +chr2L 6614 6783 +chr2L 6616 6764 +chr2L 6632 6780 +chr2L 6632 6797 +chr2L 6633 6797 +chr2L 6633 6809 +chr2L 6633 6780 +chr2L 6633 6780 +chr2L 6633 6780 +chr2L 6638 6780 +chr2L 6640 6780 +chr2L 6637 6811 +chr2L 6640 6809 +chr2L 6640 6780 +chr2L 6642 6744 +chr2L 6640 6752 +chr2L 6643 6809 +chr2L 6643 6751 +chr2L 6645 6768 +chr2L 6646 6797 +chr2L 6643 6769 +chr2L 6645 6819 +chr2L 6651 6810 +chr2L 6652 6796 +chr2L 6649 6780 +chr2L 6649 6798 +chr2L 6651 6797 +chr2L 6652 6771 +chr2L 6652 6783 +chr2L 6656 6809 +chr2L 6656 6809 +chr2L 6656 6818 +chr2L 6653 6721 +chr2L 6656 6799 +chr2L 6655 6810 +chr2L 6662 6768 +chr2L 6662 6768 +chr2L 6667 6810 +chr2L 6664 6786 +chr2L 6667 6809 +chr2L 6664 6810 +chr2L 6667 6809 +chr2L 6668 6880 +chr2L 6668 6809 +chr2L 6668 6808 +chr2L 6665 6810 +chr2L 6665 6811 +chr2L 6668 6809 +chr2L 6665 6931 +chr2L 6668 6812 +chr2L 6668 6752 +chr2L 6665 6811 +chr2L 6665 6798 +chr2L 6668 6810 +chr2L 6668 6809 +chr2L 6665 6945 +chr2L 6669 6810 +chr2L 6666 6833 +chr2L 6666 6752 +chr2L 6670 6809 +chr2L 6667 6833 +chr2L 6667 6810 +chr2L 6670 6832 +chr2L 6667 6809 +chr2L 6675 6810 +chr2L 6675 6849 +chr2L 6675 6846 +chr2L 6678 6801 +chr2L 6680 6810 +chr2L 6680 6847 +chr2L 6685 6780 +chr2L 6689 6846 +chr2L 6700 6809 +chr2L 6700 6857 +chr2L 6700 6918 +chr2L 6700 6798 +chr2L 6700 6780 +chr2L 6700 6900 +chr2L 6711 6882 +chr2L 6719 6871 +chr2L 6716 6846 +chr2L 6717 6894 +chr2L 6720 6872 +chr2L 6720 6917 +chr2L 6717 6895 +chr2L 6720 6870 +chr2L 6717 6894 +chr2L 6720 6872 +chr2L 6717 6881 +chr2L 6720 6871 +chr2L 6720 6895 +chr2L 6717 6894 +chr2L 6720 6808 +chr2L 6720 6893 +chr2L 6720 6893 +chr2L 6717 6909 +chr2L 6721 6849 +chr2L 6718 6873 +chr2L 6724 6908 +chr2L 6724 6882 +chr2L 6728 6883 +chr2L 6734 6944 +chr2L 6734 6846 +chr2L 6731 6881 +chr2L 6734 6917 +chr2L 6734 6898 +chr2L 6731 6849 +chr2L 6731 6883 +chr2L 6735 6873 +chr2L 6735 6918 +chr2L 6735 6880 +chr2L 6732 6875 +chr2L 6732 6881 +chr2L 6735 6894 +chr2L 6735 6894 +chr2L 6732 6878 +chr2L 6735 6880 +chr2L 6735 6898 +chr2L 6732 6881 +chr2L 6732 6895 +chr2L 6732 6884 +chr2L 6735 6893 +chr2L 6735 6895 +chr2L 6732 6810 +chr2L 6736 6895 +chr2L 6738 6882 +chr2L 6735 6899 +chr2L 6740 6894 +chr2L 6749 6897 +chr2L 6752 6898 +chr2L 6752 6893 +chr2L 6759 6874 +chr2L 6761 6909 +chr2L 6761 6900 +chr2L 6765 6908 +chr2L 6765 6895 +chr2L 6767 6893 +chr2L 6766 6933 +chr2L 6768 6948 +chr2L 6781 6929 +chr2L 6778 6940 +chr2L 6783 6955 +chr2L 6784 6939 +chr2L 6784 6931 +chr2L 6784 6937 +chr2L 6787 6938 +chr2L 6785 6916 +chr2L 6788 6919 +chr2L 6788 6917 +chr2L 6790 6938 +chr2L 6793 6939 +chr2L 6794 6917 +chr2L 6794 6938 +chr2L 6794 6931 +chr2L 6794 6929 +chr2L 6791 6897 +chr2L 6794 6939 +chr2L 6791 6937 +chr2L 6807 6895 +chr2L 6805 6994 +chr2L 6805 6947 +chr2L 6807 6931 +chr2L 6807 6991 +chr2L 6820 6939 +chr2L 6818 6950 +chr2L 6821 6945 +chr2L 6824 6940 +chr2L 6824 7002 +chr2L 6822 7004 +chr2L 6826 6938 +chr2L 6823 6940 +chr2L 6825 6939 +chr2L 6829 6966 +chr2L 6826 6991 +chr2L 6826 6910 +chr2L 6829 6950 +chr2L 6829 6929 +chr2L 6826 6956 +chr2L 6826 6952 +chr2L 6829 6938 +chr2L 6829 6947 +chr2L 6826 6945 +chr2L 6829 6929 +chr2L 6830 6938 +chr2L 6830 6939 +chr2L 6827 6919 +chr2L 6827 6946 +chr2L 6827 6964 +chr2L 6830 6938 +chr2L 6830 6938 +chr2L 6827 6991 +chr2L 6830 6938 +chr2L 6830 6945 +chr2L 6830 6959 +chr2L 6827 6971 +chr2L 6840 6930 +chr2L 6841 7003 +chr2L 6841 6943 +chr2L 6843 6961 +chr2L 6854 7014 +chr2L 6854 7003 +chr2L 6854 7036 +chr2L 6857 7016 +chr2L 6855 6987 +chr2L 6858 7002 +chr2L 6858 7016 +chr2L 6870 7017 +chr2L 6879 7034 +chr2L 6877 7027 +chr2L 6877 7036 +chr2L 6883 7002 +chr2L 6890 7035 +chr2L 6894 7026 +chr2L 6909 7016 +chr2L 6910 7054 +chr2L 6907 7056 +chr2L 6915 7086 +chr2L 6915 7059 +chr2L 6919 7054 +chr2L 6921 7035 +chr2L 6922 7085 +chr2L 6925 7005 +chr2L 6925 7019 +chr2L 6928 7067 +chr2L 6929 7071 +chr2L 6932 7053 +chr2L 6933 7084 +chr2L 6930 7084 +chr2L 6930 7088 +chr2L 6933 7083 +chr2L 6934 7054 +chr2L 6936 7083 +chr2L 6933 7004 +chr2L 6935 7085 +chr2L 6936 7059 +chr2L 6939 7098 +chr2L 6939 7121 +chr2L 6937 7075 +chr2L 6937 7056 +chr2L 6937 7057 +chr2L 6939 7077 +chr2L 6942 7034 +chr2L 6947 7053 +chr2L 6945 7086 +chr2L 6945 7086 +chr2L 6951 7036 +chr2L 6960 7144 +chr2L 6960 7107 +chr2L 6965 7094 +chr2L 6965 7088 +chr2L 6969 7144 +chr2L 6966 7055 +chr2L 6966 7085 +chr2L 6969 7144 +chr2L 6967 7129 +chr2L 6970 7084 +chr2L 6970 7144 +chr2L 6967 7095 +chr2L 6974 7107 +chr2L 6974 7115 +chr2L 6975 7066 +chr2L 6972 7116 +chr2L 6972 7115 +chr2L 6972 7116 +chr2L 6975 7145 +chr2L 6973 7122 +chr2L 6976 7131 +chr2L 6976 7145 +chr2L 6973 7089 +chr2L 6976 7107 +chr2L 6973 7122 +chr2L 6979 7116 +chr2L 6982 7172 +chr2L 6980 7124 +chr2L 6984 7093 +chr2L 6984 7144 +chr2L 6985 7124 +chr2L 6985 7124 +chr2L 6985 7118 +chr2L 6985 7147 +chr2L 6985 7107 +chr2L 6989 7172 +chr2L 6987 7145 +chr2L 6987 7153 +chr2L 6987 7145 +chr2L 6987 7125 +chr2L 6994 7164 +chr2L 6996 7172 +chr2L 6998 7118 +chr2L 6998 7118 +chr2L 7000 7175 +chr2L 7003 7145 +chr2L 7000 7096 +chr2L 7000 7175 +chr2L 7005 7147 +chr2L 7017 7145 +chr2L 7015 7175 +chr2L 7016 7109 +chr2L 7017 7149 +chr2L 7017 7175 +chr2L 7020 7152 +chr2L 7017 7148 +chr2L 7017 7120 +chr2L 7017 7175 +chr2L 7017 7145 +chr2L 7023 7176 +chr2L 7027 7162 +chr2L 7027 7198 +chr2L 7027 7174 +chr2L 7024 7199 +chr2L 7027 7164 +chr2L 7027 7174 +chr2L 7027 7164 +chr2L 7024 7199 +chr2L 7025 7173 +chr2L 7028 7152 +chr2L 7025 7165 +chr2L 7031 7145 +chr2L 7031 7176 +chr2L 7031 7175 +chr2L 7034 7119 +chr2L 7034 7145 +chr2L 7032 7199 +chr2L 7035 7175 +chr2L 7032 7175 +chr2L 7032 7145 +chr2L 7040 7144 +chr2L 7039 7173 +chr2L 7039 7189 +chr2L 7039 7189 +chr2L 7039 7146 +chr2L 7042 7330 +chr2L 7039 7199 +chr2L 7039 7188 +chr2L 7042 7174 +chr2L 7042 7164 +chr2L 7042 7174 +chr2L 7043 7197 +chr2L 7043 7174 +chr2L 7043 7209 +chr2L 7040 7210 +chr2L 7043 7229 +chr2L 7040 7173 +chr2L 7043 7198 +chr2L 7040 7219 +chr2L 7040 7189 +chr2L 7051 7174 +chr2L 7051 7210 +chr2L 7051 7198 +chr2L 7051 7199 +chr2L 7052 7209 +chr2L 7055 7206 +chr2L 7052 7219 +chr2L 7063 7246 +chr2L 7068 7172 +chr2L 7068 7152 +chr2L 7065 7145 +chr2L 7065 7206 +chr2L 7066 7189 +chr2L 7067 7200 +chr2L 7070 7203 +chr2L 7067 7199 +chr2L 7075 7219 +chr2L 7076 7129 +chr2L 7077 7187 +chr2L 7077 7262 +chr2L 7077 7175 +chr2L 7075 7230 +chr2L 7078 7164 +chr2L 7078 7183 +chr2L 7076 7202 +chr2L 7079 7193 +chr2L 7079 7200 +chr2L 7077 7229 +chr2L 7083 7240 +chr2L 7080 7241 +chr2L 7084 7197 +chr2L 7085 7206 +chr2L 7085 7218 +chr2L 7085 7174 +chr2L 7086 7218 +chr2L 7092 7240 +chr2L 7096 7240 +chr2L 7093 7200 +chr2L 7095 7241 +chr2L 7099 7263 +chr2L 7102 7242 +chr2L 7105 7218 +chr2L 7105 7245 +chr2L 7107 7262 +chr2L 7105 7240 +chr2L 7108 7232 +chr2L 7108 7205 +chr2L 7105 7246 +chr2L 7105 7224 +chr2L 7108 7214 +chr2L 7105 7264 +chr2L 7108 7212 +chr2L 7107 7230 +chr2L 7110 7196 +chr2L 7107 7233 +chr2L 7110 7228 +chr2L 7111 7241 +chr2L 7112 7246 +chr2L 7127 7270 +chr2L 7127 7263 +chr2L 7130 7285 +chr2L 7130 7241 +chr2L 7131 7271 +chr2L 7131 7199 +chr2L 7131 7246 +chr2L 7131 7310 +chr2L 7132 7241 +chr2L 7135 7270 +chr2L 7135 7327 +chr2L 7132 7272 +chr2L 7132 7271 +chr2L 7135 7295 +chr2L 7132 7242 +chr2L 7139 7233 +chr2L 7142 7302 +chr2L 7143 7252 +chr2L 7143 7329 +chr2L 7143 7284 +chr2L 7143 7263 +chr2L 7142 7285 +chr2L 7145 7327 +chr2L 7145 7277 +chr2L 7152 7250 +chr2L 7156 7302 +chr2L 7153 7330 +chr2L 7158 7327 +chr2L 7158 7302 +chr2L 7156 7328 +chr2L 7156 7330 +chr2L 7156 7330 +chr2L 7159 7330 +chr2L 7161 7270 +chr2L 7162 7329 +chr2L 7160 7287 +chr2L 7163 7329 +chr2L 7160 7314 +chr2L 7163 7327 +chr2L 7163 7302 +chr2L 7165 7330 +chr2L 7162 7325 +chr2L 7162 7316 +chr2L 7165 7263 +chr2L 7162 7316 +chr2L 7168 7322 +chr2L 7170 7305 +chr2L 7173 7329 +chr2L 7171 7256 +chr2L 7172 7315 +chr2L 7175 7330 +chr2L 7172 7330 +chr2L 7180 7329 +chr2L 7185 7359 +chr2L 7182 7350 +chr2L 7186 7330 +chr2L 7186 7307 +chr2L 7186 7376 +chr2L 7189 7349 +chr2L 7189 7327 +chr2L 7186 7333 +chr2L 7189 7335 +chr2L 7187 7338 +chr2L 7190 7349 +chr2L 7187 7333 +chr2L 7187 7315 +chr2L 7187 7369 +chr2L 7194 7284 +chr2L 7192 7352 +chr2L 7192 7351 +chr2L 7196 7330 +chr2L 7196 7359 +chr2L 7194 7350 +chr2L 7197 7352 +chr2L 7206 7330 +chr2L 7211 7327 +chr2L 7211 7359 +chr2L 7212 7405 +chr2L 7220 7329 +chr2L 7218 7330 +chr2L 7226 7405 +chr2L 7227 7405 +chr2L 7227 7330 +chr2L 7230 7395 +chr2L 7230 7376 +chr2L 7227 7383 +chr2L 7230 7376 +chr2L 7227 7330 +chr2L 7228 7376 +chr2L 7228 7377 +chr2L 7228 7353 +chr2L 7231 7376 +chr2L 7231 7371 +chr2L 7228 7332 +chr2L 7228 7351 +chr2L 7228 7372 +chr2L 7228 7391 +chr2L 7241 7393 +chr2L 7238 7330 +chr2L 7241 7376 +chr2L 7238 7330 +chr2L 7238 7376 +chr2L 7238 7406 +chr2L 7238 7349 +chr2L 7238 7383 +chr2L 7241 7370 +chr2L 7242 7419 +chr2L 7242 7399 +chr2L 7239 7371 +chr2L 7242 7376 +chr2L 7242 7404 +chr2L 7239 7394 +chr2L 7239 7351 +chr2L 7239 7330 +chr2L 7246 7395 +chr2L 7259 7448 +chr2L 7259 7407 +chr2L 7259 7407 +chr2L 7259 7384 +chr2L 7259 7409 +chr2L 7260 7401 +chr2L 7263 7375 +chr2L 7263 7426 +chr2L 7260 7376 +chr2L 7260 7427 +chr2L 7260 7406 +chr2L 7271 7456 +chr2L 7272 7375 +chr2L 7272 7412 +chr2L 7272 7397 +chr2L 7272 7405 +chr2L 7272 7362 +chr2L 7272 7405 +chr2L 7273 7463 +chr2L 7270 7426 +chr2L 7273 7405 +chr2L 7273 7632 +chr2L 7276 7414 +chr2L 7279 7384 +chr2L 7280 7405 +chr2L 7277 7406 +chr2L 7280 7419 +chr2L 7277 7394 +chr2L 7280 7425 +chr2L 7280 7516 +chr2L 7280 7405 +chr2L 7280 7406 +chr2L 7283 7426 +chr2L 7280 7383 +chr2L 7280 7406 +chr2L 7281 7447 +chr2L 7281 7376 +chr2L 7284 7443 +chr2L 7281 7426 +chr2L 7281 7427 +chr2L 7281 7376 +chr2L 7285 7469 +chr2L 7293 7412 +chr2L 7300 7394 +chr2L 7303 7405 +chr2L 7301 7473 +chr2L 7304 7447 +chr2L 7304 7463 +chr2L 7304 7443 +chr2L 7305 7505 +chr2L 7302 7465 +chr2L 7308 7433 +chr2L 7311 7405 +chr2L 7312 7425 +chr2L 7318 7485 +chr2L 7315 7470 +chr2L 7320 7476 +chr2L 7320 7469 +chr2L 7320 7472 +chr2L 7317 7457 +chr2L 7317 7469 +chr2L 7318 7470 +chr2L 7321 7468 +chr2L 7323 7451 +chr2L 7320 7457 +chr2L 7323 7447 +chr2L 7328 7473 +chr2L 7327 7473 +chr2L 7338 7426 +chr2L 7342 7469 +chr2L 7339 7489 +chr2L 7339 7470 +chr2L 7339 7470 +chr2L 7340 7470 +chr2L 7340 7457 +chr2L 7344 7446 +chr2L 7342 7465 +chr2L 7342 7496 +chr2L 7345 7499 +chr2L 7346 7506 +chr2L 7346 7516 +chr2L 7346 7448 +chr2L 7343 7517 +chr2L 7343 7497 +chr2L 7343 7506 +chr2L 7346 7486 +chr2L 7343 7495 +chr2L 7343 7539 +chr2L 7343 7500 +chr2L 7343 7506 +chr2L 7348 7489 +chr2L 7348 7506 +chr2L 7348 7491 +chr2L 7345 7497 +chr2L 7345 7496 +chr2L 7345 7487 +chr2L 7348 7495 +chr2L 7345 7494 +chr2L 7348 7556 +chr2L 7345 7497 +chr2L 7349 7495 +chr2L 7346 7490 +chr2L 7346 7506 +chr2L 7346 7471 +chr2L 7346 7490 +chr2L 7346 7507 +chr2L 7349 7438 +chr2L 7349 7494 +chr2L 7346 7535 +chr2L 7346 7495 +chr2L 7349 7516 +chr2L 7349 7446 +chr2L 7346 7496 +chr2L 7349 7495 +chr2L 7349 7496 +chr2L 7351 7495 +chr2L 7349 7508 +chr2L 7358 7516 +chr2L 7359 7493 +chr2L 7360 7496 +chr2L 7358 7523 +chr2L 7358 7529 +chr2L 7358 7492 +chr2L 7361 7503 +chr2L 7361 7469 +chr2L 7361 7477 +chr2L 7361 7506 +chr2L 7358 7503 +chr2L 7361 7469 +chr2L 7361 7499 +chr2L 7358 7496 +chr2L 7358 7506 +chr2L 7360 7497 +chr2L 7364 7470 +chr2L 7368 7508 +chr2L 7365 7496 +chr2L 7368 7517 +chr2L 7368 7498 +chr2L 7369 7535 +chr2L 7372 7499 +chr2L 7372 7508 +chr2L 7372 7517 +chr2L 7372 7538 +chr2L 7373 7517 +chr2L 7376 7530 +chr2L 7377 7516 +chr2L 7377 7534 +chr2L 7374 7496 +chr2L 7374 7504 +chr2L 7374 7518 +chr2L 7374 7536 +chr2L 7378 7505 +chr2L 7375 7504 +chr2L 7375 7506 +chr2L 7375 7518 +chr2L 7385 7505 +chr2L 7386 7495 +chr2L 7386 7516 +chr2L 7383 7517 +chr2L 7383 7549 +chr2L 7383 7517 +chr2L 7383 7535 +chr2L 7386 7495 +chr2L 7394 7488 +chr2L 7391 7506 +chr2L 7391 7507 +chr2L 7391 7536 +chr2L 7394 7516 +chr2L 7391 7538 +chr2L 7394 7506 +chr2L 7391 7535 +chr2L 7396 7535 +chr2L 7393 7549 +chr2L 7394 7536 +chr2L 7400 7506 +chr2L 7402 7509 +chr2L 7400 7561 +chr2L 7403 7534 +chr2L 7403 7534 +chr2L 7400 7538 +chr2L 7403 7550 +chr2L 7405 7538 +chr2L 7405 7551 +chr2L 7406 7550 +chr2L 7409 7528 +chr2L 7409 7528 +chr2L 7415 7556 +chr2L 7415 7559 +chr2L 7416 7566 +chr2L 7418 7566 +chr2L 7422 7534 +chr2L 7423 7495 +chr2L 7423 7597 +chr2L 7423 7539 +chr2L 7426 7551 +chr2L 7426 7537 +chr2L 7423 7535 +chr2L 7423 7535 +chr2L 7426 7593 +chr2L 7427 7557 +chr2L 7427 7557 +chr2L 7427 7580 +chr2L 7425 7594 +chr2L 7425 7551 +chr2L 7428 7527 +chr2L 7426 7585 +chr2L 7432 7562 +chr2L 7433 7577 +chr2L 7438 7534 +chr2L 7438 7563 +chr2L 7437 7593 +chr2L 7445 7623 +chr2L 7445 7602 +chr2L 7446 7538 +chr2L 7454 7618 +chr2L 7454 7551 +chr2L 7455 7633 +chr2L 7463 7623 +chr2L 7470 7617 +chr2L 7471 7633 +chr2L 7468 7594 +chr2L 7468 7618 +chr2L 7477 7633 +chr2L 7477 7626 +chr2L 7477 7624 +chr2L 7480 7855 +chr2L 7483 7602 +chr2L 7483 7623 +chr2L 7481 7642 +chr2L 7484 7602 +chr2L 7483 7633 +chr2L 7486 7617 +chr2L 7483 7624 +chr2L 7487 7641 +chr2L 7484 7568 +chr2L 7487 7632 +chr2L 7484 7633 +chr2L 7487 7632 +chr2L 7484 7661 +chr2L 7487 7660 +chr2L 7484 7661 +chr2L 7487 7636 +chr2L 7484 7675 +chr2L 7489 7632 +chr2L 7489 7666 +chr2L 7494 7623 +chr2L 7494 7668 +chr2L 7495 7660 +chr2L 7492 7633 +chr2L 7492 7661 +chr2L 7495 7660 +chr2L 7497 7660 +chr2L 7495 7634 +chr2L 7505 7661 +chr2L 7505 7633 +chr2L 7506 7714 +chr2L 7511 7598 +chr2L 7514 7660 +chr2L 7513 7678 +chr2L 7517 7677 +chr2L 7514 7675 +chr2L 7517 7662 +chr2L 7514 7664 +chr2L 7514 7679 +chr2L 7514 7663 +chr2L 7514 7663 +chr2L 7517 7662 +chr2L 7514 7661 +chr2L 7517 7699 +chr2L 7517 7653 +chr2L 7518 7713 +chr2L 7515 7600 +chr2L 7515 7663 +chr2L 7515 7664 +chr2L 7515 7721 +chr2L 7515 7721 +chr2L 7518 7666 +chr2L 7521 7662 +chr2L 7521 7634 +chr2L 7521 7669 +chr2L 7524 7663 +chr2L 7524 7691 +chr2L 7524 7663 +chr2L 7524 7669 +chr2L 7521 7662 +chr2L 7521 7662 +chr2L 7521 7714 +chr2L 7525 7714 +chr2L 7522 7663 +chr2L 7525 7718 +chr2L 7525 7632 +chr2L 7522 7637 +chr2L 7522 7633 +chr2L 7522 7662 +chr2L 7522 7666 +chr2L 7522 7714 +chr2L 7525 7713 +chr2L 7522 7669 +chr2L 7525 7718 +chr2L 7522 7662 +chr2L 7526 7697 +chr2L 7530 7662 +chr2L 7527 7663 +chr2L 7530 7713 +chr2L 7527 7707 +chr2L 7544 7677 +chr2L 7545 7663 +chr2L 7542 7714 +chr2L 7542 7698 +chr2L 7546 7662 +chr2L 7546 7737 +chr2L 7543 7664 +chr2L 7546 7672 +chr2L 7549 7719 +chr2L 7550 7712 +chr2L 7550 7716 +chr2L 7547 7621 +chr2L 7548 7714 +chr2L 7548 7714 +chr2L 7551 7713 +chr2L 7551 7713 +chr2L 7551 7699 +chr2L 7548 7717 +chr2L 7551 7713 +chr2L 7551 7713 +chr2L 7552 7713 +chr2L 7549 7700 +chr2L 7552 7716 +chr2L 7552 7718 +chr2L 7555 7751 +chr2L 7558 7677 +chr2L 7558 7699 +chr2L 7556 7714 +chr2L 7556 7707 +chr2L 7559 7735 +chr2L 7559 7704 +chr2L 7559 7700 +chr2L 7563 7714 +chr2L 7560 7714 +chr2L 7561 7714 +chr2L 7561 7736 +chr2L 7561 7717 +chr2L 7561 7719 +chr2L 7564 7735 +chr2L 7561 7672 +chr2L 7564 7713 +chr2L 7561 7734 +chr2L 7564 7718 +chr2L 7561 7734 +chr2L 7564 7716 +chr2L 7565 7735 +chr2L 7566 7733 +chr2L 7566 7716 +chr2L 7563 7736 +chr2L 7568 7712 +chr2L 7569 7713 +chr2L 7569 7719 +chr2L 7569 7736 +chr2L 7572 7733 +chr2L 7569 7715 +chr2L 7573 7733 +chr2L 7573 7690 +chr2L 7573 7735 +chr2L 7570 7714 +chr2L 7573 7758 +chr2L 7571 7734 +chr2L 7574 7718 +chr2L 7572 7735 +chr2L 7575 7735 +chr2L 7572 7719 +chr2L 7575 7737 +chr2L 7575 7713 +chr2L 7575 7719 +chr2L 7576 7736 +chr2L 7585 7734 +chr2L 7588 7719 +chr2L 7592 7718 +chr2L 7599 7735 +chr2L 7599 7736 +chr2L 7603 7759 +chr2L 7603 7773 +chr2L 7603 7706 +chr2L 7606 7713 +chr2L 7603 7720 +chr2L 7606 7771 +chr2L 7609 7785 +chr2L 7609 7770 +chr2L 7606 7760 +chr2L 7610 7759 +chr2L 7607 7771 +chr2L 7607 7736 +chr2L 7610 7807 +chr2L 7607 7783 +chr2L 7607 7734 +chr2L 7610 7759 +chr2L 7607 7793 +chr2L 7610 7759 +chr2L 7608 7717 +chr2L 7608 7759 +chr2L 7618 7735 +chr2L 7620 7720 +chr2L 7626 7770 +chr2L 7623 7772 +chr2L 7627 7785 +chr2L 7630 7782 +chr2L 7627 7785 +chr2L 7631 7782 +chr2L 7628 7783 +chr2L 7628 7780 +chr2L 7631 7759 +chr2L 7629 7783 +chr2L 7642 7797 +chr2L 7639 7772 +chr2L 7641 7805 +chr2L 7644 7807 +chr2L 7644 7770 +chr2L 7642 7816 +chr2L 7648 7819 +chr2L 7645 7774 +chr2L 7648 7819 +chr2L 7646 7798 +chr2L 7646 7832 +chr2L 7646 7818 +chr2L 7651 7758 +chr2L 7669 7826 +chr2L 7669 7796 +chr2L 7669 7798 +chr2L 7669 7811 +chr2L 7669 7818 +chr2L 7677 7817 +chr2L 7674 7845 +chr2L 7678 7854 +chr2L 7675 7818 +chr2L 7675 7842 +chr2L 7678 7797 +chr2L 7678 7841 +chr2L 7675 7824 +chr2L 7675 7842 +chr2L 7675 7824 +chr2L 7684 7879 +chr2L 7684 7879 +chr2L 7681 7786 +chr2L 7684 7857 +chr2L 7681 7872 +chr2L 7684 7782 +chr2L 7694 7858 +chr2L 7705 7859 +chr2L 7707 7879 +chr2L 7707 7859 +chr2L 7707 7879 +chr2L 7709 7855 +chr2L 7712 7857 +chr2L 7712 7854 +chr2L 7716 7885 +chr2L 7727 7859 +chr2L 7729 7855 +chr2L 7726 7818 +chr2L 7730 7877 +chr2L 7731 7880 +chr2L 7728 7860 +chr2L 7731 7880 +chr2L 7729 7855 +chr2L 7730 7895 +chr2L 7730 7928 +chr2L 7733 7857 +chr2L 7733 7910 +chr2L 7733 7879 +chr2L 7733 7899 +chr2L 7730 7887 +chr2L 7730 7880 +chr2L 7732 7868 +chr2L 7740 7877 +chr2L 7740 7900 +chr2L 7740 7881 +chr2L 7740 7903 +chr2L 7743 7841 +chr2L 7743 7910 +chr2L 7743 7899 +chr2L 7740 7928 +chr2L 7743 7899 +chr2L 7743 7893 +chr2L 7744 7926 +chr2L 7744 7926 +chr2L 7744 7867 +chr2L 7741 7856 +chr2L 7744 7885 +chr2L 7742 7910 +chr2L 7743 7855 +chr2L 7763 7927 +chr2L 7763 7927 +chr2L 7768 7926 +chr2L 7766 7928 +chr2L 7766 7928 +chr2L 7766 7928 +chr2L 7769 7899 +chr2L 7766 7927 +chr2L 7769 7927 +chr2L 7770 7888 +chr2L 7777 7928 +chr2L 7777 7927 +chr2L 7777 7910 +chr2L 7777 7958 +chr2L 7777 7928 +chr2L 7781 7886 +chr2L 7781 7951 +chr2L 7781 7927 +chr2L 7779 7966 +chr2L 7782 7965 +chr2L 7783 7887 +chr2L 7789 7990 +chr2L 7792 7966 +chr2L 7793 8224 +chr2L 7793 7952 +chr2L 7793 7952 +chr2L 7793 7926 +chr2L 7793 7952 +chr2L 7793 7902 +chr2L 7790 7889 +chr2L 7790 7909 +chr2L 7792 7953 +chr2L 7792 7950 +chr2L 7792 7962 +chr2L 7793 7953 +chr2L 7796 7951 +chr2L 7793 8158 +chr2L 7795 7966 +chr2L 7802 7928 +chr2L 7805 7965 +chr2L 7811 8205 +chr2L 7811 7954 +chr2L 7810 7960 +chr2L 7816 7965 +chr2L 7816 7927 +chr2L 7818 8003 +chr2L 7822 7997 +chr2L 7827 8005 +chr2L 7826 7997 +chr2L 7829 8033 +chr2L 7832 8002 +chr2L 7832 8005 +chr2L 7829 8005 +chr2L 7829 8003 +chr2L 7834 8015 +chr2L 7834 8005 +chr2L 7849 8004 +chr2L 7852 8053 +chr2L 7853 8004 +chr2L 7853 8005 +chr2L 7854 7996 +chr2L 7851 8003 +chr2L 7857 7997 +chr2L 7866 8002 +chr2L 7863 8016 +chr2L 7864 8034 +chr2L 7866 8016 +chr2L 7869 8032 +chr2L 7869 8033 +chr2L 7870 8036 +chr2L 7870 8069 +chr2L 7874 8060 +chr2L 7883 8068 +chr2L 7883 8033 +chr2L 7887 8004 +chr2L 7887 8021 +chr2L 7884 8034 +chr2L 7887 8069 +chr2L 7887 8005 +chr2L 7894 8037 +chr2L 7895 8034 +chr2L 7892 8050 +chr2L 7895 8049 +chr2L 7892 8052 +chr2L 7892 8032 +chr2L 7908 8053 +chr2L 7908 8053 +chr2L 7905 8089 +chr2L 7913 8094 +chr2L 7914 8089 +chr2L 7914 8070 +chr2L 7917 8053 +chr2L 7917 8075 +chr2L 7917 8068 +chr2L 7916 8071 +chr2L 7916 8069 +chr2L 7916 8077 +chr2L 7916 8070 +chr2L 7916 8102 +chr2L 7919 8089 +chr2L 7921 8068 +chr2L 7924 8075 +chr2L 7930 8069 +chr2L 7934 8109 +chr2L 7934 8095 +chr2L 7931 8070 +chr2L 7934 8074 +chr2L 7931 8110 +chr2L 7934 8088 +chr2L 7931 8129 +chr2L 7934 8102 +chr2L 7934 8097 +chr2L 7931 8089 +chr2L 7931 8084 +chr2L 7932 8033 +chr2L 7935 8109 +chr2L 7932 8092 +chr2L 7932 8116 +chr2L 7935 8074 +chr2L 7935 8068 +chr2L 7935 8037 +chr2L 7933 8069 +chr2L 7933 8116 +chr2L 7936 8117 +chr2L 7933 8117 +chr2L 7936 8090 +chr2L 7937 8056 +chr2L 7947 8116 +chr2L 7957 8091 +chr2L 7954 8110 +chr2L 7954 8076 +chr2L 7958 8116 +chr2L 7955 8116 +chr2L 7955 8115 +chr2L 7955 8089 +chr2L 7961 8110 +chr2L 7958 8076 +chr2L 7958 8108 +chr2L 7961 8139 +chr2L 7961 8156 +chr2L 7963 8106 +chr2L 7962 8117 +chr2L 7965 8116 +chr2L 7968 8127 +chr2L 7965 8117 +chr2L 7970 8115 +chr2L 7970 8107 +chr2L 7977 8156 +chr2L 7974 8129 +chr2L 7977 8125 +chr2L 7974 8157 +chr2L 7974 8117 +chr2L 7974 8146 +chr2L 7974 8140 +chr2L 7978 8116 +chr2L 7978 8107 +chr2L 7979 8106 +chr2L 7984 8117 +chr2L 7987 8146 +chr2L 7984 8103 +chr2L 7987 8130 +chr2L 7993 8140 +chr2L 8003 8156 +chr2L 8005 8164 +chr2L 8007 8299 +chr2L 8013 8156 +chr2L 8014 8157 +chr2L 8014 8173 +chr2L 8014 8190 +chr2L 8014 8115 +chr2L 8011 8158 +chr2L 8014 8142 +chr2L 8012 8165 +chr2L 8012 8157 +chr2L 8012 8158 +chr2L 8013 8241 +chr2L 8013 8157 +chr2L 8016 8184 +chr2L 8016 8181 +chr2L 8016 8184 +chr2L 8014 8124 +chr2L 8014 8157 +chr2L 8021 8184 +chr2L 8022 8135 +chr2L 8020 8174 +chr2L 8020 8186 +chr2L 8023 8207 +chr2L 8020 8175 +chr2L 8020 8185 +chr2L 8020 8157 +chr2L 8023 8206 +chr2L 8023 8156 +chr2L 8020 8207 +chr2L 8023 8228 +chr2L 8020 8107 +chr2L 8023 8174 +chr2L 8020 8174 +chr2L 8020 8158 +chr2L 8024 8173 +chr2L 8025 8158 +chr2L 8028 8173 +chr2L 8029 8184 +chr2L 8029 8184 +chr2L 8030 8184 +chr2L 8040 8139 +chr2L 8045 8184 +chr2L 8042 8186 +chr2L 8046 8184 +chr2L 8043 8225 +chr2L 8046 8156 +chr2L 8043 8175 +chr2L 8043 8208 +chr2L 8046 8184 +chr2L 8047 8184 +chr2L 8047 8207 +chr2L 8061 8233 +chr2L 8058 8246 +chr2L 8062 8206 +chr2L 8062 8207 +chr2L 8081 8233 +chr2L 8079 8247 +chr2L 8079 8273 +chr2L 8083 8233 +chr2L 8080 8229 +chr2L 8083 8275 +chr2L 8082 8231 +chr2L 8085 8275 +chr2L 8082 8234 +chr2L 8085 8275 +chr2L 8082 8276 +chr2L 8082 8229 +chr2L 8089 8235 +chr2L 8089 8257 +chr2L 8091 8246 +chr2L 8096 8271 +chr2L 8099 8240 +chr2L 8100 8234 +chr2L 8100 8256 +chr2L 8102 8273 +chr2L 8105 8273 +chr2L 8105 8273 +chr2L 8112 8272 +chr2L 8113 8276 +chr2L 8115 8273 +chr2L 8115 8295 +chr2L 8115 8308 +chr2L 8115 8273 +chr2L 8118 8275 +chr2L 8124 8273 +chr2L 8122 8250 +chr2L 8126 8230 +chr2L 8128 8235 +chr2L 8132 8273 +chr2L 8133 8323 +chr2L 8133 8299 +chr2L 8133 8277 +chr2L 8136 8272 +chr2L 8137 8298 +chr2L 8134 8274 +chr2L 8137 8297 +chr2L 8134 8273 +chr2L 8134 8294 +chr2L 8137 8298 +chr2L 8134 8274 +chr2L 8137 8272 +chr2L 8137 8307 +chr2L 8135 8273 +chr2L 8138 8294 +chr2L 8138 8297 +chr2L 8138 8272 +chr2L 8138 8272 +chr2L 8135 8278 +chr2L 8139 8297 +chr2L 8139 8294 +chr2L 8139 8298 +chr2L 8139 8273 +chr2L 8147 8298 +chr2L 8144 8273 +chr2L 8144 8294 +chr2L 8144 8286 +chr2L 8144 8273 +chr2L 8147 8298 +chr2L 8144 8298 +chr2L 8147 8307 +chr2L 8148 8275 +chr2L 8148 8256 +chr2L 8145 8242 +chr2L 8145 8278 +chr2L 8148 8239 +chr2L 8145 8294 +chr2L 8145 8274 +chr2L 8145 8299 +chr2L 8148 8272 +chr2L 8146 8276 +chr2L 8146 8280 +chr2L 8149 8298 +chr2L 8154 8308 +chr2L 8154 8331 +chr2L 8156 8275 +chr2L 8158 8320 +chr2L 8165 8298 +chr2L 8165 8273 +chr2L 8165 8320 +chr2L 8162 8441 +chr2L 8166 8298 +chr2L 8166 8346 +chr2L 8166 8320 +chr2L 8167 8345 +chr2L 8164 8390 +chr2L 8164 8321 +chr2L 8167 8320 +chr2L 8164 8298 +chr2L 8164 8298 +chr2L 8164 8321 +chr2L 8164 8298 +chr2L 8164 8321 +chr2L 8167 8335 +chr2L 8164 8358 +chr2L 8164 8336 +chr2L 8167 8323 +chr2L 8167 8325 +chr2L 8164 8336 +chr2L 8173 8256 +chr2L 8170 8277 +chr2L 8173 8277 +chr2L 8174 8327 +chr2L 8181 8336 +chr2L 8184 8272 +chr2L 8185 8308 +chr2L 8185 8335 +chr2L 8185 8369 +chr2L 8185 8298 +chr2L 8182 8346 +chr2L 8186 8350 +chr2L 8190 8309 +chr2L 8190 8330 +chr2L 8190 8300 +chr2L 8191 8346 +chr2L 8191 8356 +chr2L 8194 8345 +chr2L 8191 8347 +chr2L 8194 8388 +chr2L 8191 8330 +chr2L 8193 8344 +chr2L 8193 8340 +chr2L 8196 8343 +chr2L 8193 8341 +chr2L 8193 8356 +chr2L 8196 8355 +chr2L 8210 8347 +chr2L 8214 8355 +chr2L 8214 8389 +chr2L 8214 8377 +chr2L 8211 8390 +chr2L 8214 8355 +chr2L 8214 8389 +chr2L 8223 8369 +chr2L 8223 8388 +chr2L 8220 8391 +chr2L 8223 8344 +chr2L 8227 8377 +chr2L 8224 8336 +chr2L 8225 8396 +chr2L 8229 8390 +chr2L 8234 8369 +chr2L 8234 8388 +chr2L 8234 8398 +chr2L 8233 8379 +chr2L 8233 8358 +chr2L 8239 8417 +chr2L 8239 8389 +chr2L 8244 8399 +chr2L 8244 8390 +chr2L 8247 8716 +chr2L 8247 8388 +chr2L 8248 8390 +chr2L 8248 8388 +chr2L 8248 8389 +chr2L 8248 8388 +chr2L 8248 8390 +chr2L 8248 8395 +chr2L 8252 8398 +chr2L 8252 8395 +chr2L 8249 8399 +chr2L 8249 8426 +chr2L 8262 8387 +chr2L 8265 8417 +chr2L 8265 8416 +chr2L 8262 8431 +chr2L 8265 8388 +chr2L 8262 8563 +chr2L 8266 8399 +chr2L 8266 8417 +chr2L 8279 8418 +chr2L 8283 8430 +chr2L 8284 8451 +chr2L 8283 8399 +chr2L 8286 8462 +chr2L 8283 8436 +chr2L 8285 8435 +chr2L 8285 8418 +chr2L 8286 8441 +chr2L 8289 8454 +chr2L 8289 8429 +chr2L 8286 8425 +chr2L 8286 8389 +chr2L 8289 8424 +chr2L 8289 8377 +chr2L 8289 8430 +chr2L 8289 8416 +chr2L 8286 8436 +chr2L 8289 8435 +chr2L 8289 8441 +chr2L 8289 8441 +chr2L 8289 8421 +chr2L 8289 8418 +chr2L 8289 8470 +chr2L 8289 8451 +chr2L 8289 8416 +chr2L 8288 8441 +chr2L 8288 8651 +chr2L 8288 8400 +chr2L 8288 8452 +chr2L 8288 8436 +chr2L 8290 8436 +chr2L 8294 8454 +chr2L 8294 8389 +chr2L 8294 8440 +chr2L 8291 8438 +chr2L 8294 8405 +chr2L 8294 8451 +chr2L 8295 8405 +chr2L 8300 8471 +chr2L 8306 8452 +chr2L 8306 8481 +chr2L 8307 8438 +chr2L 8307 8465 +chr2L 8307 8455 +chr2L 8307 8441 +chr2L 8307 8463 +chr2L 8310 8454 +chr2L 8310 8471 +chr2L 8310 8469 +chr2L 8310 8470 +chr2L 8307 8456 +chr2L 8307 8418 +chr2L 8313 8447 +chr2L 8311 8442 +chr2L 8313 8501 +chr2L 8328 8442 +chr2L 8337 8435 +chr2L 8338 8690 +chr2L 8338 8623 +chr2L 8335 8490 +chr2L 8340 8508 +chr2L 8340 8500 +chr2L 8345 8499 +chr2L 8345 8500 +chr2L 8342 8501 +chr2L 8346 8499 +chr2L 8346 8531 +chr2L 8343 8519 +chr2L 8346 8464 +chr2L 8354 8490 +chr2L 8357 8530 +chr2L 8357 8435 +chr2L 8354 8496 +chr2L 8357 8471 +chr2L 8357 8522 +chr2L 8355 8500 +chr2L 8355 8525 +chr2L 8358 8506 +chr2L 8358 8500 +chr2L 8355 8523 +chr2L 8355 8471 +chr2L 8355 8500 +chr2L 8358 8524 +chr2L 8358 8499 +chr2L 8355 8500 +chr2L 8358 8501 +chr2L 8360 8520 +chr2L 8360 8500 +chr2L 8360 8530 +chr2L 8366 8499 +chr2L 8363 8532 +chr2L 8366 8532 +chr2L 8371 8472 +chr2L 8384 8500 +chr2L 8387 8554 +chr2L 8385 8571 +chr2L 8386 8502 +chr2L 8396 8499 +chr2L 8397 8555 +chr2L 8394 8502 +chr2L 8396 8500 +chr2L 8396 8555 +chr2L 8402 8555 +chr2L 8402 8561 +chr2L 8402 8556 +chr2L 8402 8555 +chr2L 8402 8562 +chr2L 8403 8588 +chr2L 8403 8562 +chr2L 8403 8556 +chr2L 8406 8561 +chr2L 8406 8576 +chr2L 8408 8540 +chr2L 8408 8554 +chr2L 8409 8555 +chr2L 8406 8561 +chr2L 8409 8530 +chr2L 8406 8596 +chr2L 8411 8531 +chr2L 8408 8558 +chr2L 8411 8598 +chr2L 8412 8568 +chr2L 8412 8588 +chr2L 8412 8594 +chr2L 8409 8561 +chr2L 8409 8578 +chr2L 8409 8555 +chr2L 8409 8574 +chr2L 8409 8569 +chr2L 8411 8578 +chr2L 8411 8574 +chr2L 8411 8563 +chr2L 8414 8555 +chr2L 8415 8561 +chr2L 8423 8598 +chr2L 8424 8562 +chr2L 8421 8577 +chr2L 8427 8562 +chr2L 8427 8598 +chr2L 8427 8576 +chr2L 8425 8579 +chr2L 8425 8579 +chr2L 8430 8578 +chr2L 8435 8598 +chr2L 8433 8589 +chr2L 8436 8590 +chr2L 8433 8600 +chr2L 8433 8595 +chr2L 8433 8599 +chr2L 8433 8599 +chr2L 8438 8598 +chr2L 8438 8598 +chr2L 8438 8555 +chr2L 8441 8598 +chr2L 8440 8588 +chr2L 8443 8556 +chr2L 8443 8587 +chr2L 8444 8587 +chr2L 8441 8562 +chr2L 8445 8577 +chr2L 8446 8651 +chr2L 8446 8590 +chr2L 8446 8598 +chr2L 8447 8575 +chr2L 8447 8657 +chr2L 8450 8598 +chr2L 8447 8598 +chr2L 8447 8623 +chr2L 8447 8599 +chr2L 8450 8598 +chr2L 8447 8563 +chr2L 8450 8531 +chr2L 8447 8600 +chr2L 8447 8580 +chr2L 8447 8562 +chr2L 8447 8599 +chr2L 8447 8623 +chr2L 8450 8598 +chr2L 8450 8589 +chr2L 8450 8597 +chr2L 8450 8598 +chr2L 8447 8596 +chr2L 8450 8650 +chr2L 8447 8596 +chr2L 8451 8598 +chr2L 8450 8599 +chr2L 8450 8599 +chr2L 8450 8599 +chr2L 8450 8600 +chr2L 8453 8648 +chr2L 8455 8577 +chr2L 8458 8623 +chr2L 8458 8598 +chr2L 8458 8622 +chr2L 8455 8602 +chr2L 8461 8595 +chr2L 8458 8589 +chr2L 8458 8590 +chr2L 8459 8623 +chr2L 8459 8624 +chr2L 8462 8622 +chr2L 8462 8573 +chr2L 8462 8597 +chr2L 8459 8624 +chr2L 8462 8597 +chr2L 8460 8588 +chr2L 8460 8648 +chr2L 8465 8646 +chr2L 8465 8602 +chr2L 8470 8597 +chr2L 8471 8598 +chr2L 8468 8623 +chr2L 8471 8622 +chr2L 8471 8597 +chr2L 8468 8668 +chr2L 8471 8597 +chr2L 8476 8651 +chr2L 8477 8598 +chr2L 8478 8633 +chr2L 8481 8607 +chr2L 8483 8600 +chr2L 8486 8613 +chr2L 8498 8658 +chr2L 8501 8648 +chr2L 8498 8625 +chr2L 8498 8623 +chr2L 8501 8657 +chr2L 8501 8650 +chr2L 8507 8649 +chr2L 8508 8647 +chr2L 8508 8668 +chr2L 8505 8657 +chr2L 8508 8633 +chr2L 8507 8691 +chr2L 8507 8674 +chr2L 8510 8657 +chr2L 8513 8667 +chr2L 8516 8666 +chr2L 8516 8658 +chr2L 8516 8708 +chr2L 8513 8599 +chr2L 8517 8688 +chr2L 8517 8690 +chr2L 8514 8657 +chr2L 8517 8657 +chr2L 8516 8675 +chr2L 8519 8716 +chr2L 8519 8647 +chr2L 8516 8657 +chr2L 8519 8647 +chr2L 8518 8650 +chr2L 8521 8688 +chr2L 8522 8667 +chr2L 8528 8659 +chr2L 8529 8650 +chr2L 8532 8681 +chr2L 8533 8647 +chr2L 8534 8693 +chr2L 8538 8657 +chr2L 8536 8717 +chr2L 8539 8702 +chr2L 8539 8707 +chr2L 8541 8693 +chr2L 8538 8708 +chr2L 8538 8708 +chr2L 8541 8707 +chr2L 8541 8651 +chr2L 8538 8677 +chr2L 8543 8707 +chr2L 8540 8658 +chr2L 8540 8708 +chr2L 8540 8716 +chr2L 8552 8717 +chr2L 8563 8648 +chr2L 8564 8690 +chr2L 8565 8666 +chr2L 8565 8666 +chr2L 8571 8707 +chr2L 8571 8715 +chr2L 8571 8692 +chr2L 8568 8688 +chr2L 8568 8723 +chr2L 8571 8692 +chr2L 8569 8659 +chr2L 8569 8719 +chr2L 8569 8708 +chr2L 8573 8666 +chr2L 8574 8717 +chr2L 8571 8679 +chr2L 8574 8755 +chr2L 8573 8749 +chr2L 8584 8750 +chr2L 8587 8736 +chr2L 8587 8909 +chr2L 8584 8717 +chr2L 8588 8717 +chr2L 8588 8749 +chr2L 8588 8717 +chr2L 8587 8750 +chr2L 8596 8735 +chr2L 8593 8747 +chr2L 8596 8717 +chr2L 8607 8751 +chr2L 8611 8716 +chr2L 8611 8749 +chr2L 8613 8758 +chr2L 8610 8719 +chr2L 8611 8756 +chr2L 8611 8802 +chr2L 8614 8787 +chr2L 8614 8716 +chr2L 8611 8737 +chr2L 8614 8755 +chr2L 8611 8759 +chr2L 8614 8773 +chr2L 8614 8800 +chr2L 8614 8718 +chr2L 8614 8738 +chr2L 8619 8788 +chr2L 8616 8776 +chr2L 8617 8790 +chr2L 8621 8804 +chr2L 8621 8750 +chr2L 8626 8772 +chr2L 8630 8767 +chr2L 8632 8757 +chr2L 8634 8758 +chr2L 8635 8801 +chr2L 8633 8813 +chr2L 8636 8815 +chr2L 8636 8787 +chr2L 8641 8822 +chr2L 8638 8823 +chr2L 8668 8814 +chr2L 8668 8801 +chr2L 8668 8821 +chr2L 8668 8786 +chr2L 8665 8813 +chr2L 8665 8815 +chr2L 8668 8747 +chr2L 8665 8815 +chr2L 8668 8821 +chr2L 8665 8830 +chr2L 8665 8774 +chr2L 8668 8821 +chr2L 8666 8822 +chr2L 8666 8823 +chr2L 8669 8773 +chr2L 8666 8813 +chr2L 8666 8772 +chr2L 8669 8812 +chr2L 8669 8822 +chr2L 8669 8821 +chr2L 8666 8822 +chr2L 8669 8802 +chr2L 8672 8790 +chr2L 8676 8822 +chr2L 8679 8815 +chr2L 8682 8812 +chr2L 8682 8822 +chr2L 8682 8822 +chr2L 8684 8821 +chr2L 8684 8813 +chr2L 8685 8822 +chr2L 8685 8830 +chr2L 8689 8849 +chr2L 8690 8802 +chr2L 8690 8869 +chr2L 8690 8815 +chr2L 8690 8888 +chr2L 8688 8879 +chr2L 8694 8822 +chr2L 8701 8821 +chr2L 8701 8852 +chr2L 8698 8888 +chr2L 8698 8888 +chr2L 8702 8869 +chr2L 8703 8822 +chr2L 8703 8822 +chr2L 8708 8871 +chr2L 8710 8871 +chr2L 8712 8897 +chr2L 8712 8870 +chr2L 8716 8871 +chr2L 8716 8821 +chr2L 8716 8865 +chr2L 8713 8870 +chr2L 8713 8871 +chr2L 8716 8822 +chr2L 8716 8821 +chr2L 8716 8869 +chr2L 8713 8870 +chr2L 8713 8870 +chr2L 8716 8870 +chr2L 8716 8870 +chr2L 8716 9038 +chr2L 8722 8870 +chr2L 8725 8870 +chr2L 8726 8854 +chr2L 8726 8888 +chr2L 8729 8829 +chr2L 8726 8888 +chr2L 8727 8882 +chr2L 8727 8888 +chr2L 8730 8887 +chr2L 8730 8878 +chr2L 8727 8913 +chr2L 8730 8852 +chr2L 8727 8862 +chr2L 8727 8888 +chr2L 8730 8911 +chr2L 8730 8865 +chr2L 8730 8887 +chr2L 8727 8888 +chr2L 8730 8896 +chr2L 8727 8871 +chr2L 8733 8912 +chr2L 8736 8911 +chr2L 8736 8897 +chr2L 8734 8888 +chr2L 8737 8897 +chr2L 8734 8912 +chr2L 8734 8926 +chr2L 8734 9061 +chr2L 8739 8847 +chr2L 8740 8889 +chr2L 8744 8897 +chr2L 8745 8912 +chr2L 8742 8889 +chr2L 8744 8898 +chr2L 8755 8912 +chr2L 8755 8870 +chr2L 8756 8888 +chr2L 8764 8896 +chr2L 8764 8909 +chr2L 8762 8913 +chr2L 8765 8887 +chr2L 8765 8925 +chr2L 8762 8894 +chr2L 8765 8925 +chr2L 8764 8897 +chr2L 8767 8911 +chr2L 8765 8897 +chr2L 8768 8960 +chr2L 8768 8912 +chr2L 8768 8945 +chr2L 8765 8912 +chr2L 8765 8960 +chr2L 8768 8936 +chr2L 8768 8959 +chr2L 8768 8911 +chr2L 8765 8906 +chr2L 8767 8912 +chr2L 8767 8898 +chr2L 8770 8959 +chr2L 8773 8925 +chr2L 8774 8959 +chr2L 8771 8870 +chr2L 8777 8959 +chr2L 8779 8945 +chr2L 8781 8962 +chr2L 8783 8990 +chr2L 8780 8913 +chr2L 8781 8961 +chr2L 8781 8960 +chr2L 8782 8964 +chr2L 8785 8962 +chr2L 8792 8978 +chr2L 8796 8983 +chr2L 8801 8989 +chr2L 8802 8974 +chr2L 8802 8960 +chr2L 8799 8960 +chr2L 8808 8963 +chr2L 8808 8960 +chr2L 8821 8959 +chr2L 8819 8960 +chr2L 8819 8983 +chr2L 8822 8963 +chr2L 8829 8959 +chr2L 8829 8977 +chr2L 8830 8988 +chr2L 8827 8975 +chr2L 8830 8977 +chr2L 8831 8982 +chr2L 8828 8978 +chr2L 8831 8977 +chr2L 8831 8989 +chr2L 8831 8959 +chr2L 8828 8978 +chr2L 8831 8989 +chr2L 8829 9054 +chr2L 8830 8961 +chr2L 8833 8987 +chr2L 8830 8991 +chr2L 8832 8960 +chr2L 8833 9177 +chr2L 8837 8989 +chr2L 8834 8991 +chr2L 8837 8990 +chr2L 8839 8996 +chr2L 8839 8989 +chr2L 8837 8989 +chr2L 8840 8959 +chr2L 8840 8992 +chr2L 8837 8960 +chr2L 8840 9033 +chr2L 8837 8989 +chr2L 8837 8992 +chr2L 8837 8989 +chr2L 8841 9020 +chr2L 8841 8990 +chr2L 8843 8990 +chr2L 8840 8993 +chr2L 8855 8982 +chr2L 8867 9026 +chr2L 8865 9013 +chr2L 8868 9039 +chr2L 8878 8982 +chr2L 8875 9053 +chr2L 8875 9037 +chr2L 8875 9036 +chr2L 8875 9062 +chr2L 8875 9022 +chr2L 8879 9039 +chr2L 8876 9061 +chr2L 8876 9036 +chr2L 8876 9041 +chr2L 8879 9041 +chr2L 8876 9027 +chr2L 8878 9039 +chr2L 8894 9041 +chr2L 8894 9041 +chr2L 8892 9095 +chr2L 8892 9042 +chr2L 8897 9053 +chr2L 8897 9036 +chr2L 8897 9055 +chr2L 8894 9042 +chr2L 8894 8997 +chr2L 8903 9032 +chr2L 8900 9057 +chr2L 8906 9060 +chr2L 8903 9061 +chr2L 8906 9056 +chr2L 8908 9096 +chr2L 8909 9036 +chr2L 8909 9054 +chr2L 8909 9042 +chr2L 8909 9054 +chr2L 8909 8991 +chr2L 8913 9073 +chr2L 8914 9001 +chr2L 8919 9073 +chr2L 8919 9073 +chr2L 8916 9040 +chr2L 8920 9042 +chr2L 8920 9074 +chr2L 8920 9096 +chr2L 8917 9081 +chr2L 8918 9083 +chr2L 8918 9097 +chr2L 8921 9041 +chr2L 8921 9035 +chr2L 8918 9096 +chr2L 8921 9060 +chr2L 8921 9063 +chr2L 8918 9102 +chr2L 8918 9088 +chr2L 8921 9062 +chr2L 8921 9080 +chr2L 8918 9059 +chr2L 8921 9033 +chr2L 8921 9116 +chr2L 8922 9058 +chr2L 8919 9096 +chr2L 8922 9081 +chr2L 8925 9083 +chr2L 8929 9038 +chr2L 8931 9095 +chr2L 8928 9097 +chr2L 8938 9116 +chr2L 8935 9096 +chr2L 8942 9096 +chr2L 8940 9118 +chr2L 8953 9118 +chr2L 8950 9097 +chr2L 8950 9114 +chr2L 8953 9102 +chr2L 8957 9117 +chr2L 8966 9094 +chr2L 8969 9102 +chr2L 8966 9132 +chr2L 8969 9118 +chr2L 8966 9155 +chr2L 8966 9119 +chr2L 8967 9103 +chr2L 8970 9119 +chr2L 8970 9116 +chr2L 8967 9117 +chr2L 8970 9116 +chr2L 8970 9101 +chr2L 8970 9095 +chr2L 8970 9118 +chr2L 8970 9118 +chr2L 8969 9104 +chr2L 8974 9101 +chr2L 8971 9117 +chr2L 8974 9119 +chr2L 8974 9102 +chr2L 8972 9117 +chr2L 8972 9130 +chr2L 8972 9139 +chr2L 8972 9096 +chr2L 8975 9084 +chr2L 8972 9102 +chr2L 8975 9179 +chr2L 8981 9154 +chr2L 8981 9179 +chr2L 8989 9120 +chr2L 8988 9179 +chr2L 8994 9147 +chr2L 8996 9179 +chr2L 8996 9153 +chr2L 8996 9095 +chr2L 8996 9154 +chr2L 9000 9094 +chr2L 9000 9086 +chr2L 9000 9103 +chr2L 8997 9096 +chr2L 8997 9177 +chr2L 8999 9177 +chr2L 8999 9120 +chr2L 8999 9180 +chr2L 8999 9168 +chr2L 9003 9176 +chr2L 9001 9102 +chr2L 9006 9153 +chr2L 9004 9168 +chr2L 9004 9158 +chr2L 9004 9148 +chr2L 9004 9117 +chr2L 9004 9119 +chr2L 9007 9154 +chr2L 9007 9176 +chr2L 9008 9217 +chr2L 9008 9178 +chr2L 9005 9177 +chr2L 9005 9180 +chr2L 9005 9156 +chr2L 9010 9178 +chr2L 9013 9181 +chr2L 9014 9167 +chr2L 9011 9177 +chr2L 9016 9136 +chr2L 9017 9180 +chr2L 9018 9177 +chr2L 9029 9176 +chr2L 9029 9199 +chr2L 9041 9189 +chr2L 9042 9176 +chr2L 9039 9180 +chr2L 9042 9219 +chr2L 9044 9198 +chr2L 9050 9206 +chr2L 9047 9199 +chr2L 9050 9180 +chr2L 9053 9178 +chr2L 9050 9219 +chr2L 9062 9169 +chr2L 9070 9229 +chr2L 9071 9179 +chr2L 9068 9179 +chr2L 9071 9198 +chr2L 9068 9219 +chr2L 9068 9168 +chr2L 9070 9199 +chr2L 9070 9236 +chr2L 9073 9217 +chr2L 9073 9176 +chr2L 9070 9316 +chr2L 9074 9246 +chr2L 9074 9178 +chr2L 9074 9206 +chr2L 9074 9206 +chr2L 9079 9236 +chr2L 9086 9219 +chr2L 9086 9219 +chr2L 9087 9184 +chr2L 9092 9198 +chr2L 9093 9178 +chr2L 9093 9249 +chr2L 9093 9198 +chr2L 9091 9323 +chr2L 9094 9229 +chr2L 9094 9246 +chr2L 9092 9236 +chr2L 9092 9249 +chr2L 9097 9297 +chr2L 9097 9206 +chr2L 9111 9212 +chr2L 9111 9278 +chr2L 9108 9281 +chr2L 9108 9220 +chr2L 9108 9253 +chr2L 9108 9228 +chr2L 9108 9297 +chr2L 9111 9264 +chr2L 9113 9297 +chr2L 9112 9297 +chr2L 9115 9198 +chr2L 9115 9264 +chr2L 9115 9241 +chr2L 9119 9279 +chr2L 9123 9287 +chr2L 9124 9307 +chr2L 9127 9271 +chr2L 9128 9315 +chr2L 9125 9276 +chr2L 9129 9268 +chr2L 9129 9313 +chr2L 9129 9296 +chr2L 9126 9307 +chr2L 9130 9279 +chr2L 9127 9252 +chr2L 9132 9297 +chr2L 9129 9282 +chr2L 9135 9275 +chr2L 9137 9318 +chr2L 9141 9296 +chr2L 9138 9309 +chr2L 9140 9298 +chr2L 9140 9298 +chr2L 9140 9309 +chr2L 9141 9310 +chr2L 9141 9314 +chr2L 9144 9308 +chr2L 9144 9275 +chr2L 9144 9313 +chr2L 9144 9280 +chr2L 9151 9297 +chr2L 9158 9269 +chr2L 9160 9314 +chr2L 9161 9314 +chr2L 9165 9341 +chr2L 9163 9272 +chr2L 9166 9315 +chr2L 9167 9275 +chr2L 9170 9297 +chr2L 9174 9331 +chr2L 9174 9309 +chr2L 9186 9357 +chr2L 9186 9357 +chr2L 9184 9323 +chr2L 9188 9355 +chr2L 9185 9314 +chr2L 9185 9358 +chr2L 9186 9331 +chr2L 9189 9355 +chr2L 9186 9315 +chr2L 9186 9351 +chr2L 9189 9374 +chr2L 9189 9313 +chr2L 9189 9331 +chr2L 9186 9317 +chr2L 9189 9340 +chr2L 9189 9340 +chr2L 9186 9358 +chr2L 9187 9331 +chr2L 9187 9355 +chr2L 9190 9341 +chr2L 9187 9327 +chr2L 9187 9379 +chr2L 9190 9331 +chr2L 9190 9319 +chr2L 9187 9358 +chr2L 9187 9365 +chr2L 9190 9315 +chr2L 9191 9330 +chr2L 9188 9340 +chr2L 9191 9350 +chr2L 9188 9380 +chr2L 9191 9296 +chr2L 9193 9374 +chr2L 9190 9374 +chr2L 9190 9351 +chr2L 9195 9341 +chr2L 9192 9355 +chr2L 9194 9379 +chr2L 9198 9354 +chr2L 9198 9364 +chr2L 9198 9308 +chr2L 9195 9365 +chr2L 9195 9355 +chr2L 9197 9365 +chr2L 9200 9317 +chr2L 9207 9430 +chr2L 9207 9308 +chr2L 9204 9355 +chr2L 9208 9373 +chr2L 9208 9378 +chr2L 9206 9379 +chr2L 9210 9366 +chr2L 9210 9380 +chr2L 9213 9378 +chr2L 9213 9339 +chr2L 9210 9375 +chr2L 9213 9339 +chr2L 9211 9380 +chr2L 9211 9380 +chr2L 9211 9374 +chr2L 9211 9374 +chr2L 9215 9378 +chr2L 9215 9378 +chr2L 9218 9308 +chr2L 9220 9350 +chr2L 9227 9375 +chr2L 9227 9379 +chr2L 9229 9354 +chr2L 9232 9378 +chr2L 9232 9378 +chr2L 9229 9420 +chr2L 9232 9379 +chr2L 9233 9379 +chr2L 9233 9379 +chr2L 9233 9316 +chr2L 9235 9313 +chr2L 9235 9379 +chr2L 9236 9418 +chr2L 9236 9383 +chr2L 9234 9420 +chr2L 9234 9420 +chr2L 9238 9418 +chr2L 9245 9414 +chr2L 9242 9419 +chr2L 9242 9419 +chr2L 9244 9380 +chr2L 9244 9438 +chr2L 9247 9427 +chr2L 9248 9419 +chr2L 9245 9428 +chr2L 9245 9420 +chr2L 9248 9459 +chr2L 9252 9379 +chr2L 9251 9407 +chr2L 9254 9405 +chr2L 9251 9419 +chr2L 9252 9405 +chr2L 9255 9420 +chr2L 9259 9418 +chr2L 9256 9419 +chr2L 9260 9404 +chr2L 9260 9418 +chr2L 9257 9405 +chr2L 9257 9418 +chr2L 9260 9427 +chr2L 9270 9451 +chr2L 9272 9419 +chr2L 9277 9430 +chr2L 9277 9418 +chr2L 9277 9419 +chr2L 9279 9430 +chr2L 9278 9459 +chr2L 9281 9452 +chr2L 9284 9420 +chr2L 9284 9444 +chr2L 9285 9419 +chr2L 9288 9418 +chr2L 9288 9432 +chr2L 9288 9478 +chr2L 9289 9440 +chr2L 9287 9440 +chr2L 9287 9440 +chr2L 9290 9458 +chr2L 9289 9483 +chr2L 9289 9440 +chr2L 9289 9420 +chr2L 9289 9448 +chr2L 9292 9464 +chr2L 9294 9449 +chr2L 9291 9433 +chr2L 9307 9478 +chr2L 9304 9430 +chr2L 9307 9432 +chr2L 9307 9449 +chr2L 9304 9440 +chr2L 9304 9462 +chr2L 9307 9604 +chr2L 9304 9495 +chr2L 9307 9451 +chr2L 9306 9479 +chr2L 9306 9460 +chr2L 9306 9459 +chr2L 9306 9480 +chr2L 9309 9458 +chr2L 9313 9479 +chr2L 9313 9448 +chr2L 9317 9458 +chr2L 9316 9483 +chr2L 9323 9481 +chr2L 9320 9419 +chr2L 9320 9458 +chr2L 9323 9447 +chr2L 9324 9478 +chr2L 9324 9479 +chr2L 9324 9479 +chr2L 9327 9464 +chr2L 9331 9528 +chr2L 9333 9489 +chr2L 9330 9452 +chr2L 9333 9464 +chr2L 9333 9418 +chr2L 9331 9490 +chr2L 9334 9479 +chr2L 9334 9494 +chr2L 9333 9445 +chr2L 9333 9479 +chr2L 9335 9482 +chr2L 9339 9488 +chr2L 9342 9478 +chr2L 9342 9427 +chr2L 9339 9648 +chr2L 9342 9461 +chr2L 9340 9502 +chr2L 9343 9504 +chr2L 9344 9488 +chr2L 9344 9517 +chr2L 9346 9493 +chr2L 9344 9457 +chr2L 9346 9505 +chr2L 9349 9528 +chr2L 9346 9463 +chr2L 9346 9506 +chr2L 9350 9516 +chr2L 9351 9493 +chr2L 9350 9506 +chr2L 9353 9465 +chr2L 9356 9505 +chr2L 9357 9506 +chr2L 9366 9526 +chr2L 9366 9478 +chr2L 9366 9526 +chr2L 9363 9504 +chr2L 9366 9479 +chr2L 9363 9516 +chr2L 9363 9529 +chr2L 9363 9527 +chr2L 9368 9479 +chr2L 9373 9529 +chr2L 9374 9528 +chr2L 9374 9528 +chr2L 9374 9523 +chr2L 9373 9504 +chr2L 9377 9527 +chr2L 9380 9546 +chr2L 9380 9569 +chr2L 9381 9531 +chr2L 9378 9529 +chr2L 9385 9527 +chr2L 9388 9524 +chr2L 9389 9583 +chr2L 9393 9563 +chr2L 9393 9506 +chr2L 9396 9569 +chr2L 9396 9516 +chr2L 9396 9488 +chr2L 9396 9526 +chr2L 9396 9554 +chr2L 9397 9546 +chr2L 9394 9518 +chr2L 9397 9494 +chr2L 9397 9547 +chr2L 9397 9541 +chr2L 9397 9569 +chr2L 9397 9570 +chr2L 9396 9559 +chr2L 9399 9569 +chr2L 9396 9517 +chr2L 9396 9524 +chr2L 9399 9548 +chr2L 9399 9548 +chr2L 9409 9570 +chr2L 9410 9531 +chr2L 9413 9582 +chr2L 9413 9562 +chr2L 9410 9531 +chr2L 9412 9529 +chr2L 9412 9564 +chr2L 9415 9569 +chr2L 9415 9558 +chr2L 9415 9526 +chr2L 9415 9559 +chr2L 9424 9531 +chr2L 9424 9564 +chr2L 9427 9583 +chr2L 9431 9565 +chr2L 9431 9574 +chr2L 9434 9615 +chr2L 9432 9601 +chr2L 9438 9532 +chr2L 9438 9583 +chr2L 9438 9583 +chr2L 9441 9562 +chr2L 9441 9582 +chr2L 9443 9562 +chr2L 9443 9560 +chr2L 9444 9596 +chr2L 9447 9579 +chr2L 9450 9616 +chr2L 9447 9621 +chr2L 9448 9619 +chr2L 9451 9583 +chr2L 9451 9546 +chr2L 9451 9575 +chr2L 9448 9621 +chr2L 9451 9614 +chr2L 9448 9589 +chr2L 9451 9600 +chr2L 9448 9527 +chr2L 9448 9616 +chr2L 9448 9592 +chr2L 9451 9569 +chr2L 9452 9604 +chr2L 9450 9597 +chr2L 9454 9597 +chr2L 9457 9603 +chr2L 9458 9582 +chr2L 9456 9615 +chr2L 9459 9603 +chr2L 9459 9603 +chr2L 9456 9615 +chr2L 9456 9605 +chr2L 9459 9638 +chr2L 9456 9605 +chr2L 9456 9595 +chr2L 9461 9582 +chr2L 9461 9582 +chr2L 9462 9615 +chr2L 9459 9588 +chr2L 9459 9616 +chr2L 9459 9622 +chr2L 9465 9630 +chr2L 9467 9582 +chr2L 9464 9604 +chr2L 9465 9583 +chr2L 9468 9603 +chr2L 9468 9622 +chr2L 9472 9631 +chr2L 9470 9588 +chr2L 9473 9591 +chr2L 9470 9597 +chr2L 9474 9597 +chr2L 9476 9582 +chr2L 9474 9649 +chr2L 9474 9647 +chr2L 9478 9621 +chr2L 9478 9620 +chr2L 9475 9616 +chr2L 9478 9583 +chr2L 9475 9647 +chr2L 9478 9595 +chr2L 9476 9633 +chr2L 9476 9638 +chr2L 9479 9590 +chr2L 9476 9632 +chr2L 9479 9615 +chr2L 9476 9631 +chr2L 9479 9638 +chr2L 9479 9603 +chr2L 9479 9647 +chr2L 9476 9669 +chr2L 9479 9614 +chr2L 9479 9643 +chr2L 9476 9604 +chr2L 9479 9631 +chr2L 9476 9668 +chr2L 9479 9630 +chr2L 9484 9647 +chr2L 9484 9614 +chr2L 9481 9594 +chr2L 9482 9616 +chr2L 9482 9648 +chr2L 9482 9631 +chr2L 9489 9639 +chr2L 9493 9604 +chr2L 9492 9669 +chr2L 9495 9643 +chr2L 9495 9630 +chr2L 9496 9630 +chr2L 9493 9640 +chr2L 9496 9668 +chr2L 9493 9636 +chr2L 9496 9647 +chr2L 9493 9647 +chr2L 9493 9584 +chr2L 9496 9646 +chr2L 9496 9629 +chr2L 9493 9626 +chr2L 9499 9668 +chr2L 9502 9639 +chr2L 9499 9647 +chr2L 9499 9632 +chr2L 9502 9657 +chr2L 9500 9669 +chr2L 9500 9615 +chr2L 9500 9647 +chr2L 9507 9621 +chr2L 9513 9682 +chr2L 9513 9664 +chr2L 9516 9668 +chr2L 9516 9659 +chr2L 9516 9667 +chr2L 9513 9669 +chr2L 9513 9663 +chr2L 9516 9688 +chr2L 9516 9644 +chr2L 9516 9639 +chr2L 9516 9667 +chr2L 9514 9644 +chr2L 9514 9686 +chr2L 9514 9663 +chr2L 9514 9668 +chr2L 9517 9662 +chr2L 9514 9658 +chr2L 9517 9651 +chr2L 9521 9669 +chr2L 9521 9668 +chr2L 9524 9668 +chr2L 9526 9668 +chr2L 9538 9646 +chr2L 9535 9682 +chr2L 9536 9678 +chr2L 9540 9664 +chr2L 9542 9668 +chr2L 9539 9681 +chr2L 9545 9693 +chr2L 9546 9729 +chr2L 9546 9640 +chr2L 9550 9709 +chr2L 9547 9660 +chr2L 9550 9682 +chr2L 9547 9655 +chr2L 9553 9680 +chr2L 9554 9701 +chr2L 9551 9686 +chr2L 9551 9700 +chr2L 9551 9663 +chr2L 9554 9687 +chr2L 9551 9731 +chr2L 9551 9729 +chr2L 9551 9686 +chr2L 9552 9695 +chr2L 9555 9684 +chr2L 9552 9664 +chr2L 9555 9695 +chr2L 9555 9702 +chr2L 9555 9709 +chr2L 9554 9685 +chr2L 9554 9672 +chr2L 9554 9700 +chr2L 9555 9647 +chr2L 9561 9709 +chr2L 9561 9699 +chr2L 9568 9696 +chr2L 9568 9712 +chr2L 9568 9742 +chr2L 9571 9711 +chr2L 9568 9702 +chr2L 9569 9710 +chr2L 9572 9709 +chr2L 9572 9722 +chr2L 9577 9678 +chr2L 9583 9759 +chr2L 9580 9724 +chr2L 9583 9715 +chr2L 9583 9741 +chr2L 9580 9732 +chr2L 9580 9703 +chr2L 9580 9749 +chr2L 9580 9748 +chr2L 9583 9712 +chr2L 9580 9711 +chr2L 9580 9749 +chr2L 9580 9731 +chr2L 9591 9765 +chr2L 9595 9737 +chr2L 9595 9742 +chr2L 9598 9748 +chr2L 9595 9712 +chr2L 9598 9893 +chr2L 9599 9720 +chr2L 9599 9747 +chr2L 9596 9695 +chr2L 9599 9760 +chr2L 9602 9740 +chr2L 9605 9711 +chr2L 9606 9750 +chr2L 9606 9739 +chr2L 9606 9741 +chr2L 9603 9745 +chr2L 9606 9711 +chr2L 9606 9742 +chr2L 9609 9760 +chr2L 9611 9731 +chr2L 9614 9742 +chr2L 9611 9742 +chr2L 9612 9787 +chr2L 9612 9795 +chr2L 9612 9741 +chr2L 9615 9712 +chr2L 9615 9740 +chr2L 9613 9723 +chr2L 9616 9759 +chr2L 9613 9760 +chr2L 9613 9745 +chr2L 9616 9874 +chr2L 9616 9768 +chr2L 9613 9771 +chr2L 9616 9792 +chr2L 9613 9787 +chr2L 9613 9742 +chr2L 9613 9761 +chr2L 9613 9788 +chr2L 9616 9883 +chr2L 9613 9787 +chr2L 9618 9759 +chr2L 9621 9744 +chr2L 9621 9744 +chr2L 9619 9741 +chr2L 9623 9792 +chr2L 9623 9760 +chr2L 9624 9761 +chr2L 9625 9777 +chr2L 9626 9787 +chr2L 9626 9771 +chr2L 9629 9787 +chr2L 9629 9792 +chr2L 9627 9769 +chr2L 9631 9792 +chr2L 9631 9770 +chr2L 9628 9772 +chr2L 9628 9787 +chr2L 9628 9787 +chr2L 9628 9793 +chr2L 9628 9787 +chr2L 9628 9723 +chr2L 9628 9788 +chr2L 9629 9771 +chr2L 9632 9777 +chr2L 9629 9794 +chr2L 9632 9787 +chr2L 9629 9748 +chr2L 9638 9786 +chr2L 9635 9840 +chr2L 9638 9722 +chr2L 9638 9844 +chr2L 9641 9806 +chr2L 9638 9773 +chr2L 9643 9788 +chr2L 9652 9815 +chr2L 9654 9806 +chr2L 9654 9770 +chr2L 9657 9789 +chr2L 9654 9816 +chr2L 9657 9797 +chr2L 9654 9841 +chr2L 9654 9814 +chr2L 9658 9806 +chr2L 9655 9834 +chr2L 9655 9834 +chr2L 9655 9841 +chr2L 9655 9742 +chr2L 9655 9742 +chr2L 9655 9788 +chr2L 9657 9855 +chr2L 9657 9807 +chr2L 9660 9794 +chr2L 9662 9765 +chr2L 9663 9810 +chr2L 9663 9816 +chr2L 9668 9771 +chr2L 9669 9806 +chr2L 9667 9816 +chr2L 9670 9840 +chr2L 9671 9792 +chr2L 9671 9809 +chr2L 9671 9853 +chr2L 9668 9816 +chr2L 9668 9816 +chr2L 9677 9816 +chr2L 9677 9815 +chr2L 9675 9784 +chr2L 9676 9832 +chr2L 9677 9835 +chr2L 9677 9751 +chr2L 9677 9826 +chr2L 9679 9788 +chr2L 9679 9788 +chr2L 9679 9874 +chr2L 9684 9837 +chr2L 9684 9809 +chr2L 9681 9851 +chr2L 9681 9832 +chr2L 9684 9809 +chr2L 9684 9837 +chr2L 9685 9816 +chr2L 9684 9874 +chr2L 9684 9834 +chr2L 9687 9835 +chr2L 9687 9855 +chr2L 9687 9805 +chr2L 9687 9840 +chr2L 9690 9882 +chr2L 9690 9838 +chr2L 9688 9790 +chr2L 9692 9844 +chr2L 9695 9853 +chr2L 9692 9816 +chr2L 9692 9842 +chr2L 9695 9884 +chr2L 9697 9835 +chr2L 9701 9833 +chr2L 9701 9837 +chr2L 9698 9888 +chr2L 9698 9838 +chr2L 9699 9840 +chr2L 9699 9851 +chr2L 9704 9839 +chr2L 9701 9834 +chr2L 9704 9833 +chr2L 9701 9807 +chr2L 9705 9850 +chr2L 9702 9851 +chr2L 9702 9832 +chr2L 9705 9849 +chr2L 9707 9794 +chr2L 9711 9831 +chr2L 9711 9831 +chr2L 9711 9815 +chr2L 9708 9857 +chr2L 9712 9815 +chr2L 9715 9838 +chr2L 9718 9850 +chr2L 9715 9870 +chr2L 9718 9883 +chr2L 9719 9858 +chr2L 9716 9883 +chr2L 9721 9875 +chr2L 9718 9826 +chr2L 9719 9893 +chr2L 9719 9838 +chr2L 9719 9851 +chr2L 9720 9883 +chr2L 9723 9882 +chr2L 9720 9883 +chr2L 9720 9871 +chr2L 9723 9882 +chr2L 9720 9874 +chr2L 9723 9850 +chr2L 9720 9883 +chr2L 9720 9832 +chr2L 9724 9839 +chr2L 9721 9881 +chr2L 9721 9884 +chr2L 9724 9890 +chr2L 9725 9883 +chr2L 9728 9882 +chr2L 9729 9882 +chr2L 9726 9854 +chr2L 9729 9882 +chr2L 9729 9893 +chr2L 9730 9834 +chr2L 9730 9840 +chr2L 9730 9861 +chr2L 9727 9876 +chr2L 9730 9850 +chr2L 9730 9868 +chr2L 9727 9876 +chr2L 9730 9873 +chr2L 9727 9847 +chr2L 9731 9928 +chr2L 9739 9883 +chr2L 9739 9882 +chr2L 9745 9857 +chr2L 9748 9883 +chr2L 9748 9881 +chr2L 9748 9893 +chr2L 9754 9851 +chr2L 9758 9880 +chr2L 9758 9874 +chr2L 9759 9839 +chr2L 9756 9923 +chr2L 9760 9895 +chr2L 9757 9925 +chr2L 9757 9869 +chr2L 9760 9884 +chr2L 9760 9932 +chr2L 9760 9893 +chr2L 9757 9881 +chr2L 9758 9893 +chr2L 9758 9906 +chr2L 9758 9923 +chr2L 9758 9855 +chr2L 9758 9925 +chr2L 9758 9884 +chr2L 9761 9886 +chr2L 9758 9893 +chr2L 9763 9869 +chr2L 9767 9926 +chr2L 9770 9882 +chr2L 9770 9882 +chr2L 9768 9923 +chr2L 9768 9936 +chr2L 9771 9941 +chr2L 9771 9924 +chr2L 9771 9943 +chr2L 9768 9926 +chr2L 9781 9948 +chr2L 9778 9917 +chr2L 9781 9892 +chr2L 9781 9942 +chr2L 9787 9948 +chr2L 9784 9923 +chr2L 9784 9926 +chr2L 9787 9948 +chr2L 9793 9958 +chr2L 9793 9924 +chr2L 9795 9948 +chr2L 9793 9939 +chr2L 9799 9949 +chr2L 9799 9925 +chr2L 9802 9941 +chr2L 9803 9948 +chr2L 9800 9942 +chr2L 9803 9953 +chr2L 9800 9926 +chr2L 9803 9973 +chr2L 9803 9959 +chr2L 9806 9946 +chr2L 9806 9949 +chr2L 9803 9891 +chr2L 9806 9958 +chr2L 9806 9958 +chr2L 9803 9942 +chr2L 9803 9949 +chr2L 9803 9956 +chr2L 9806 9948 +chr2L 9803 9942 +chr2L 9804 9954 +chr2L 9807 9958 +chr2L 9808 9953 +chr2L 9813 9912 +chr2L 9816 10018 +chr2L 9813 9950 +chr2L 9820 9978 +chr2L 9823 9949 +chr2L 9823 9975 +chr2L 9827 9949 +chr2L 9827 9955 +chr2L 9828 9936 +chr2L 9832 9954 +chr2L 9832 9971 +chr2L 9833 9942 +chr2L 9833 9953 +chr2L 9830 9942 +chr2L 9833 9973 +chr2L 9830 9950 +chr2L 9833 9942 +chr2L 9833 9932 +chr2L 9830 10006 +chr2L 9830 9974 +chr2L 9830 9946 +chr2L 9833 9971 +chr2L 9833 9932 +chr2L 9834 9960 +chr2L 9844 9953 +chr2L 9849 9973 +chr2L 9850 9974 +chr2L 9853 9972 +chr2L 9850 9955 +chr2L 9853 9997 +chr2L 9850 9972 +chr2L 9853 10029 +chr2L 9854 10017 +chr2L 9851 10003 +chr2L 9851 9938 +chr2L 9853 9959 +chr2L 9854 10005 +chr2L 9854 9973 +chr2L 9862 10010 +chr2L 9861 10031 +chr2L 9866 10039 +chr2L 9868 10017 +chr2L 9869 10018 +chr2L 9867 10011 +chr2L 9867 10022 +chr2L 9867 10025 +chr2L 9871 10024 +chr2L 9871 10075 +chr2L 9871 10004 +chr2L 9868 10025 +chr2L 9868 9959 +chr2L 9868 9957 +chr2L 9871 9975 +chr2L 9875 9961 +chr2L 9872 10030 +chr2L 9875 10009 +chr2L 9875 9961 +chr2L 9876 10017 +chr2L 9876 10024 +chr2L 9883 10018 +chr2L 9880 10025 +chr2L 9883 10004 +chr2L 9884 10046 +chr2L 9884 10030 +chr2L 9884 10144 +chr2L 9884 10018 +chr2L 9886 10017 +chr2L 9891 10018 +chr2L 9894 9972 +chr2L 9896 10054 +chr2L 9896 10050 +chr2L 9898 10077 +chr2L 9900 10050 +chr2L 9903 10055 +chr2L 9903 10049 +chr2L 9903 10056 +chr2L 9900 10064 +chr2L 9903 10067 +chr2L 9903 10067 +chr2L 9900 10076 +chr2L 9903 10062 +chr2L 9904 10018 +chr2L 9901 10030 +chr2L 9904 10063 +chr2L 9904 10073 +chr2L 9901 10019 +chr2L 9901 10018 +chr2L 9904 10046 +chr2L 9904 10055 +chr2L 9904 10072 +chr2L 9901 10051 +chr2L 9904 10029 +chr2L 9904 10017 +chr2L 9904 10068 +chr2L 9904 10050 +chr2L 9904 10072 +chr2L 9904 10049 +chr2L 9904 10067 +chr2L 9904 10049 +chr2L 9901 10047 +chr2L 9905 10050 +chr2L 9907 10049 +chr2L 9904 10047 +chr2L 9904 10030 +chr2L 9907 10067 +chr2L 9907 10036 +chr2L 9904 10026 +chr2L 9914 10068 +chr2L 9914 10017 +chr2L 9916 10048 +chr2L 9919 10068 +chr2L 9916 10064 +chr2L 9918 10019 +chr2L 9919 10068 +chr2L 9924 10069 +chr2L 9921 10056 +chr2L 9927 10019 +chr2L 9931 10067 +chr2L 9929 10090 +chr2L 9932 10072 +chr2L 9931 10089 +chr2L 9935 10100 +chr2L 9935 10072 +chr2L 9935 10067 +chr2L 9933 10089 +chr2L 9935 10088 +chr2L 9936 10045 +chr2L 9939 10094 +chr2L 9937 10030 +chr2L 9942 10135 +chr2L 9957 10049 +chr2L 9958 10095 +chr2L 9958 10106 +chr2L 9961 10088 +chr2L 9958 10086 +chr2L 9962 10089 +chr2L 9962 10100 +chr2L 9964 10108 +chr2L 9967 10088 +chr2L 9964 10073 +chr2L 9968 10134 +chr2L 9965 10068 +chr2L 9968 10107 +chr2L 9968 10067 +chr2L 9966 10089 +chr2L 9966 10074 +chr2L 9969 10089 +chr2L 9971 10089 +chr2L 9969 10103 +chr2L 9969 10142 +chr2L 9969 10094 +chr2L 9970 10106 +chr2L 9973 10132 +chr2L 9973 10121 +chr2L 9973 10116 +chr2L 9973 10095 +chr2L 9971 10280 +chr2L 9974 10113 +chr2L 9971 10088 +chr2L 9974 10116 +chr2L 9974 10088 +chr2L 9974 10117 +chr2L 9974 10134 +chr2L 9974 10104 +chr2L 9972 10141 +chr2L 9972 10073 +chr2L 9977 10101 +chr2L 9980 10118 +chr2L 9981 10125 +chr2L 9985 10135 +chr2L 9985 10134 +chr2L 9982 10133 +chr2L 9982 10237 +chr2L 9985 10113 +chr2L 9985 10134 +chr2L 9986 10362 +chr2L 9983 10146 +chr2L 9986 10132 +chr2L 9983 10141 +chr2L 9986 10149 +chr2L 9986 10141 +chr2L 9983 10142 +chr2L 9986 10100 +chr2L 9986 10134 +chr2L 9983 10136 +chr2L 9983 10108 +chr2L 9986 10141 +chr2L 9987 10121 +chr2L 9987 10134 +chr2L 9984 10141 +chr2L 9987 10089 +chr2L 9989 10171 +chr2L 9989 10099 +chr2L 9989 10141 +chr2L 9992 10134 +chr2L 9989 10158 +chr2L 9992 10150 +chr2L 9993 10147 +chr2L 9990 10108 +chr2L 9990 10142 +chr2L 9993 10170 +chr2L 9990 10135 +chr2L 9993 10091 +chr2L 9994 10135 +chr2L 9991 10145 +chr2L 9991 10101 +chr2L 9991 10145 +chr2L 9991 10133 +chr2L 9999 10134 +chr2L 10000 10173 diff --git a/pydeeptools/deeptools/test/test_data/alignmentSieve2.bam b/pydeeptools/deeptools/test/test_data/alignmentSieve2.bam new file mode 100644 index 0000000000..aebd0399f4 Binary files /dev/null and b/pydeeptools/deeptools/test/test_data/alignmentSieve2.bam differ diff --git a/pydeeptools/deeptools/test/test_data/alignmentSieve3.bam b/pydeeptools/deeptools/test/test_data/alignmentSieve3.bam new file mode 100644 index 0000000000..e3afc22700 Binary files /dev/null and b/pydeeptools/deeptools/test/test_data/alignmentSieve3.bam differ diff --git a/pydeeptools/deeptools/test/test_data/bamCoverage_result4.bw b/pydeeptools/deeptools/test/test_data/bamCoverage_result4.bw new file mode 100644 index 0000000000..6eb0b982ac Binary files /dev/null and b/pydeeptools/deeptools/test/test_data/bamCoverage_result4.bw differ diff --git a/pydeeptools/deeptools/test/test_data/bamPEFragmentSize_histogram_result1.png b/pydeeptools/deeptools/test/test_data/bamPEFragmentSize_histogram_result1.png new file mode 100644 index 0000000000..25ae59a929 Binary files /dev/null and b/pydeeptools/deeptools/test/test_data/bamPEFragmentSize_histogram_result1.png differ diff --git a/pydeeptools/deeptools/test/test_data/bowtie2_test1.bam b/pydeeptools/deeptools/test/test_data/bowtie2_test1.bam new file mode 100644 index 0000000000..e23d7aef9e Binary files /dev/null and b/pydeeptools/deeptools/test/test_data/bowtie2_test1.bam differ diff --git a/pydeeptools/deeptools/test/test_data/bowtie2_test1.bam.bai b/pydeeptools/deeptools/test/test_data/bowtie2_test1.bam.bai new file mode 100644 index 0000000000..c25b15e121 Binary files /dev/null and b/pydeeptools/deeptools/test/test_data/bowtie2_test1.bam.bai differ diff --git a/pydeeptools/deeptools/test/test_data/computeGCBias_result1.tabular b/pydeeptools/deeptools/test/test_data/computeGCBias_result1.tabular new file mode 100644 index 0000000000..19bea922a0 --- /dev/null +++ b/pydeeptools/deeptools/test/test_data/computeGCBias_result1.tabular @@ -0,0 +1,301 @@ +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 1.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 1.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 1.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 1.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 1.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 1.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +5.000000000000000000e+00 1.000000000000000000e+00 1.000000000000000000e+01 +0.000000000000000000e+00 1.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 1.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 1.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 +0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 diff --git a/pydeeptools/deeptools/test/test_data/computeMatrix1.bed b/pydeeptools/deeptools/test/test_data/computeMatrix1.bed new file mode 100644 index 0000000000..3c25ec7fd9 --- /dev/null +++ b/pydeeptools/deeptools/test/test_data/computeMatrix1.bed @@ -0,0 +1,8 @@ +phiX174 1000 1500 CG11023 0 + +phiX174 150 1750 cda5 0 - +phiX174 150 177 cda8 0 - +phiX174 75 1500 cda9 0 + +phiX174 101 175 C11023 0 + +phiX174 125 150 ca5 0 - +phiX174 450 1750 ca8 0 + +phiX174 80 1500 cda9 0 + diff --git a/pydeeptools/deeptools/test/test_data/computeMatrix2.bed b/pydeeptools/deeptools/test/test_data/computeMatrix2.bed new file mode 100644 index 0000000000..ec9531e1bd --- /dev/null +++ b/pydeeptools/deeptools/test/test_data/computeMatrix2.bed @@ -0,0 +1,6 @@ +ch1 100 150 CG11023 0 + +ch2 150 175 cda5 0 - +ch3 100 125 cda8 0 + +ch1 75 125 C11023 0 + +ch2 125 150 ca5 0 - +ch3 75 100 ca8 0 + diff --git a/pydeeptools/deeptools/test/test_data/computeMatrix2.bw b/pydeeptools/deeptools/test/test_data/computeMatrix2.bw new file mode 100644 index 0000000000..02fe971712 Binary files /dev/null and b/pydeeptools/deeptools/test/test_data/computeMatrix2.bw differ diff --git a/pydeeptools/deeptools/test/test_data/computeMatrix_result1.gz b/pydeeptools/deeptools/test/test_data/computeMatrix_result1.gz new file mode 100644 index 0000000000..5614371533 Binary files /dev/null and b/pydeeptools/deeptools/test/test_data/computeMatrix_result1.gz differ diff --git a/pydeeptools/deeptools/test/test_data/computeMatrix_result2.gz b/pydeeptools/deeptools/test/test_data/computeMatrix_result2.gz new file mode 100644 index 0000000000..451411ecdd Binary files /dev/null and b/pydeeptools/deeptools/test/test_data/computeMatrix_result2.gz differ diff --git a/pydeeptools/deeptools/test/test_data/computeMatrix_result3.gz b/pydeeptools/deeptools/test/test_data/computeMatrix_result3.gz new file mode 100644 index 0000000000..27f85c318e Binary files /dev/null and b/pydeeptools/deeptools/test/test_data/computeMatrix_result3.gz differ diff --git a/pydeeptools/deeptools/test/test_data/correctGCBias_result1.bam b/pydeeptools/deeptools/test/test_data/correctGCBias_result1.bam new file mode 100644 index 0000000000..ae0521b459 Binary files /dev/null and b/pydeeptools/deeptools/test/test_data/correctGCBias_result1.bam differ diff --git a/pydeeptools/deeptools/test/test_data/paired_chr2L.bam b/pydeeptools/deeptools/test/test_data/paired_chr2L.bam new file mode 100644 index 0000000000..cf535ec667 Binary files /dev/null and b/pydeeptools/deeptools/test/test_data/paired_chr2L.bam differ diff --git a/pydeeptools/deeptools/test/test_data/paired_chr2L.bam.bai b/pydeeptools/deeptools/test/test_data/paired_chr2L.bam.bai new file mode 100644 index 0000000000..cdb421dd39 Binary files /dev/null and b/pydeeptools/deeptools/test/test_data/paired_chr2L.bam.bai differ diff --git a/pydeeptools/deeptools/test/test_data/paired_chr2L.cram b/pydeeptools/deeptools/test/test_data/paired_chr2L.cram new file mode 100644 index 0000000000..4789b1513f Binary files /dev/null and b/pydeeptools/deeptools/test/test_data/paired_chr2L.cram differ diff --git a/pydeeptools/deeptools/test/test_data/sequence.2bit b/pydeeptools/deeptools/test/test_data/sequence.2bit new file mode 100644 index 0000000000..51f1a51e81 Binary files /dev/null and b/pydeeptools/deeptools/test/test_data/sequence.2bit differ diff --git a/pydeeptools/deeptools/utilities.py b/pydeeptools/deeptools/utilities.py index 64cc7a75c3..0562b8c9b8 100755 --- a/pydeeptools/deeptools/utilities.py +++ b/pydeeptools/deeptools/utilities.py @@ -4,7 +4,6 @@ from deeptools.bamHandler import openBam import matplotlib as mpl mpl.use('Agg') -from deeptools import cm # noqa: F401 import numpy as np diff --git a/pydeeptools/deeptools/writeBedGraph.py b/pydeeptools/deeptools/writeBedGraph.py index 4888aca945..44b6a2d202 100644 --- a/pydeeptools/deeptools/writeBedGraph.py +++ b/pydeeptools/deeptools/writeBedGraph.py @@ -150,8 +150,6 @@ def run(self, func_to_call, func_args, out_file_name, blackListFileName=None, fo region=self.region, blackListFileName=blackListFileName, numberOfProcessors=self.numberOfProcessors) - print("Result after mapReduce") - print(res) # Determine the sorted order of the temp files chrom_order = dict() for i, _ in enumerate(chrom_names_and_size): diff --git a/pyproject.toml b/pyproject.toml index 383622e3cd..74b0b3ca41 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -64,20 +64,20 @@ repository = "https://github.com/deeptools/deepTools" packages = ["deeptools"] [project.scripts] -alignmentSieve = "deeptools.alignmentSieve:main" -bamCompare = "deeptools.bamCompare:main" -bamCoverage = "deeptools.bamCoverage:main" +#alignmentSieve = "deeptools.alignmentSieve:main" +#bamCompare = "deeptools.bamCompare:main" +#bamCoverage = "deeptools.bamCoverage:main" bamPEFragmentSize = "deeptools.bamPEFragmentSize:main" bigwigAverage = "deeptools.bigwigAverage:main" bigwigCompare = "deeptools.bigwigCompare:main" computeGCBias = "deeptools.computeGCBias:main" -computeMatrix = "deeptools.computeMatrix:main" +#computeMatrix = "deeptools.computeMatrix:main" computeMatrixOperations = "deeptools.computeMatrixOperations:main" correctGCBias = "deeptools.correctGCBias:main" deeptools = "deeptools.deeptools_list_tools:main" estimateReadFiltering = "deeptools.estimateReadFiltering:main" estimateScaleFactor = "deeptools.estimateScaleFactor:main" -multiBamSummary = "deeptools.multiBamSummary:main" +#multiBamSummary = "deeptools.multiBamSummary:main" multiBigwigSummary = "deeptools.multiBigwigSummary:main" plotCorrelation = "deeptools.plotCorrelation:main" plotCoverage = "deeptools.plotCoverage:main" @@ -86,8 +86,8 @@ plotFingerprint = "deeptools.plotFingerprint:main" plotHeatmap = "deeptools.plotHeatmap:main" plotPCA = "deeptools.plotPCA:main" plotProfile = "deeptools.plotProfile:main" -bamCoverage2 = "deeptools.bamCoverage2:main" -bamCompare2 = "deeptools.bamCompare2:main" -computeMatrix2 = "deeptools.computeMatrix2:main" -alignmentSieve2 = "deeptools.alignmentSieve2:main" -multiBamSummary2 = "deeptools.multiBamSummary2:main" \ No newline at end of file +bamCoverage = "deeptools.bamCoverage2:main" +bamCompare = "deeptools.bamCompare2:main" +computeMatrix = "deeptools.computeMatrix2:main" +alignmentSieve = "deeptools.alignmentSieve2:main" +multiBamSummary = "deeptools.multiBamSummary2:main" \ No newline at end of file diff --git a/src/alignmentsieve.rs b/src/alignmentsieve.rs index 3f37e54970..4bf487d96e 100644 --- a/src/alignmentsieve.rs +++ b/src/alignmentsieve.rs @@ -8,7 +8,7 @@ use rust_htslib::bam::{self, record, Header, IndexedReader, Read, Reader, Writer use tempfile::{Builder, TempPath, NamedTempFile}; use std::fs::File; use std::io::Write; -use crate::covcalc::{parse_regions, Alignmentfilters}; +use crate::covcalc::{parse_regions, Alignmentfilters, Region}; #[pyfunction] pub fn r_alignmentsieve( @@ -47,7 +47,7 @@ pub fn r_alignmentsieve( // shift is of length 0, 2, or 4. // Define regions - let (regions, chromsizes) = parse_regions(&Vec::new(), bamifile); + let (regions, chromsizes) = parse_regions(&Vec::new(), vec![bamifile]); let filters = Alignmentfilters{ minmappingquality: min_mapping_quality, @@ -74,7 +74,7 @@ pub fn r_alignmentsieve( // write output let mut obam = Writer::from_path(ofile, &header, bam::Format::Bam).unwrap(); - obam.set_threads(nproc); + let _ = obam.set_threads(nproc); for sb in sieve.into_iter() { if let Some(sb) = sb { let mut bam = Reader::from_path(&sb).unwrap(); @@ -87,7 +87,7 @@ pub fn r_alignmentsieve( // write filtered reads if necessary if write_filters { let mut ofilterbam = Writer::from_path(filtered_out_readsfile, &header, bam::Format::Bam).unwrap(); - ofilterbam.set_threads(nproc); + let _ = ofilterbam.set_threads(nproc); for sb in filtersieve.into_iter() { if let Some(sb) = sb { let mut bam = Reader::from_path(&sb).unwrap(); @@ -113,7 +113,8 @@ pub fn r_alignmentsieve( } -fn sieve_bamregion(ibam: &str, region: &(String, u32, u32), alfilters: &Alignmentfilters, filter_rna_strand: &str, shift: &Vec, write_filters: bool, nproc: usize, verbose: bool) -> (Vec>, Vec>, u64, u64) { +fn sieve_bamregion(ibam: &str, regstruct: &Region, alfilters: &Alignmentfilters, filter_rna_strand: &str, shift: &Vec, write_filters: bool, nproc: usize, verbose: bool) -> (Vec>, Vec>, u64, u64) { + let region = (regstruct.chrom.clone(), regstruct.get_startu(), regstruct.get_endu()); let mut total_reads: u64 = 0; let mut filtered_reads: u64 = 0; let mut bam = IndexedReader::from_path(ibam).unwrap(); @@ -147,8 +148,8 @@ fn sieve_bamregion(ibam: &str, region: &(String, u32, u32), alfilters: &Alignmen if nproc > 4 { let readthreads = 2; let writethreads = nproc - 2; - bam.set_threads(readthreads); - sievebamout.set_threads(writethreads); + let _ = bam.set_threads(readthreads); + let _ = sievebamout.set_threads(writethreads); if verbose { println!("Reading = {}, Writing = {}", readthreads, writethreads); } diff --git a/src/bamcompare.rs b/src/bamcompare.rs index f327392262..1d18f405ec 100644 --- a/src/bamcompare.rs +++ b/src/bamcompare.rs @@ -8,7 +8,7 @@ use std::fs::File; use itertools::Itertools; use bigtools::{Value}; use crate::filehandler::{bam_ispaired, write_covfile}; -use crate::covcalc::{bam_pileup, parse_regions, Alignmentfilters}; +use crate::covcalc::{bam_pileup, parse_regions, Alignmentfilters, TempZip, region_divider}; use crate::normalization::scale_factor_bamcompare; use crate::calc::{median, calc_ratio}; use tempfile::{TempPath}; @@ -60,17 +60,19 @@ pub fn r_bamcompare( }; // Parse regions & calculate coverage. Note that - let (regions, chromsizes) = parse_regions(®ions, bamifile1); + let (regions, chromsizes) = parse_regions(®ions, vec![bamifile1, bamifile2]); + let regionblocks = region_divider(®ions); + let pool = ThreadPoolBuilder::new().num_threads(nproc).build().unwrap(); // Set up the bam files in a Vec. let bamfiles = vec![(bamifile1, ispe1), (bamifile2, ispe2)]; - let covcalcs: Vec = pool.install(|| { + let mut covcalcs: Vec = pool.install(|| { bamfiles.par_iter() .map(|(bamfile, ispe)| { - let (bg, mapped, unmapped, readlen, fraglen) = regions.par_iter() - .map(|i| bam_pileup(bamfile, &i, &binsize, &ispe, &ignorechr, &filters, false)) + let (bg, mapped, unmapped, readlen, fraglen) = regionblocks.par_iter() + .map(|i| bam_pileup(bamfile, &i, &binsize, &ispe, &ignorechr, &filters, false, false)) .reduce( || (vec![], 0, 0, vec![], vec![]), |(mut _bg, mut _mapped, mut _unmapped, mut _readlen, mut _fraglen), (bg, mapped, unmapped, readlen, fraglen)| { @@ -100,45 +102,44 @@ pub fn r_bamcompare( println!("scale factor1 = {}, scale factor2 = {}", sf.0, sf.1); // Create output stream let mut chrom = "".to_string(); - let lines = covcalcs[0].bg.iter().zip(covcalcs[1].bg.iter()).flat_map( - |(t1, t2)| { - let reader1 = BufReader::new(File::open(t1).unwrap()).lines(); - let reader2 = BufReader::new(File::open(t2).unwrap()).lines(); - reader1.zip(reader2).map( - |(l1, l2)| { - let l1 = l1.unwrap(); - let l2 = l2.unwrap(); - let fields1: Vec<&str> = l1.split('\t').collect(); - let fields2: Vec<&str> = l2.split('\t').collect(); - - let chrom1: String = fields1[0].to_string(); - let chrom2: String = fields2[0].to_string(); - let start1: u32 = fields1[1].parse().unwrap(); - let start2: u32 = fields2[1].parse().unwrap(); - let end1: u32 = fields1[2].parse().unwrap(); - let end2: u32 = fields2[2].parse().unwrap(); - - // Assert the regions are equal. - assert_eq!(chrom1, chrom2); - assert_eq!(start1, start2); - assert_eq!(end1, end2); - - // Calculate the coverage. - let cov1: f32 = fields1[3].parse().unwrap(); - let cov2: f32 = fields2[3].parse().unwrap(); - let cov = calc_ratio(cov1, cov2, &sf.0, &sf.1, &pseudocount, operation); - - (chrom1, Value { start: start1, end: end1, value: cov }) - }).coalesce(|p, c| { - if p.1.value == c.1.value { - Ok((p.0, Value {start: p.1.start, end: c.1.end, value: p.1.value})) - } else { - Err((p, c)) - } - }) - } - ); + // Extract both vecs of TempPaths into a single vector + let its = vec![ + covcalcs[0].bg.drain(..).collect::>(), + covcalcs[1].bg.drain(..).collect::>() + ]; + let its: Vec<_> = its.iter().map(|x| x.into_iter()).collect(); + let zips = TempZip { iterators: its }; + let zips_vec: Vec<_> = zips.collect(); + + let lines = zips_vec + .into_iter() + .flat_map(|c| { + let readers: Vec<_> = c.into_iter().map(|x| BufReader::new(File::open(x).unwrap()).lines()).collect(); + let temp_zip = TempZip { iterators: readers }; + temp_zip.into_iter().map(|mut _l| { + let lines: Vec<_> = _l + .iter_mut() + .map(|x| x.as_mut().unwrap()) + .map(|x| x.split('\t').collect()) + .map(|x: Vec<&str>| (x[0].to_string(), x[1].parse::().unwrap(), x[2].parse::().unwrap(), x[3].parse::().unwrap())) + .collect(); + assert_eq!(lines.len(), 2); + assert_eq!(lines[0].0, lines[1].0); + assert_eq!(lines[0].1, lines[1].1); + assert_eq!(lines[0].2, lines[1].2); + // Calculate the coverage. + let cov = calc_ratio(lines[0].3, lines[1].3, &sf.0, &sf.1, &pseudocount, operation); + (lines[0].0.clone(), Value { start: lines[0].1, end: lines[0].2, value: cov }) + }).coalesce(|p, c| { + if p.1.value == c.1.value && p.0 == c.0 { + Ok((p.0, Value {start: p.1.start, end: c.1.end, value: p.1.value})) + } else { + Err((p, c)) + } + }) + }); + write_covfile(lines, ofile, ofiletype, chromsizes); Ok(()) } diff --git a/src/bamcoverage.rs b/src/bamcoverage.rs index 256cd34b18..8d74a6ff13 100644 --- a/src/bamcoverage.rs +++ b/src/bamcoverage.rs @@ -6,7 +6,7 @@ use std::io::prelude::*; use std::io::BufReader; use std::fs::File; use bigtools::Value; -use crate::covcalc::{bam_pileup, parse_regions, Alignmentfilters}; +use crate::covcalc::{bam_pileup, parse_regions, Alignmentfilters, region_divider}; use crate::filehandler::{bam_ispaired, write_covfile}; use crate::normalization::scale_factor; use crate::calc::median; @@ -70,11 +70,12 @@ pub fn r_bamcoverage( } // Parse regions & calculate coverage - let (regions, chromsizes) = parse_regions(®ions, bamifile); + let (regions, chromsizes) = parse_regions(®ions, vec![bamifile]); + let regionblocks = region_divider(®ions); let pool = ThreadPoolBuilder::new().num_threads(nproc).build().unwrap(); let (bg, mapped, _unmapped, readlen, fraglen) = pool.install(|| { - regions.par_iter() - .map(|i| bam_pileup(bamifile, &i, &binsize, &ispe, &ignorechr, &filters, true)) + regionblocks.par_iter() + .map(|i| bam_pileup(bamifile, &i, &binsize, &ispe, &ignorechr, &filters, true, false)) .reduce( || (vec![], 0, 0, vec![], vec![]), |(mut _bg, mut _mapped, mut _unmapped, mut _readlen, mut _fraglen), (bg, mapped, unmapped, readlen, fraglen)| { diff --git a/src/calc.rs b/src/calc.rs index 15b4c83e43..75239ad1e7 100644 --- a/src/calc.rs +++ b/src/calc.rs @@ -1,3 +1,5 @@ +use ndarray::{Array1, Array2, Axis}; + pub fn median(mut nvec: Vec) -> f32 { if nvec.is_empty() { 0.0 @@ -156,3 +158,19 @@ pub fn calc_ratio( } } } + +pub fn deseq_scalefactors(array2: &Array2) -> Array1 { + let loggeomeans = array2.mapv(|v| v.ln()).sum_axis(Axis(1)) / array2.shape()[1] as f32; + let masked_array = array2.mapv(|x| if x <= 0.0 { f32::NAN } else { x }); + let masked_loggeomeans = loggeomeans.mapv(|x| if x.is_infinite() { f32::NAN } else { x }); + let adjusted_loga = masked_array.mapv(|x| x.ln()).t().to_owned() - &masked_loggeomeans; + let medians: Array1 = adjusted_loga.t().axis_iter(Axis(1)) + .map(|x| { + let vec: Vec<&f32> = x.iter() + .filter(|&&x| !x.is_nan()) + .collect(); + median_float(vec) + }) + .collect(); + medians.mapv(|x| 1.0 / x.exp()) +} \ No newline at end of file diff --git a/src/computematrix.rs b/src/computematrix.rs index 5ff64f7c19..a632c8257c 100644 --- a/src/computematrix.rs +++ b/src/computematrix.rs @@ -1,15 +1,13 @@ use pyo3::prelude::*; use pyo3::types::PyList; -use crate::filehandler::{read_bedfile, read_gtffile, chrombounds_from_bw, bwintervals, header_matrix, write_matrix}; +use crate::filehandler::{read_bedfile, read_gtffile, chrombounds_from_bw, bwintervals, header_matrix, write_matrix, is_bed_or_gtf}; use rayon::prelude::*; use rayon::ThreadPoolBuilder; use std::collections::HashMap; use std::path::Path; -use std::fmt; use itertools::Itertools; -use ndarray::Array1; use crate::calc::{mean_float, median_float, max_float, min_float, sum_float}; - +use crate::covcalc::{Region, Gtfparse, Scalingregions, Bin}; #[pyfunction] pub fn r_computematrix( @@ -130,15 +128,12 @@ pub fn r_computematrix( let mut regionsizes: HashMap = HashMap::new(); region_files.iter() .map(|r| { - let ext = Path::new(r) - .extension() - .and_then(|e| e.to_str()) - .map(|e| e.to_ascii_lowercase()); - - match ext { - Some(v) if v == "gtf".to_string() => read_gtffile(r, >fparse, chromsizes.keys().collect()), - Some(v) if v == "bed".to_string() => read_bedfile(r, metagene, chromsizes.keys().collect()), - _ => panic!("Only .bed and .gtf files are allowed as regions. File = {}, Extension = {:?}", r, ext), + let ftype = is_bed_or_gtf(r); + + match ftype.as_str() { + "gtf" => read_gtffile(r, >fparse, chromsizes.keys().collect()), + "bed" => read_bedfile(r, metagene, chromsizes.keys().collect()), + _ => panic!("Only .bed and .gtf files are allowed (as determined by the number of columns). File = {}", ftype), } }) .for_each(|(reg, regsize)| { @@ -202,1003 +197,6 @@ fn slop_region( region.get_anchor_bins(scale_regions, chromend) } -#[derive(Debug)] -pub struct Scalingregions { - pub upstream: u32, - pub downstream: u32, - pub unscaled5prime: u32, - pub unscaled3prime: u32, - pub regionbodylength: u32, - pub binsize: u32, - pub cols_expected: usize, - pub bpsum: u32, - pub missingdata_as_zero: bool, - pub scale: f32, - pub nan_after_end: bool, - pub skipzero: bool, - pub minthresh: f32, - pub maxthresh: f32, - pub referencepoint: String, - pub mode: String, - pub bwfiles: usize, - pub avgtype: String, - pub verbose: bool, - pub proc_number: usize, - pub regionlabels: Vec, - pub bwlabels: Vec -} - -#[derive(Clone)] -pub struct Gtfparse { - pub metagene: bool, - pub txnid: String, - pub exonid: String, - pub txniddesignator: String, -} - -#[derive(Clone)] -pub enum Revalue { - U(u32), - V(Vec), -} - -impl Revalue { - pub fn rewrites(&self) -> String { - match self { - Revalue::U(v) => format!("{}", v), - Revalue::V(vs) => vs.iter() - .map(|v| v.to_string()) - .collect::>() - .join(","), - } - } -} - -impl fmt::Debug for Revalue { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - match self { - Revalue::U(value) => write!(f, "U({})", value), - Revalue::V(values) => write!(f, "V({:?})", values), - } - } -} - -impl fmt::Display for Revalue { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - match self { - Revalue::U(value) => write!(f, "U({})", value), - Revalue::V(values) => write!(f, "V({})", values.iter().map(|v| v.to_string()).collect::>().join(", ")), - } - } -} - -#[derive(Clone, Debug)] -pub enum Bin { - Conbin(u32, u32), - Catbin(Vec<(u32, u32)>), -} - -impl Bin { - pub fn get_start(&self) -> u32 { - match self { - Bin::Conbin(start, _) => *start, - Bin::Catbin(starts) => starts.first().unwrap().0, - } - } - pub fn get_end(&self) -> u32 { - match self { - Bin::Conbin(_, end) => *end, - Bin::Catbin(ends) => ends.last().unwrap().1, - } - } -} - - -#[derive(Clone, Debug)] -pub struct Region { - pub chrom: String, - pub start: Revalue, - pub end: Revalue, - pub score: String, - pub strand: String, - pub name: String, - pub regionlength: u32 -} - -impl Region { - pub fn assert_end(&self, chromend: u32) { - match &self.end { - Revalue::U(end) => { - assert!( - *end <= chromend, - "Region end goes beyond chromosome boundary. Fix {}. {} {} {} (chr end = {})", self.name, self.chrom, self.start, self.end, chromend - ); - }, - Revalue::V(ends) => { - for end in ends.iter() { - assert!( - *end <= chromend, - "Region end goes beyond chromosome boundary. Fix {}. {} {} {} (chr end = {})", self.name, self.chrom, self.start, end, chromend - ); - } - } - } - } - - pub fn get_anchorpoint(&self, referencepoint: &str) -> u32 { - // reference-point mode. - // What is exactly returned depends on a couple of parameters - // what is the referencepoint : TSS, center, TES - // what is the strand: +, -, . (note . is assumed to be +) - // depending on if we have exon blocks (start / end are Revalue V == Vectors) or not (start / end are Revalue U == u32's) - match referencepoint { - "TSS" => { - match self.strand.as_str() { - "+" | "." => match &self.start {Revalue::U(start) => *start, Revalue::V(starts) => starts[0]}, - "-" => match &self.end {Revalue::U(end) => *end, Revalue::V(ends) => *ends.last().unwrap()}, - _ => panic!("Strand should either be + or - or . {:?} is not supported.", self.strand), - } - }, - "TES" => { - match self.strand.as_str() { - "+" | "." => match &self.end {Revalue::U(end) => *end, Revalue::V(ends) => *ends.last().unwrap()}, - "-" => match &self.start {Revalue::U(start) => *start, Revalue::V(starts) => starts[0]}, - _ => panic!("Strand should either be + or - or . {:?} is not supported.", self.strand), - } - }, - "center" => { - // Here + or - doesn't matter. It is important though if we have 'metagenes' or not. - match (&self.start, &self.end) { - (Revalue::U(start), Revalue::U(end)) => { - (*start + *end) / 2 - }, - (Revalue::V(starts), Revalue::V(ends)) => { - let exonlength: u32 = starts.iter().zip(ends.iter()).map(|(s, e)| e - s).sum(); - let middle = exonlength / 2; - let mut cumsum: u32 = 0; - for (s, e) in starts.iter().zip(ends.iter()) { - cumsum += e - s; - if cumsum >= middle { - return s + (middle - (cumsum - (e - s))); - } - } - panic!( - "Middle of region not found. Fix {}. {}:{}-{}", - self.name, self.chrom, self.start, self.end - ) - }, - _ => panic!( - "Start and End are not either both u32, or Vecs. This means your regions file is ill-defined. Fix {}. {}:{}-{}", - self.name, self.chrom, self.start, self.end - ), - } - }, - _ => panic!( - "Reference should either be TSS, TES or center. {:?} is not supported.", - referencepoint - ), - } - } - - pub fn get_anchor_bins(&self, scale_regions: &Scalingregions, chromend: u32) -> Vec { - // Given an anchorpoint, return a vector, start, end , middle - // The order of the vector is always 5' -> 3', meaning 'increasing' for +/. regions, and 'decreasing' for - regions. - // At this stage, two situations are possible: - // - self.start / self.end are Revalue::U, meaning we are in 'non metagene' mode. - // - self.start / self.end are Revalue::V, meaning we are in 'metagene' mode, and the bins returned are exon-aware. - // We need a notion of bins that don't make sense (i.e. beyond chromosome boundaries). These are encoded as (0,0) - - let mut bins: Vec = Vec::new(); - let mut bodybins: Vec = Vec::new(); - - // Define anchorpoints - let anchorstart; - let anchorstop; - match scale_regions.mode.as_str() { - "reference-point" => { - anchorstart = self.get_anchorpoint(&scale_regions.referencepoint); - anchorstop = anchorstart; - }, - "scale-regions" => { - match (&self.start, &self.end) { - (Revalue::U(start), Revalue::U(end)) => { - anchorstart = *start; - anchorstop = *end; - }, - (Revalue::V(start), Revalue::V(end)) => { - anchorstart = *start.first().unwrap(); - anchorstop = *end.last().unwrap(); - }, - _ => panic!("Start and End are not either both u32, or Vecs. This means your regions file is ill-defined. Fix {}.",self.name), - } - }, - _ => panic!("Mode should either be reference-point or scale-regions. {} is not supported.", scale_regions.mode), - } - if scale_regions.mode != "reference-point" { - // scale-regions mode. Assert - assert!(scale_regions.regionbodylength != 0, "scale-regions mode, but regionbodylength is 0."); - if self.regionlength < (scale_regions.unscaled5prime + scale_regions.unscaled3prime) || - self.regionlength - (scale_regions.unscaled5prime + scale_regions.unscaled3prime) < scale_regions.binsize { - println!("Warning ! Region {} is shorter than the binsize (potentially after unscaled regions taken into account. Whole region encoded as 0 or NA", self.name); - let nbin = scale_regions.cols_expected / scale_regions.bwfiles; - for _ in 0..nbin { - bins.push(Bin::Conbin(0,0)); - } - return bins; - } else { - bodybins.extend(self.scale_regionbody(scale_regions, chromend)); - } - } - - // Get flanking regions. - // Note that we still need to deal with exon - non-exon as reference-point mode could require metagene walks. - match self.strand.as_str() { - "+" | "." => { - match (&self.start, &self.end) { - (Revalue::U(start), Revalue::U(end)) => { - let mut leftbins: Vec = Vec::new(); - let mut rightbins: Vec = Vec::new(); - - let mut absstart: i64 = anchorstart as i64 - scale_regions.upstream as i64; - let absstop: i64 = anchorstop as i64 + scale_regions.downstream as i64; - - for binix in (absstart..anchorstart as i64).step_by(scale_regions.binsize as usize) { - if binix < 0 || binix as u32 >= chromend || (binix + scale_regions.binsize as i64) as u32 >= chromend { - leftbins.push(Bin::Conbin(0,0)); - } else if scale_regions.nan_after_end && binix as u32 <= *start { - leftbins.push(Bin::Conbin(0,0)); - } else { - leftbins.push(Bin::Conbin(binix as u32, (binix as u32) + scale_regions.binsize)); - } - } - - for binix in (anchorstop as i64..absstop).step_by(scale_regions.binsize as usize) { - if binix < 0 || binix as u32 >= chromend || (binix + scale_regions.binsize as i64) as u32 >= chromend { - rightbins.push(Bin::Conbin(0,0)); - } else if scale_regions.nan_after_end && binix as u32 >= *end { - rightbins.push(Bin::Conbin(0,0)); - } else { - rightbins.push(Bin::Conbin(binix as u32, (binix as u32) + scale_regions.binsize)); - } - } - - for bin in leftbins.into_iter() { - bins.push(bin); - } - // If we have bodybins, they should be squeezed in here. - for bin in bodybins.into_iter() { - bins.push(bin); - } - // Reset bodybins, as they are consumed. - bodybins = Vec::new(); - for bin in rightbins.into_iter() { - bins.push(bin); - } - } - (Revalue::V(start), Revalue::V(end)) => { - let exons: Vec<(u32, u32)> = start.iter().zip(end.iter()) - .map(|(&s, &e)| (s, e)) - .collect(); - // Right side. - let mut rightbins: Vec = Vec::new(); - let mut lastanchor: u32 = anchorstop; - let mut walked_bps: u32 = 0; - while walked_bps < scale_regions.downstream { - if lastanchor >= chromend { - rightbins.push(Bin::Conbin(0,0)); - walked_bps += scale_regions.binsize; - } else { - let (bin, retanch) = refpoint_exonwalker( - &exons, - lastanchor, - scale_regions.binsize, - chromend, - scale_regions.nan_after_end, - true - ); - rightbins.push(bin); - walked_bps += scale_regions.binsize; - lastanchor = retanch; - } - } - // Left side. - let mut leftbins: Vec = Vec::new(); - let mut lastanchor: u32 = anchorstart; - let mut walked_bps: u32 = 0; - while walked_bps < scale_regions.upstream { - if lastanchor == 0 { - leftbins.push(Bin::Conbin(0,0)); - walked_bps += scale_regions.binsize; - } else { - let (bin, retanch) = refpoint_exonwalker( - &exons, - lastanchor, - scale_regions.binsize, - chromend, - scale_regions.nan_after_end, - false - ); - leftbins.push(bin); - walked_bps += scale_regions.binsize; - lastanchor = retanch; - } - } - // Now we need to reverse the leftbins, as we walked backwards. - leftbins.reverse(); - for bin in leftbins.into_iter() { - bins.push(bin); - } - // If we have bodybins, they should be squeezed in here. - for bin in bodybins.into_iter() { - bins.push(bin); - } - // Reset bodybins, as they are consumed. - bodybins = Vec::new(); - for bin in rightbins.into_iter() { - bins.push(bin); - } - } - _ => panic!("Start and End are not either both u32, or Vecs. This means your regions file is ill-defined. Fix {}. {}:{}-{}", - self.name, self.chrom, self.start, self.end), - } - }, - "-" => { - match (&self.start, &self.end) { - (Revalue::U(start), Revalue::U(end)) => { - let mut leftbins: Vec = Vec::new(); - let mut rightbins: Vec = Vec::new(); - - let mut absstart: i64 = anchorstop as i64 + scale_regions.upstream as i64; - let absstop: i64 = anchorstart as i64 - scale_regions.downstream as i64; - - let steps: Vec<_> = (anchorstop as i64..absstart) - .step_by(scale_regions.binsize as usize) - .collect(); - for binix in steps.into_iter().rev() { - if binix as u32 > chromend || (binix + scale_regions.binsize as i64) as u32 > chromend { - rightbins.push(Bin::Conbin(0,0)); - } else if scale_regions.nan_after_end && binix as u32 >= *end { - leftbins.push(Bin::Conbin(0,0)); - } else { - leftbins.push(Bin::Conbin(binix as u32, (binix as u32) + scale_regions.binsize)); - } - } - - let steps: Vec<_> = (absstop..anchorstart as i64) - .step_by(scale_regions.binsize as usize) - .collect(); - for binix in steps.into_iter().rev() { - if binix < 0 { - leftbins.push(Bin::Conbin(0,0)); - } else if scale_regions.nan_after_end && binix as u32 + scale_regions.binsize <= *start { - rightbins.push(Bin::Conbin(0,0)); - } else { - rightbins.push(Bin::Conbin(binix as u32, (binix as u32) + scale_regions.binsize)); - } - } - - for bin in rightbins.into_iter() { - bins.push(bin); - } - // If we have bodybins, they should be squeezed in here. - bodybins.reverse(); - for bin in bodybins.into_iter() { - bins.push(bin); - } - // Reset bodybins, as they are consumed. - bodybins = Vec::new(); - for bin in leftbins.into_iter() { - bins.push(bin); - } - } - (Revalue::V(start), Revalue::V(end)) => { - let exons: Vec<(u32, u32)> = start.iter().zip(end.iter()) - .map(|(&s, &e)| (s, e)) - .collect(); - // Right side. - let mut rightbins: Vec = Vec::new(); - let mut lastanchor: u32 = anchorstop; - let mut walked_bps: u32 = 0; - while walked_bps < scale_regions.upstream { - if lastanchor >= chromend { - rightbins.push(Bin::Conbin(0,0)); - walked_bps += scale_regions.binsize; - } else { - let (bin, retanch) = refpoint_exonwalker( - &exons, - lastanchor, - scale_regions.binsize, - chromend, - scale_regions.nan_after_end, - true - ); - rightbins.push(bin); - walked_bps += scale_regions.binsize; - lastanchor = retanch; - } - } - // Left side. - let mut leftbins: Vec = Vec::new(); - let mut lastanchor: u32 = anchorstart; - let mut walked_bps: u32 = 0; - while walked_bps < scale_regions.downstream { - if lastanchor == 0 { - leftbins.push(Bin::Conbin(0,0)); - walked_bps += scale_regions.binsize; - } else { - let (bin, retanch) = refpoint_exonwalker( - &exons, - lastanchor, - scale_regions.binsize, - chromend, - scale_regions.nan_after_end, - false - ); - leftbins.push(bin); - walked_bps += scale_regions.binsize; - lastanchor = retanch; - } - } - // Note that now we need to go the exact opposite way as for the + strand as the 'highest position' is the 'starting point'. - rightbins.reverse(); - for bin in rightbins.into_iter() { - bins.push(bin); - } - bodybins.reverse(); - for bin in bodybins.into_iter() { - bins.push(bin); - } - bodybins = Vec::new(); - for bin in leftbins.into_iter() { - bins.push(bin); - } - } - _ => panic!("Start and End are not either both u32, or Vecs. This means your regions file is ill-defined. Fix {}. {}:{}-{}", - self.name, self.chrom, self.start, self.end), - } - }, - _ => panic!("Strand should either be + or - or . {:?} is not supported.", self.strand), - }; - assert_eq!( - bins.len(), - scale_regions.cols_expected / scale_regions.bwfiles, - "Number of bins does not match expected number of columns: {} != {}", - bins.len(), - scale_regions.cols_expected / scale_regions.bwfiles - ); - bins - } - - pub fn scale_regionbody(&self, scale_regions: &Scalingregions, chromend: u32) -> Vec { - // A vector of bins needs to be constructed for regionbody. - // Since this is scaling mode, 'linspace' functionality is reproduced. - match self.strand.as_str() { - "+" | "." => { - match (&self.start, &self.end) { - (Revalue::U(start), Revalue::U(end)) => { - // No exons, forward strand. divide start - end as such: - // |---un5prime---|---bodylength---|---un3prime---| - let mut un5bins: Vec = Vec::new(); - let mut un3bins: Vec = Vec::new(); - let mut innerbins: Vec = Vec::new(); - if scale_regions.unscaled5prime > 0 { - un5bins.extend((0..scale_regions.unscaled5prime) - .step_by(scale_regions.binsize as usize) - .map(|i| Bin::Conbin(*start + i, *start + i + scale_regions.binsize)) - .collect::>()); - } - - if scale_regions.unscaled3prime > 0 { - un3bins.extend( (0..scale_regions.unscaled3prime) - .step_by(scale_regions.binsize as usize) - .rev() - .map(|i| Bin::Conbin(*end - i - scale_regions.binsize, *end - i)) - .collect::>() ); - } - let bodystart = *start + scale_regions.unscaled5prime; - let bodyend = *end - scale_regions.unscaled3prime; - - // Get the bins over the body length. These need to be scaled, so similar to deeptools < 4, linspace is used. - let neededbins = (scale_regions.regionbodylength / scale_regions.binsize) as usize; - // There's multiple options here: - // transcriptlength >= regionbodylength -> linspace - // regionbodylength / binsize > transcriptlength <= regionbodylength -> 1 >= binsize > binsize. - // transcriptlength <= regionbodylength / binsize -> index repetitions with binsize of one. - let scaledbinsize = std::cmp::min(std::cmp::max((bodyend - bodystart) / neededbins as u32, 1), scale_regions.binsize); - - innerbins.extend( Array1::linspace(bodystart as f32, (bodyend - scaledbinsize) as f32, neededbins) - .mapv(|x| x as u32) - .map(|x| Bin::Conbin(*x, *x + scaledbinsize)) - .into_iter() - .collect::>() ); - - // Combine the vectors and return - let mut combined_bins = Vec::new(); - if scale_regions.unscaled5prime > 0 { - combined_bins.extend(un5bins.into_iter()); - } - combined_bins.extend(innerbins.into_iter()); - if scale_regions.unscaled3prime > 0 { - combined_bins.extend(un3bins.into_iter()); - } - return combined_bins; - }, - (Revalue::V(start), Revalue::V(end)) => { - let exons: Vec<(u32, u32)> = start.iter().zip(end.iter()) - .map(|(&s, &e)| (s, e)) - .collect(); - let mut un5bins: Vec = Vec::new(); - let mut un3bins: Vec = Vec::new(); - if scale_regions.unscaled5prime > 0 { - let mut walked_bps: u32 = 0; - let mut lastanchor: u32 = start[0]; - - while walked_bps < scale_regions.unscaled5prime { - let (bin, retanch) = refpoint_exonwalker( - &exons, - lastanchor, - scale_regions.binsize, - chromend, - scale_regions.nan_after_end, - true - ); - un5bins.push(bin); - walked_bps += scale_regions.binsize; - lastanchor = retanch; - } - } - if scale_regions.unscaled3prime > 0 { - let mut walked_bps: u32 = 0; - let mut lastanchor: u32 = *end.last().unwrap(); - - while walked_bps < scale_regions.unscaled3prime { - let (bin, retanch) = refpoint_exonwalker( - &exons, - lastanchor, - scale_regions.binsize, - chromend, - scale_regions.nan_after_end, - false - ); - un3bins.push(bin); - walked_bps += scale_regions.binsize; - lastanchor = retanch; - } - } - un3bins.reverse(); - - let bodystart: u32; - let bodyend: u32; - if scale_regions.unscaled5prime > 0 { - bodystart = un5bins.last().unwrap().get_end(); - } else { - bodystart = *start.first().unwrap(); - } - if scale_regions.unscaled3prime > 0 { - bodyend = un3bins.first().unwrap().get_start(); - } else { - bodyend = *end.last().unwrap(); - } - let truebodylength = self.regionlength - scale_regions.unscaled5prime - scale_regions.unscaled3prime; - let neededbins = (scale_regions.regionbodylength / scale_regions.binsize) as usize; - let scaledbinsize = std::cmp::min(std::cmp::max(truebodylength / neededbins as u32, 1), scale_regions.binsize); - // Things are a bit tricky now, as we can do a linspace over the region, but we don't have a notion of the exons. - // I think easiest is to just pull a hashmap over the entire region, get linspace from hashmap to vec, and be done with it. - // technically we fetch a bunch of regions we don't need, but this operation is not too expensive. - - let mut binmap: HashMap = HashMap::new(); - let mut lastanchor: u32 = bodystart; - - for ix in 0..((truebodylength/scaledbinsize)+1) { - let (bin, anchor) = refpoint_exonwalker( - &exons, - lastanchor, - scaledbinsize, - chromend, - scale_regions.nan_after_end, - true - ); - lastanchor = anchor; - match bin { - Bin::Conbin(start, end) => { - if end > bodyend { - binmap.insert(ix, Bin::Conbin(start, bodyend)); - } else { - binmap.insert(ix, Bin::Conbin(start, end)); - } - }, - Bin::Catbin(bins) => { - if bins.last().unwrap().1 > bodyend { - let mut newbins: Vec<(u32, u32)> = Vec::new(); - for (s, e) in bins.iter() { - if *e > bodyend { - newbins.push((*s, bodyend)); - } else { - newbins.push((*s, *e)); - } - } - binmap.insert(ix, Bin::Catbin(newbins)); - } else { - binmap.insert(ix, Bin::Catbin(bins)); - } - }, - } - } - - let innerbins = Array1::linspace(0 as f32, ((truebodylength)/scaledbinsize) as f32, neededbins) - .mapv(|x| x as u32) - .map(|x| binmap.get(&x).unwrap().clone()) - .into_iter() - .collect::>(); - - // Combine the vectors and return - let mut combined_bins = Vec::new(); - if scale_regions.unscaled5prime > 0 { - combined_bins.extend(un5bins.into_iter()); - } - combined_bins.extend(innerbins.into_iter()); - if scale_regions.unscaled3prime > 0 { - combined_bins.extend(un3bins.into_iter()); - } - return combined_bins; - }, - _ => panic!("Start and End are not either both u32, or Vecs. This means your regions file is ill-defined."), - } - }, - "-" => { - match (&self.start, &self.end) { - (Revalue::U(start), Revalue::U(end)) => { - // No exons, negative strand. divide start - end as such: - // |---un3prime---|---bodylength---|---un5prime---| - let mut un5bins: Vec = Vec::new(); - let mut un3bins: Vec = Vec::new(); - let mut innerbins: Vec = Vec::new(); - if scale_regions.unscaled5prime > 0 { - un5bins.extend((0..scale_regions.unscaled5prime) - .step_by(scale_regions.binsize as usize) - .map(|i| Bin::Conbin(*end - i - scale_regions.binsize, *end - i)) - .collect::>()); - } - - if scale_regions.unscaled3prime > 0 { - un3bins.extend( (0..scale_regions.unscaled3prime) - .step_by(scale_regions.binsize as usize) - .rev() - .map(|i| Bin::Conbin(*start + scale_regions.unscaled3prime - i - scale_regions.binsize, *start + scale_regions.unscaled3prime - i)) - .collect::>() ); - } - let bodystart = *start + scale_regions.unscaled3prime; - let bodyend = *end - scale_regions.unscaled5prime; - - // Get the bins over the body length. These need to be scaled, so similar to deeptools < 4, linspace is used. - let neededbins = (scale_regions.regionbodylength / scale_regions.binsize) as usize; - // There's multiple options here: - // transcriptlength >= regionbodylength -> linspace - // regionbodylength / binsize > transcriptlength <= regionbodylength -> 1 >= binsize > binsize. - // transcriptlength <= regionbodylength / binsize -> index repetitions with binsize of one. - let mut scaledbinsize = (bodyend - bodystart)/neededbins as u32; - if scaledbinsize == 0 { - scaledbinsize = 1; - } - if scaledbinsize > scale_regions.binsize { - scaledbinsize = scale_regions.binsize; - } - - innerbins.extend( Array1::linspace(bodystart as f32, (bodyend - scaledbinsize) as f32, neededbins) - .mapv(|x| x as u32) - .map(|x| Bin::Conbin(*x, *x + scaledbinsize)) - .into_iter() - .collect::>() ); - - // Reverse innerbins to go from 3' -> 5' - innerbins.reverse(); - // Combine the vectors and return - let mut combined_bins = Vec::new(); - if scale_regions.unscaled3prime > 0 { - combined_bins.extend(un3bins.into_iter()); - } - combined_bins.extend(innerbins.into_iter()); - if scale_regions.unscaled5prime > 0 { - combined_bins.extend(un5bins.into_iter()); - } - return combined_bins; - }, - (Revalue::V(start), Revalue::V(end)) => { - let exons: Vec<(u32, u32)> = start.iter().zip(end.iter()) - .map(|(&s, &e)| (s, e)) - .collect(); - let mut un5bins: Vec = Vec::new(); - let mut un3bins: Vec = Vec::new(); - if scale_regions.unscaled5prime > 0 { - let mut walked_bps: u32 = 0; - let mut lastanchor: u32 = *end.last().unwrap(); - - while walked_bps < scale_regions.unscaled5prime { - let (bin, retanch) = refpoint_exonwalker( - &exons, - lastanchor, - scale_regions.binsize, - chromend, - scale_regions.nan_after_end, - false - ); - un5bins.push(bin); - walked_bps += scale_regions.binsize; - lastanchor = retanch; - } - } - un5bins.reverse(); - - if scale_regions.unscaled3prime > 0 { - let mut walked_bps: u32 = 0; - let mut lastanchor: u32 = start[0]; - - while walked_bps < scale_regions.unscaled3prime { - let (bin, retanch) = refpoint_exonwalker( - &exons, - lastanchor, - scale_regions.binsize, - chromend, - scale_regions.nan_after_end, - true - ); - un3bins.push(bin); - walked_bps += scale_regions.binsize; - lastanchor = retanch; - } - } - - let bodystart: u32; - let bodyend: u32; - if scale_regions.unscaled3prime > 0 { - bodystart = un3bins.last().unwrap().get_end(); - } else { - bodystart = *start.first().unwrap(); - } - if scale_regions.unscaled5prime > 0 { - bodyend = un5bins.first().unwrap().get_start(); - } else { - bodyend = *end.last().unwrap(); - } - let truebodylength = self.regionlength - scale_regions.unscaled5prime - scale_regions.unscaled3prime; - let neededbins = (scale_regions.regionbodylength / scale_regions.binsize) as usize; - let scaledbinsize = std::cmp::min(std::cmp::max(truebodylength / neededbins as u32, 1), scale_regions.binsize); - // Things are a bit tricky now, as we can do a linspace over the region, but we don't have a notion of the exons. - // I think easiest is to just pull a hashmap over the entire region, get linspace from hashmap to vec, and be done with it. - // technically we fetch a bunch of regions we don't need, but this operation is not too expensive. - - let mut binmap: HashMap = HashMap::new(); - let mut lastanchor: u32 = bodystart; - - for ix in 0..((truebodylength/scaledbinsize)+1) { - let (bin, anchor) = refpoint_exonwalker( - &exons, - lastanchor, - scaledbinsize, - chromend, - scale_regions.nan_after_end, - true - ); - lastanchor = anchor; - match bin { - Bin::Conbin(start, end) => { - if end > bodyend { - binmap.insert(ix, Bin::Conbin(start, bodyend)); - } else { - binmap.insert(ix, Bin::Conbin(start, end)); - } - }, - Bin::Catbin(bins) => { - if bins.last().unwrap().1 > bodyend { - let mut newbins: Vec<(u32, u32)> = Vec::new(); - for (s, e) in bins.iter() { - if *e > bodyend { - newbins.push((*s, bodyend)); - } else { - newbins.push((*s, *e)); - } - } - binmap.insert(ix, Bin::Catbin(newbins)); - } else { - binmap.insert(ix, Bin::Catbin(bins)); - } - }, - } - } - - let innerbins = Array1::linspace(0 as f32, ((truebodylength)/scaledbinsize) as f32, neededbins) - .mapv(|x| x as u32) - .map(|x| binmap.get(&x).unwrap().clone()) - .into_iter() - .collect::>(); - // Combine the vectors and return - let mut combined_bins = Vec::new(); - if scale_regions.unscaled5prime > 0 { - combined_bins.extend(un5bins.into_iter()); - } - combined_bins.extend(innerbins.into_iter()); - if scale_regions.unscaled3prime > 0 { - combined_bins.extend(un3bins.into_iter()); - } - return combined_bins; - }, - _ => panic!("Start and End are not either both u32, or Vecs. This means your regions file is ill-defined."), - } - }, - _ => panic!("Strand should either be + or - or . {:?} is not supported.", self.strand), - } - } -} - -fn refpoint_exonwalker(exons: &Vec<(u32, u32)>, anchor: u32, binsize: u32, chromend: u32, nan_after_end: bool, forward: bool) -> (Bin, u32) { - // Basic function that walks over exons, and returns a Bin (Either Conbin or Catbin) and the last anchorpoint. - let mut anchorix: Option = None; - - for (ix, exon) in exons.iter().enumerate() { - if anchor >= exon.0 && anchor <= exon.1 { - anchorix = Some(ix); - } - } - if forward { - // Walk forward (downstream, towards chromosome end) - match anchorix { - Some(i) => { - // anchor sits in an exon. Check if anchor + binsize is also in same exon. - if anchor + binsize <= exons[i].1 { - (Bin::Conbin(anchor, anchor + binsize), anchor + binsize) - } else { - // anchor + binsize is not in same exon. We need a Catbin. - // Things are a bit more difficult here as well, as we need to walk exons. - let mut start_end_vec: Vec<(u32, u32)> = Vec::new(); - start_end_vec.push( (anchor, exons[i].1) ); - - let mut remainingbin: u32 = binsize - (exons[i].1 - anchor); - let mut lastix: usize = i; - let mut lastanchor: u32 = exons[i].1; - - while remainingbin != 0 { - if lastix + 1 < exons.len() { - // next exon is available. - // Two options here: - // the remainder fits in the lastix + 1 exon. We are done. - // the remainder doesn't fit in the lastix + 1 exon. We need to walk further. - if exons[lastix+1].1 - exons[lastix+1].0 >= remainingbin { - // remainder fits in next exon. - start_end_vec.push( (exons[lastix+1].0, exons[lastix+1].0 + remainingbin) ); - lastanchor = exons[lastix+1].0 + remainingbin; - remainingbin = 0; - } else { - // Remainder is larger then our exon. We need another walk. - start_end_vec.push( (exons[lastix+1].0, exons[lastix+1].1) ); - remainingbin -= exons[lastix+1].1 - exons[lastix+1].0; - lastix += 1; - lastanchor = exons[lastix].1; - } - } else { - // No next exon available. Remainder can just be genomic. - // The last entry here can be changed to include the last part. - if nan_after_end { - start_end_vec.push((0,0)); - } else { - let last = start_end_vec.last_mut().unwrap(); - assert_eq!( - last.1, - lastanchor, - "In the exon - genomic walk, our coordinates are not contiguous" - ); - // Check we don't fall of the chromosome. - if lastanchor + remainingbin > chromend { - last.1 = chromend; - lastanchor = chromend; - } else { - last.1 = lastanchor + remainingbin; - lastanchor = lastanchor + remainingbin; - } - } - remainingbin = 0; - } - } - // We now have a Vec of start - end, we can construct a CatBin. - // Note that CatBins are (absstart, absstop, ((intstart1, intstart2), ...)) - // This seems weird, but makes sure we need to slice the bigwig file only once per bin. - if start_end_vec.len() == 1 { - (Bin::Conbin(anchor, lastanchor), lastanchor) - } else { - (Bin::Catbin(start_end_vec), lastanchor) - } - } - }, - None => { - // our anchor doesn't sit in exons. We just return the anchor + binsize as Bin - if anchor + binsize > chromend { - (Bin::Conbin(anchor, chromend), chromend) - } else { - (Bin::Conbin(anchor, anchor + binsize), anchor + binsize) - } - } - } - } else { - // Walk backwards (upstream, towards chromosome start) - match anchorix { - Some(i) => { - // anchor sits in an exon. Check if anchor - binsize is also in same exon. - if anchor - binsize >= exons[i].0 { - (Bin::Conbin(anchor - binsize, anchor), anchor - binsize) - } else { - // anchor + binsize is not in same exon. We need a Catbin. - // Things are a bit more difficult here as well, as we need to walk exons. - let mut start_end_vec: Vec<(u32, u32)> = Vec::new(); - start_end_vec.push( (exons[i].0, anchor) ); - - let mut remainingbin: u32 = binsize - (anchor - exons[i].0); - let mut lastix: usize = i; - let mut lastanchor: u32 = exons[i].0; - - while remainingbin != 0 { - if lastix >= 1 { - // previous exon is available. - // Two options here: - // the remainder fits in the previous exon. We are done. - // the remainder doesn't fit in the previous exon. We need to walk further. - if exons[lastix-1].1 - exons[lastix-1].0 >= remainingbin { - // remainder fits in next exon. - start_end_vec.push( (exons[lastix-1].1 - remainingbin, exons[lastix-1].1) ); - lastanchor = exons[lastix-1].1 - remainingbin; - remainingbin = 0; - } else { - // Remainder is larger then our exon. We need another walk. - start_end_vec.push( (exons[lastix-1].0, exons[lastix-1].1 ) ); - remainingbin -= exons[lastix-1].1 - exons[lastix-1].0; - lastix -= 1; - lastanchor = exons[lastix].0; - } - } else { - // No previous exon available. Remainder can just be genomic. - // The last entry here can be changed to include the last part. - if nan_after_end { - start_end_vec.push( (0,0) ); - } else { - let last = start_end_vec.last_mut().unwrap(); - assert_eq!( - last.0, - lastanchor, - "In the exon - genomic walk (reverse), our coordinates are not contiguous" - ); - // Check we don't go in the negative. - if lastanchor < remainingbin { - last.0 = 0; - lastanchor = 0; - } else { - last.0 = lastanchor - remainingbin; - lastanchor = lastanchor - remainingbin; - } - } - remainingbin = 0; - } - } - // We now have a Vec of start - end, we can construct a CatBin. - // Note that CatBins are (absstart, absstop, ((intstart1, intstart2), ...)) - // This seems weird, but makes sure we need to slice the bigwig file only once per bin. - if start_end_vec.len() == 1 { - (Bin::Conbin(lastanchor, anchor), lastanchor) - } else { - start_end_vec.reverse(); - (Bin::Catbin(start_end_vec), lastanchor) - } - } - }, - None => { - // our anchor doesn't sit in exons. We just return the anchor - binsize as Bin - if anchor < binsize { - (Bin::Conbin(0, anchor), 0) - } else { - (Bin::Conbin(anchor - binsize, anchor), anchor - binsize) - } - } - } - } -} - fn matrix_dump( sortregions: &str, sortusing: &str, diff --git a/src/covcalc.rs b/src/covcalc.rs index 0013a7da5e..76341be642 100644 --- a/src/covcalc.rs +++ b/src/covcalc.rs @@ -1,18 +1,48 @@ use rust_htslib::bam::{self, Read, IndexedReader, record::Cigar}; +use rust_htslib::bam::ext::BamRecordExtensions; use std::collections::HashMap; use tempfile::{Builder, TempPath}; use std::io::{BufWriter, Write}; use std::cmp::min; +use std::fmt; +use ndarray::Array1; +use rayon::prelude::*; +use std::collections::HashSet; -pub fn parse_regions(regions: &Vec<(String, u32, u32)>, bam_ifile: &str) -> (Vec<(String, u32, u32)>, HashMap) { +pub fn parse_regions(regions: &Vec<(String, u32, u32)>, bam_ifile: Vec<&str>) -> (Vec, HashMap) { // Takes a vector of regions, and a bam reference // returns a vector of regions, with all chromosomes and full lengths if original regions was empty // Else it validates the regions against the information from the bam header // Finally, a Vec with chromsizes is returned as well. - - let bam = IndexedReader::from_path(bam_ifile).unwrap(); + let mut found_chroms: HashMap = HashMap::new(); + for bam in bam_ifile.iter() { + let bam = IndexedReader::from_path(bam).unwrap(); + let chroms: Vec = bam.header().target_names().iter().map(|x| String::from_utf8(x.to_vec()).unwrap()).collect(); + for chrom in chroms.iter() { + // if it's not in the hashmap, add it, else increment count + if !found_chroms.contains_key(chrom) { + found_chroms.insert(chrom.clone(), 1); + } else { + let count = found_chroms.get_mut(chrom).unwrap(); + *count += 1; + } + } + } + let mut validchroms: Vec = Vec::new(); + // loop over all chroms in the hashmap, if the count is expected, include them + for (chrom, count) in found_chroms.iter() { + if *count == bam_ifile.len() { + validchroms.push(chrom.clone()); + } else { + println!("Chromosome {} is missing in at least one bam file, and thus ignored!", chrom); + } + } + // Crash if validchroms is empty. + assert!(!validchroms.is_empty(), "No chromosomes found that are present in all bam files. Did you mix references ?"); + // Read header from first bam file + let bam = IndexedReader::from_path(bam_ifile[0]).unwrap(); let header = bam.header().clone(); - let mut chromregions: Vec<(String, u32, u32)> = Vec::new(); + let mut chromregions: Vec = Vec::new(); let mut chromsizes = HashMap::new(); if regions.is_empty() { // if regions is empty, we default to all chromosomes, full length @@ -21,7 +51,20 @@ pub fn parse_regions(regions: &Vec<(String, u32, u32)>, bam_ifile: &str) -> (Vec .expect("Invalid UTF-8 in chromosome name"); let chromlen = header.target_len(tid) .expect("Error retrieving length for chromosome"); - chromregions.push((chromname.clone(), 0, chromlen as u32)); + // If chromname is not in validchroms, skip it. + if !validchroms.contains(&chromname) { + continue; + } + let _reg = Region { + chrom: chromname.clone(), + start: Revalue::U(0), + end: Revalue::U(chromlen as u32), + score: String::from("."), + strand: String::from("."), + name: format!("{}:{}-{}", chromname, 0, chromlen), + regionlength: chromlen as u32, + }; + chromregions.push(_reg); chromsizes.insert(chromname.to_string(), chromlen as u32); } } else { @@ -31,23 +74,33 @@ pub fn parse_regions(regions: &Vec<(String, u32, u32)>, bam_ifile: &str) -> (Vec .expect("Invalid UTF-8 in chromosome name"); let chromlen = header.target_len(tid) .expect("Error retrieving length for chromosome"); - chromsizes.insert(chromname, chromlen as u32); + if validchroms.contains(&chromname) { + chromsizes.insert(chromname, chromlen as u32); + } } - let validchroms: Vec = header - .target_names() - .iter() - .map(|x| String::from_utf8(x.to_vec()).unwrap()) - .collect(); for region in regions { let chromname = ®ion.0; assert!(region.1 < region.2, "Region start must be strictly less than region end."); - assert!(validchroms.contains(chromname), "Chromosome {} not found in bam header", chromname); - chromregions.push((chromname.clone(), region.1, region.2)); + // Check if chromname is in validchroms + if !validchroms.contains(chromname) { + continue; + } + let _reg = Region { + chrom: chromname.clone(), + start: Revalue::U(region.1), + end: Revalue::U(region.2), + score: String::from("."), + strand: String::from("."), + name: format!("{}:{}-{}", chromname, region.1, region.2), + regionlength: region.2 - region.1, + }; + chromregions.push(_reg); } } // Sort regions to make our live easier down the line - chromregions.sort_by(|a, b| a.0.cmp(&b.0).then(a.1.cmp(&b.1))); + // Sort Vec of Regions per chromosome, and then by start. + chromregions.sort_by(|a, b| a.chrom.cmp(&b.chrom).then(a.get_startu().cmp(&b.get_startu()))); return (chromregions, chromsizes); } @@ -56,12 +109,13 @@ pub fn parse_regions(regions: &Vec<(String, u32, u32)>, bam_ifile: &str) -> (Vec #[allow(unused_assignments)] pub fn bam_pileup<'a>( bam_ifile: &str, - region: &'a (String, u32, u32), - binsize: &u32, + regionvec: &'a Vec, + provbs: &u32, ispe: &bool, ignorechr: &Vec, _filters: &Alignmentfilters, collapse: bool, + gene_mode: bool ) -> ( Vec, // temp bedgraph file. u32, // mapped reads @@ -69,14 +123,13 @@ pub fn bam_pileup<'a>( Vec, // read lengths Vec, // fragment lengths ) { - + let mut bs = *provbs; + let mut binsize = &bs; // constant to check if read is first in pair (relevant later) const FREAD: u16 = 0x40; // open bam file and fetch proper chrom let mut bam = IndexedReader::from_path(bam_ifile).unwrap(); - bam.fetch((region.0.as_str(), region.1, region.2)) - .expect(&format!("Error fetching region: {:?}", region)); // init variables for mapping statistics and lengths let mut mapped_reads: u32 = 0; @@ -95,256 +148,1345 @@ pub fn bam_pileup<'a>( // Two cases: either the binsize is 1, or it is > 1. // Counting between the two modes is different. In binsize == 1 we compute pileups // for binsize > 1, we count the number of reads that overlap a bin. - if binsize > &1 { - // populate the bg vector with 0 counts over all bins - let mut counts: Vec = vec![0.0; (region.2 - region.1).div_ceil(*binsize) as usize]; - // let mut binstart = region.1; - let mut binix: u32 = 0; + + // Convert region to tuple to ease computations. + for regstruct in regionvec.iter() { + // There are two options here: + // either we are supposed to calculate coverage over regions (variable binsize required) gene_mode = true + // or we have a regular bin setting, gene_mode = false + let mut region: (String, u32, u32); + if gene_mode { + region = (regstruct.chrom.clone(), regstruct.get_startu(), regstruct.get_endu()); + bs = region.2 - region.1; + binsize = &bs; + } else { + region = (regstruct.chrom.clone(), regstruct.get_startu(), regstruct.get_endu()); + } + //let region = (regstruct.chrom.clone(), regstruct.get_startu(), regstruct.get_endu()); + bam.fetch((region.0.as_str(), region.1, region.2)) + .expect(&format!("Error fetching region: {:?}", region)); + + if binsize > &1 { + let mut counts: Vec; + let mut startstr: String = region.1.to_string(); + let mut endstr: String = region.2.to_string(); + + if gene_mode { + // It could be that we are in metagene mode, i.e. we only want counts over exons + // In this we need another iter - fetch per regstruct + match (regstruct.start.clone(), regstruct.end.clone()) { + (Revalue::U(start), Revalue::U(end)) => { + counts = vec![0.0; 1]; + for record in bam.records() { + let record = record.expect("Error parsing record."); + if !ignorechr.contains(®ion.0) { + if record.is_unmapped() { + unmapped_reads += 1; + } else { + mapped_reads += 1; + if *ispe { + if record.is_paired() && record.is_proper_pair() && (record.flags() & FREAD != 0) { + fraglens.push(record.insert_size().abs() as u32); + } + } + readlens.push(record.seq_len() as u32); + } + } + counts[0] += 1.0; + } + }, + (Revalue::V(starts), Revalue::V(ends)) => { + // Make a string with the start values comma separated + startstr = starts.iter().map(|x| x.to_string()).collect::>().join(","); + endstr = ends.iter().map(|x| x.to_string()).collect::>().join(","); + + counts = vec![0.0; 1]; + let exons: Vec<(u32, u32)> = starts.iter().zip(ends.iter()) + .map(|(&s, &e)| (s, e)) + .collect(); + for exon in exons { + bam.fetch((regstruct.chrom.as_str(), exon.0, exon.1)) + .expect(&format!("Error fetching region: {}:{},{}", regstruct.chrom, exon.0, exon.1)); + for record in bam.records() { + let record = record.expect("Error parsing record."); + if !ignorechr.contains(®ion.0) { + if record.is_unmapped() { + unmapped_reads += 1; + } else { + mapped_reads += 1; + if *ispe { + if record.is_paired() && record.is_proper_pair() && (record.flags() & FREAD != 0) { + fraglens.push(record.insert_size().abs() as u32); + } + } + readlens.push(record.seq_len() as u32); + } + } + counts[0] += 1.0; + } + } + }, + _ => panic!("Start and End are not either both u32, or Vecs. This means your regions file is ill-defined. Fix {}.",regstruct.name), + } + } else { + // populate the bg vector with 0 counts over all bins + counts = vec![0.0; (region.2 - region.1).div_ceil(*binsize) as usize]; + // let mut binstart = region.1; + let mut binix: u32 = 0; + + for record in bam.records() { + let record = record.expect("Error parsing record."); + if !ignorechr.contains(®ion.0) { + if record.is_unmapped() { + unmapped_reads += 1; + } else { + mapped_reads += 1; + if *ispe { + if record.is_paired() && record.is_proper_pair() && (record.flags() & FREAD != 0) { + fraglens.push(record.insert_size().abs() as u32); + } + } + readlens.push(record.seq_len() as u32); + } + } + + let indices: HashSet = record + .aligned_blocks() + .filter(|x| (x[1] as u32) < region.2) + .flat_map(|x| x[0] as u32..x[1] as u32) + .map(|x| (x / binsize) as usize) + .collect(); + indices.into_iter() + .for_each(|ix| counts[ix] += 1.0); + } + } + let mut writer = BufWriter::new(&bg); + // There are two scenarios: + // bamCoverage mode -> we can collapse bins with same coverage (collapse = true) + // bamCompare & others -> We cannot collapse the bins, yet. (collapse = false) + if counts.len() == 1 { + writeln!(writer, "{}\t{}\t{}\t{}", region.0, startstr, endstr, counts[0]).unwrap(); + } else { + if collapse { + let mut lcov = counts[0]; + let mut lstart = region.1; + let mut lend = region.1 + binsize; + let mut start = lstart; + let mut end = lend; + let mut bin: u32 = 0; - for record in bam.records() { - let record = record.expect("Error parsing record."); - if !ignorechr.contains(®ion.0) { - if record.is_unmapped() { - unmapped_reads += 1; - } else { - mapped_reads += 1; - if *ispe { - if record.is_paired() && record.is_proper_pair() && (record.flags() & FREAD != 0) { - fraglens.push(record.insert_size().abs() as u32); + for (ix, count) in counts.into_iter().skip(1).enumerate() { + bin = (ix + 1) as u32; // offset of 1 due to skip(1) + start = (bin * binsize) + region.1; + end = min(start + binsize, region.2); + if count != lcov { + //bg.push((®ion.0, lstart, lend, lcov)); + writeln!(writer, "{}\t{}\t{}\t{}", region.0, lstart, lend, lcov).unwrap(); + lstart = lend; + lcov = count; } + lend = end; + } + // write last entry + writeln!(writer, "{}\t{}\t{}\t{}", region.0, lstart, lend, lcov).unwrap(); + } else { + let mut start = region.1; + let mut end = region.1 + binsize; + writeln!(writer, "{}\t{}\t{}\t{}", region.0, start, end, counts[0]).unwrap(); + for (ix, count) in counts.into_iter().skip(1).enumerate() { + let bin = (ix + 1) as u32; + start = (bin * binsize) + region.1; + end = min(start + binsize, region.2); + writeln!(writer, "{}\t{}\t{}\t{}", region.0, start, end, count).unwrap(); } - readlens.push(record.seq_len() as u32); } } - let blocks = bam_blocks(record); - // keep a record of bin indices that have been updated already - let mut changedbins: Vec = Vec::new(); - for block in blocks.into_iter() { - // Don't count blocks that exceed the chromosome - if block.0 >= region.2 { - continue; - } - binix = block.0 / binsize; - if !changedbins.contains(&binix) { - counts[binix as usize] += 1.0; - changedbins.push(binix); - } - // Don't count blocks that exceed the chromosome - if block.1 >= region.2 { - continue; - } - // Note that our blocks are strictly less then region ends, hence no problem with bin spewing at end: - // binix = [a,b) where b == region.2 would divide into binix+1 (doesn't exist). - binix = block.1 / binsize; - if !changedbins.contains(&binix) { - counts[binix as usize] += 1.0; - changedbins.push(binix); + // binsize = 1 + } else { + let mut l_start: u32 = region.1; + let mut l_end: u32 = region.1; + let mut l_cov: u32 = 0; + let mut pileup_start: bool = true; + let mut writer = BufWriter::new(&bg); + let mut written: bool = false; + for record in bam.records() { + let record = record.expect("Error parsing record."); + if !ignorechr.contains(®ion.0) { + if record.is_unmapped() { + unmapped_reads += 1; + } else { + mapped_reads += 1; + if *ispe { + if record.is_paired() && record.is_proper_pair() && (record.flags() & FREAD != 0) { + fraglens.push(record.insert_size().abs() as u32); + } + } + readlens.push(record.seq_len() as u32); + } } } - // if changedbins contains non-continuous blocks (perhaps read length spans multiple bins), update the inbetweens - if let (Some(&min), Some(&max)) = (changedbins.iter().min(), changedbins.iter().max()) { - for ix in min..=max { - if !changedbins.contains(&ix) { - counts[ix as usize] += 1.0; - changedbins.push(ix); + // Refetch bam file to reset iterator. + bam.fetch((region.0.as_str(), region.1, region.2)) + .expect(&format!("Error fetching region: {:?}", region)); + for p in bam.pileup() { + // Per default pileups count deletions in cigar string too. + // For consistency with previous deepTools functionality, we ignore them. + // to be fair I think they shouldn't be counted anyhow, but who am I ? + // Note that coverages can be 0 now. + let pileup = p.expect("Error parsing pileup."); + let mut cov: u32 = 0; + for _a in pileup.alignments() { + if !_a.is_del() { + cov += 1; + } + } + let pos = pileup.pos(); + if pileup_start { + // if the first pileup is not at the start of the region, write 0 coverage + if pos > l_start { + if collapse { + writeln!(writer, "{}\t{}\t{}\t{}", region.0, l_start, pos, 0 as f32).unwrap(); + } else { + for p in l_start..pos { + writeln!(writer, "{}\t{}\t{}\t{}", region.0, p, p + 1, 0 as f32).unwrap(); + } + } + written = true; + } + pileup_start = false; + l_start = pos; + l_cov = cov; + } else { + if pos != l_end + 1 { + if collapse { + writeln!(writer, "{}\t{}\t{}\t{}", region.0, l_start, l_end + 1, l_cov as f32).unwrap(); + writeln!(writer, "{}\t{}\t{}\t{}", region.0, l_end + 1, pos, 0 as f32).unwrap(); + } else { + for p in l_start..l_end + 1 { + writeln!(writer, "{}\t{}\t{}\t{}", region.0, p, p + 1, l_cov as f32).unwrap(); + } + for p in l_end + 1..pos { + writeln!(writer, "{}\t{}\t{}\t{}", region.0, p, p + 1, 0 as f32).unwrap(); + } + } + written = true; + l_start = pos; + l_cov = cov; + } else if l_cov != cov { + if collapse { + writeln!(writer, "{}\t{}\t{}\t{}", region.0, l_start, pos, l_cov as f32).unwrap(); + } else { + for p in l_start..pos { + writeln!(writer, "{}\t{}\t{}\t{}", region.0, p, p + 1, l_cov as f32).unwrap(); + } + } + written = true; + l_start = pos; + l_cov = cov; } } + l_end = pos; + l_cov = cov; } - } - let mut writer = BufWriter::new(&bg); - // There are two scenarios: - // bamCoverage mode -> we can collapse bins with same coverage (collapse = true) - // bamCompare & others -> We cannot collapse the bins, yet. (collapse = false) - if counts.len() == 1 { - writeln!(writer, "{}\t{}\t{}\t{}", region.0, region.1, region.2, counts[0]).unwrap(); - } else { - if collapse { - let mut lcov = counts[0]; - let mut lstart = region.1; - let mut lend = region.1 + binsize; - let mut start = lstart; - let mut end = lend; - let mut bin: u32 = 0; - - for (ix, count) in counts.into_iter().skip(1).enumerate() { - bin = (ix + 1) as u32; // offset of 1 due to skip(1) - start = (bin * binsize) + region.1; - end = min(start + binsize, region.2); - if count != lcov { - //bg.push((®ion.0, lstart, lend, lcov)); - writeln!(writer, "{}\t{}\t{}\t{}", region.0, lstart, lend, lcov).unwrap(); - lstart = lend; - lcov = count; + // if bg is empty, whole region is 0 coverage + if !written { + if collapse { + writeln!(writer, "{}\t{}\t{}\t{}", region.0, l_start, region.2, 0 as f32).unwrap(); + } else { + for p in l_start..region.2 { + writeln!(writer, "{}\t{}\t{}\t{}", region.0, p, p + 1, 0 as f32).unwrap(); } - lend = end; } - // write last entry - writeln!(writer, "{}\t{}\t{}\t{}", region.0, lstart, lend, lcov).unwrap(); } else { - let mut start = region.1; - let mut end = region.1 + binsize; - writeln!(writer, "{}\t{}\t{}\t{}", region.0, start, end, counts[0]).unwrap(); - for (ix, count) in counts.into_iter().skip(1).enumerate() { - let bin = (ix + 1) as u32; - start = (bin * binsize) + region.1; - end = min(start + binsize, region.2); - writeln!(writer, "{}\t{}\t{}\t{}", region.0, start, end, count).unwrap(); + // Still need to write the last pileup(s) + if collapse { + writeln!(writer, "{}\t{}\t{}\t{}", region.0, l_start, l_end + 1, l_cov as f32).unwrap(); + // Make sure that if we didn't reach end of chromosome, we still write 0 cov. + if l_end + 1 < region.2 { + writeln!(writer, "{}\t{}\t{}\t{}", region.0, l_end + 1, region.2, 0 as f32).unwrap(); + } + } else { + for p in l_start..l_end + 1 { + writeln!(writer, "{}\t{}\t{}\t{}", region.0, p, p + 1, l_cov as f32).unwrap(); + } + if l_end + 1 < region.2 { + for p in l_end + 1..region.2 + 1 { + writeln!(writer, "{}\t{}\t{}\t{}", region.0, p, p + 1, 0 as f32).unwrap(); + } + } } } } + } + let bgpath = bg.into_temp_path(); + let tmpvec = vec![bgpath]; + return (tmpvec, mapped_reads, unmapped_reads, readlens, fraglens); +} - // binsize = 1 - } else { - let mut l_start: u32 = region.1; - let mut l_end: u32 = region.1; - let mut l_cov: u32 = 0; - let mut pileup_start: bool = true; - let mut writer = BufWriter::new(&bg); - let mut written: bool = false; - for record in bam.records() { - let record = record.expect("Error parsing record."); - if !ignorechr.contains(®ion.0) { - if record.is_unmapped() { - unmapped_reads += 1; - } else { - mapped_reads += 1; - if *ispe { - if record.is_paired() && record.is_proper_pair() && (record.flags() & FREAD != 0) { - fraglens.push(record.insert_size().abs() as u32); - } - } - readlens.push(record.seq_len() as u32); +pub struct Alignmentfilters { + pub minmappingquality: u8, + pub samflaginclude: u16, + pub samflagexclude: u16, + pub minfraglen: u32, + pub maxfraglen: u32, +} + + +#[derive(Clone, Debug)] +pub struct Region { + pub chrom: String, + pub start: Revalue, + pub end: Revalue, + pub score: String, + pub strand: String, + pub name: String, + pub regionlength: u32 +} + +impl Region { + pub fn assert_end(&self, chromend: u32) { + match &self.end { + Revalue::U(end) => { + assert!( + *end <= chromend, + "Region end goes beyond chromosome boundary. Fix {}. {} {} {} (chr end = {})", self.name, self.chrom, self.start, self.end, chromend + ); + }, + Revalue::V(ends) => { + for end in ends.iter() { + assert!( + *end <= chromend, + "Region end goes beyond chromosome boundary. Fix {}. {} {} {} (chr end = {})", self.name, self.chrom, self.start, end, chromend + ); } } } - // Refetch bam file to reset iterator. - bam.fetch((region.0.as_str(), region.1, region.2)) - .expect(&format!("Error fetching region: {:?}", region)); - for p in bam.pileup() { - // Per default pileups count deletions in cigar string too. - // For consistency with previous deepTools functionality, we ignore them. - // to be fair I think they shouldn't be counted anyhow, but who am I ? - // Note that coverages can be 0 now. - let pileup = p.expect("Error parsing pileup."); - let mut cov: u32 = 0; - for _a in pileup.alignments() { - if !_a.is_del() { - cov += 1; + } + + pub fn get_anchorpoint(&self, referencepoint: &str) -> u32 { + // reference-point mode. + // What is exactly returned depends on a couple of parameters + // what is the referencepoint : TSS, center, TES + // what is the strand: +, -, . (note . is assumed to be +) + // depending on if we have exon blocks (start / end are Revalue V == Vectors) or not (start / end are Revalue U == u32's) + match referencepoint { + "TSS" => { + match self.strand.as_str() { + "+" | "." => match &self.start {Revalue::U(start) => *start, Revalue::V(starts) => starts[0]}, + "-" => match &self.end {Revalue::U(end) => *end, Revalue::V(ends) => *ends.last().unwrap()}, + _ => panic!("Strand should either be + or - or . {:?} is not supported.", self.strand), + } + }, + "TES" => { + match self.strand.as_str() { + "+" | "." => match &self.end {Revalue::U(end) => *end, Revalue::V(ends) => *ends.last().unwrap()}, + "-" => match &self.start {Revalue::U(start) => *start, Revalue::V(starts) => starts[0]}, + _ => panic!("Strand should either be + or - or . {:?} is not supported.", self.strand), + } + }, + "center" => { + // Here + or - doesn't matter. It is important though if we have 'metagenes' or not. + match (&self.start, &self.end) { + (Revalue::U(start), Revalue::U(end)) => { + (*start + *end) / 2 + }, + (Revalue::V(starts), Revalue::V(ends)) => { + let exonlength: u32 = starts.iter().zip(ends.iter()).map(|(s, e)| e - s).sum(); + let middle = exonlength / 2; + let mut cumsum: u32 = 0; + for (s, e) in starts.iter().zip(ends.iter()) { + cumsum += e - s; + if cumsum >= middle { + return s + (middle - (cumsum - (e - s))); + } + } + panic!( + "Middle of region not found. Fix {}. {}:{}-{}", + self.name, self.chrom, self.start, self.end + ) + }, + _ => panic!( + "Start and End are not either both u32, or Vecs. This means your regions file is ill-defined. Fix {}. {}:{}-{}", + self.name, self.chrom, self.start, self.end + ), + } + }, + _ => panic!( + "Reference should either be TSS, TES or center. {:?} is not supported.", + referencepoint + ), + } + } + + pub fn get_anchor_bins(&self, scale_regions: &Scalingregions, chromend: u32) -> Vec { + // Given an anchorpoint, return a vector, start, end , middle + // The order of the vector is always 5' -> 3', meaning 'increasing' for +/. regions, and 'decreasing' for - regions. + // At this stage, two situations are possible: + // - self.start / self.end are Revalue::U, meaning we are in 'non metagene' mode. + // - self.start / self.end are Revalue::V, meaning we are in 'metagene' mode, and the bins returned are exon-aware. + // We need a notion of bins that don't make sense (i.e. beyond chromosome boundaries). These are encoded as (0,0) + + let mut bins: Vec = Vec::new(); + let mut bodybins: Vec = Vec::new(); + + // Define anchorpoints + let anchorstart; + let anchorstop; + match scale_regions.mode.as_str() { + "reference-point" => { + anchorstart = self.get_anchorpoint(&scale_regions.referencepoint); + anchorstop = anchorstart; + }, + "scale-regions" => { + match (&self.start, &self.end) { + (Revalue::U(start), Revalue::U(end)) => { + anchorstart = *start; + anchorstop = *end; + }, + (Revalue::V(start), Revalue::V(end)) => { + anchorstart = *start.first().unwrap(); + anchorstop = *end.last().unwrap(); + }, + _ => panic!("Start and End are not either both u32, or Vecs. This means your regions file is ill-defined. Fix {}.",self.name), + } + }, + _ => panic!("Mode should either be reference-point or scale-regions. {} is not supported.", scale_regions.mode), + } + if scale_regions.mode != "reference-point" { + // scale-regions mode. Assert + assert!(scale_regions.regionbodylength != 0, "scale-regions mode, but regionbodylength is 0."); + if self.regionlength < (scale_regions.unscaled5prime + scale_regions.unscaled3prime) || + self.regionlength - (scale_regions.unscaled5prime + scale_regions.unscaled3prime) < scale_regions.binsize { + println!("Warning ! Region {} is shorter than the binsize (potentially after unscaled regions taken into account. Whole region encoded as 0 or NA", self.name); + let nbin = scale_regions.cols_expected / scale_regions.bwfiles; + for _ in 0..nbin { + bins.push(Bin::Conbin(0,0)); } + return bins; + } else { + bodybins.extend(self.scale_regionbody(scale_regions, chromend)); } - let pos = pileup.pos(); - if pileup_start { - // if the first pileup is not at the start of the region, write 0 coverage - if pos > l_start { - if collapse { - writeln!(writer, "{}\t{}\t{}\t{}", region.0, l_start, pos, 0 as f32).unwrap(); - } else { - for p in l_start..pos { - writeln!(writer, "{}\t{}\t{}\t{}", region.0, p, p + 1, 0 as f32).unwrap(); + } + + // Get flanking regions. + // Note that we still need to deal with exon - non-exon as reference-point mode could require metagene walks. + match self.strand.as_str() { + "+" | "." => { + match (&self.start, &self.end) { + (Revalue::U(start), Revalue::U(end)) => { + let mut leftbins: Vec = Vec::new(); + let mut rightbins: Vec = Vec::new(); + + let mut absstart: i64 = anchorstart as i64 - scale_regions.upstream as i64; + let absstop: i64 = anchorstop as i64 + scale_regions.downstream as i64; + + for binix in (absstart..anchorstart as i64).step_by(scale_regions.binsize as usize) { + if binix < 0 || binix as u32 >= chromend || (binix + scale_regions.binsize as i64) as u32 >= chromend { + leftbins.push(Bin::Conbin(0,0)); + } else if scale_regions.nan_after_end && binix as u32 <= *start { + leftbins.push(Bin::Conbin(0,0)); + } else { + leftbins.push(Bin::Conbin(binix as u32, (binix as u32) + scale_regions.binsize)); + } + } + + for binix in (anchorstop as i64..absstop).step_by(scale_regions.binsize as usize) { + if binix < 0 || binix as u32 >= chromend || (binix + scale_regions.binsize as i64) as u32 >= chromend { + rightbins.push(Bin::Conbin(0,0)); + } else if scale_regions.nan_after_end && binix as u32 >= *end { + rightbins.push(Bin::Conbin(0,0)); + } else { + rightbins.push(Bin::Conbin(binix as u32, (binix as u32) + scale_regions.binsize)); + } + } + + for bin in leftbins.into_iter() { + bins.push(bin); + } + // If we have bodybins, they should be squeezed in here. + for bin in bodybins.into_iter() { + bins.push(bin); + } + // Reset bodybins, as they are consumed. + bodybins = Vec::new(); + for bin in rightbins.into_iter() { + bins.push(bin); + } + } + (Revalue::V(start), Revalue::V(end)) => { + let exons: Vec<(u32, u32)> = start.iter().zip(end.iter()) + .map(|(&s, &e)| (s, e)) + .collect(); + // Right side. + let mut rightbins: Vec = Vec::new(); + let mut lastanchor: u32 = anchorstop; + let mut walked_bps: u32 = 0; + while walked_bps < scale_regions.downstream { + if lastanchor >= chromend { + rightbins.push(Bin::Conbin(0,0)); + walked_bps += scale_regions.binsize; + } else { + let (bin, retanch) = refpoint_exonwalker( + &exons, + lastanchor, + scale_regions.binsize, + chromend, + scale_regions.nan_after_end, + true + ); + rightbins.push(bin); + walked_bps += scale_regions.binsize; + lastanchor = retanch; + } + } + // Left side. + let mut leftbins: Vec = Vec::new(); + let mut lastanchor: u32 = anchorstart; + let mut walked_bps: u32 = 0; + while walked_bps < scale_regions.upstream { + if lastanchor == 0 { + leftbins.push(Bin::Conbin(0,0)); + walked_bps += scale_regions.binsize; + } else { + let (bin, retanch) = refpoint_exonwalker( + &exons, + lastanchor, + scale_regions.binsize, + chromend, + scale_regions.nan_after_end, + false + ); + leftbins.push(bin); + walked_bps += scale_regions.binsize; + lastanchor = retanch; + } + } + // Now we need to reverse the leftbins, as we walked backwards. + leftbins.reverse(); + for bin in leftbins.into_iter() { + bins.push(bin); + } + // If we have bodybins, they should be squeezed in here. + for bin in bodybins.into_iter() { + bins.push(bin); + } + // Reset bodybins, as they are consumed. + bodybins = Vec::new(); + for bin in rightbins.into_iter() { + bins.push(bin); } } - written = true; + _ => panic!("Start and End are not either both u32, or Vecs. This means your regions file is ill-defined. Fix {}. {}:{}-{}", + self.name, self.chrom, self.start, self.end), } - pileup_start = false; - l_start = pos; - l_cov = cov; - } else { - if pos != l_end + 1 { - if collapse { - writeln!(writer, "{}\t{}\t{}\t{}", region.0, l_start, l_end + 1, l_cov as f32).unwrap(); - writeln!(writer, "{}\t{}\t{}\t{}", region.0, l_end + 1, pos, 0 as f32).unwrap(); - } else { - for p in l_start..l_end + 1 { - writeln!(writer, "{}\t{}\t{}\t{}", region.0, p, p + 1, l_cov as f32).unwrap(); + }, + "-" => { + match (&self.start, &self.end) { + (Revalue::U(start), Revalue::U(end)) => { + let mut leftbins: Vec = Vec::new(); + let mut rightbins: Vec = Vec::new(); + + let mut absstart: i64 = anchorstop as i64 + scale_regions.upstream as i64; + let absstop: i64 = anchorstart as i64 - scale_regions.downstream as i64; + + let steps: Vec<_> = (anchorstop as i64..absstart) + .step_by(scale_regions.binsize as usize) + .collect(); + for binix in steps.into_iter().rev() { + if binix as u32 > chromend || (binix + scale_regions.binsize as i64) as u32 > chromend { + rightbins.push(Bin::Conbin(0,0)); + } else if scale_regions.nan_after_end && binix as u32 >= *end { + leftbins.push(Bin::Conbin(0,0)); + } else { + leftbins.push(Bin::Conbin(binix as u32, (binix as u32) + scale_regions.binsize)); + } } - for p in l_end + 1..pos { - writeln!(writer, "{}\t{}\t{}\t{}", region.0, p, p + 1, 0 as f32).unwrap(); + + let steps: Vec<_> = (absstop..anchorstart as i64) + .step_by(scale_regions.binsize as usize) + .collect(); + for binix in steps.into_iter().rev() { + if binix < 0 { + leftbins.push(Bin::Conbin(0,0)); + } else if scale_regions.nan_after_end && binix as u32 + scale_regions.binsize <= *start { + rightbins.push(Bin::Conbin(0,0)); + } else { + rightbins.push(Bin::Conbin(binix as u32, (binix as u32) + scale_regions.binsize)); + } + } + + for bin in rightbins.into_iter() { + bins.push(bin); + } + // If we have bodybins, they should be squeezed in here. + bodybins.reverse(); + for bin in bodybins.into_iter() { + bins.push(bin); + } + // Reset bodybins, as they are consumed. + bodybins = Vec::new(); + for bin in leftbins.into_iter() { + bins.push(bin); } } - written = true; - l_start = pos; - l_cov = cov; - } else if l_cov != cov { - if collapse { - writeln!(writer, "{}\t{}\t{}\t{}", region.0, l_start, pos, l_cov as f32).unwrap(); - } else { - for p in l_start..pos { - writeln!(writer, "{}\t{}\t{}\t{}", region.0, p, p + 1, l_cov as f32).unwrap(); + (Revalue::V(start), Revalue::V(end)) => { + let exons: Vec<(u32, u32)> = start.iter().zip(end.iter()) + .map(|(&s, &e)| (s, e)) + .collect(); + // Right side. + let mut rightbins: Vec = Vec::new(); + let mut lastanchor: u32 = anchorstop; + let mut walked_bps: u32 = 0; + while walked_bps < scale_regions.upstream { + if lastanchor >= chromend { + rightbins.push(Bin::Conbin(0,0)); + walked_bps += scale_regions.binsize; + } else { + let (bin, retanch) = refpoint_exonwalker( + &exons, + lastanchor, + scale_regions.binsize, + chromend, + scale_regions.nan_after_end, + true + ); + rightbins.push(bin); + walked_bps += scale_regions.binsize; + lastanchor = retanch; + } + } + // Left side. + let mut leftbins: Vec = Vec::new(); + let mut lastanchor: u32 = anchorstart; + let mut walked_bps: u32 = 0; + while walked_bps < scale_regions.downstream { + if lastanchor == 0 { + leftbins.push(Bin::Conbin(0,0)); + walked_bps += scale_regions.binsize; + } else { + let (bin, retanch) = refpoint_exonwalker( + &exons, + lastanchor, + scale_regions.binsize, + chromend, + scale_regions.nan_after_end, + false + ); + leftbins.push(bin); + walked_bps += scale_regions.binsize; + lastanchor = retanch; + } + } + // Note that now we need to go the exact opposite way as for the + strand as the 'highest position' is the 'starting point'. + rightbins.reverse(); + for bin in rightbins.into_iter() { + bins.push(bin); + } + bodybins.reverse(); + for bin in bodybins.into_iter() { + bins.push(bin); + } + bodybins = Vec::new(); + for bin in leftbins.into_iter() { + bins.push(bin); } } - written = true; - l_start = pos; - l_cov = cov; + _ => panic!("Start and End are not either both u32, or Vecs. This means your regions file is ill-defined. Fix {}. {}:{}-{}", + self.name, self.chrom, self.start, self.end), } - } - l_end = pos; - l_cov = cov; + }, + _ => panic!("Strand should either be + or - or . {:?} is not supported.", self.strand), + }; + assert_eq!( + bins.len(), + scale_regions.cols_expected / scale_regions.bwfiles, + "Number of bins does not match expected number of columns: {} != {}", + bins.len(), + scale_regions.cols_expected / scale_regions.bwfiles + ); + bins + } + + pub fn get_endu(&self) -> u32 { + match &self.end { + Revalue::U(end) => *end, + Revalue::V(ends) => *ends.last().unwrap(), } - // if bg is empty, whole region is 0 coverage - if !written { - if collapse { - writeln!(writer, "{}\t{}\t{}\t{}", region.0, l_start, region.2, 0 as f32).unwrap(); - } else { - for p in l_start..region.2 { - writeln!(writer, "{}\t{}\t{}\t{}", region.0, p, p + 1, 0 as f32).unwrap(); + } + + pub fn get_startu(&self) -> u32 { + match &self.start { + Revalue::U(start) => *start, + Revalue::V(starts) => *starts.first().unwrap(), + } + } + + pub fn scale_regionbody(&self, scale_regions: &Scalingregions, chromend: u32) -> Vec { + // A vector of bins needs to be constructed for regionbody. + // Since this is scaling mode, 'linspace' functionality is reproduced. + match self.strand.as_str() { + "+" | "." => { + match (&self.start, &self.end) { + (Revalue::U(start), Revalue::U(end)) => { + // No exons, forward strand. divide start - end as such: + // |---un5prime---|---bodylength---|---un3prime---| + let mut un5bins: Vec = Vec::new(); + let mut un3bins: Vec = Vec::new(); + let mut innerbins: Vec = Vec::new(); + if scale_regions.unscaled5prime > 0 { + un5bins.extend((0..scale_regions.unscaled5prime) + .step_by(scale_regions.binsize as usize) + .map(|i| Bin::Conbin(*start + i, *start + i + scale_regions.binsize)) + .collect::>()); + } + + if scale_regions.unscaled3prime > 0 { + un3bins.extend( (0..scale_regions.unscaled3prime) + .step_by(scale_regions.binsize as usize) + .rev() + .map(|i| Bin::Conbin(*end - i - scale_regions.binsize, *end - i)) + .collect::>() ); + } + let bodystart = *start + scale_regions.unscaled5prime; + let bodyend = *end - scale_regions.unscaled3prime; + + // Get the bins over the body length. These need to be scaled, so similar to deeptools < 4, linspace is used. + let neededbins = (scale_regions.regionbodylength / scale_regions.binsize) as usize; + // There's multiple options here: + // transcriptlength >= regionbodylength -> linspace + // regionbodylength / binsize > transcriptlength <= regionbodylength -> 1 >= binsize > binsize. + // transcriptlength <= regionbodylength / binsize -> index repetitions with binsize of one. + let scaledbinsize = std::cmp::min(std::cmp::max((bodyend - bodystart) / neededbins as u32, 1), scale_regions.binsize); + + innerbins.extend( Array1::linspace(bodystart as f32, (bodyend - scaledbinsize) as f32, neededbins) + .mapv(|x| x as u32) + .map(|x| Bin::Conbin(*x, *x + scaledbinsize)) + .into_iter() + .collect::>() ); + + // Combine the vectors and return + let mut combined_bins = Vec::new(); + if scale_regions.unscaled5prime > 0 { + combined_bins.extend(un5bins.into_iter()); + } + combined_bins.extend(innerbins.into_iter()); + if scale_regions.unscaled3prime > 0 { + combined_bins.extend(un3bins.into_iter()); + } + return combined_bins; + }, + (Revalue::V(start), Revalue::V(end)) => { + let exons: Vec<(u32, u32)> = start.iter().zip(end.iter()) + .map(|(&s, &e)| (s, e)) + .collect(); + let mut un5bins: Vec = Vec::new(); + let mut un3bins: Vec = Vec::new(); + if scale_regions.unscaled5prime > 0 { + let mut walked_bps: u32 = 0; + let mut lastanchor: u32 = start[0]; + + while walked_bps < scale_regions.unscaled5prime { + let (bin, retanch) = refpoint_exonwalker( + &exons, + lastanchor, + scale_regions.binsize, + chromend, + scale_regions.nan_after_end, + true + ); + un5bins.push(bin); + walked_bps += scale_regions.binsize; + lastanchor = retanch; + } + } + if scale_regions.unscaled3prime > 0 { + let mut walked_bps: u32 = 0; + let mut lastanchor: u32 = *end.last().unwrap(); + + while walked_bps < scale_regions.unscaled3prime { + let (bin, retanch) = refpoint_exonwalker( + &exons, + lastanchor, + scale_regions.binsize, + chromend, + scale_regions.nan_after_end, + false + ); + un3bins.push(bin); + walked_bps += scale_regions.binsize; + lastanchor = retanch; + } + } + un3bins.reverse(); + + let bodystart: u32; + let bodyend: u32; + if scale_regions.unscaled5prime > 0 { + bodystart = un5bins.last().unwrap().get_end(); + } else { + bodystart = *start.first().unwrap(); + } + if scale_regions.unscaled3prime > 0 { + bodyend = un3bins.first().unwrap().get_start(); + } else { + bodyend = *end.last().unwrap(); + } + let truebodylength = self.regionlength - scale_regions.unscaled5prime - scale_regions.unscaled3prime; + let neededbins = (scale_regions.regionbodylength / scale_regions.binsize) as usize; + let scaledbinsize = std::cmp::min(std::cmp::max(truebodylength / neededbins as u32, 1), scale_regions.binsize); + // Things are a bit tricky now, as we can do a linspace over the region, but we don't have a notion of the exons. + // I think easiest is to just pull a hashmap over the entire region, get linspace from hashmap to vec, and be done with it. + // technically we fetch a bunch of regions we don't need, but this operation is not too expensive. + + let mut binmap: HashMap = HashMap::new(); + let mut lastanchor: u32 = bodystart; + + for ix in 0..((truebodylength/scaledbinsize)+1) { + let (bin, anchor) = refpoint_exonwalker( + &exons, + lastanchor, + scaledbinsize, + chromend, + scale_regions.nan_after_end, + true + ); + lastanchor = anchor; + match bin { + Bin::Conbin(start, end) => { + if end > bodyend { + binmap.insert(ix, Bin::Conbin(start, bodyend)); + } else { + binmap.insert(ix, Bin::Conbin(start, end)); + } + }, + Bin::Catbin(bins) => { + if bins.last().unwrap().1 > bodyend { + let mut newbins: Vec<(u32, u32)> = Vec::new(); + for (s, e) in bins.iter() { + if *e > bodyend { + newbins.push((*s, bodyend)); + } else { + newbins.push((*s, *e)); + } + } + binmap.insert(ix, Bin::Catbin(newbins)); + } else { + binmap.insert(ix, Bin::Catbin(bins)); + } + }, + } + } + + let innerbins = Array1::linspace(0 as f32, ((truebodylength)/scaledbinsize) as f32, neededbins) + .mapv(|x| x as u32) + .map(|x| binmap.get(&x).unwrap().clone()) + .into_iter() + .collect::>(); + + // Combine the vectors and return + let mut combined_bins = Vec::new(); + if scale_regions.unscaled5prime > 0 { + combined_bins.extend(un5bins.into_iter()); + } + combined_bins.extend(innerbins.into_iter()); + if scale_regions.unscaled3prime > 0 { + combined_bins.extend(un3bins.into_iter()); + } + return combined_bins; + }, + _ => panic!("Start and End are not either both u32, or Vecs. This means your regions file is ill-defined."), } - } - } else { - // Still need to write the last pileup(s) - if collapse { - writeln!(writer, "{}\t{}\t{}\t{}", region.0, l_start, l_end + 1, l_cov as f32).unwrap(); - // Make sure that if we didn't reach end of chromosome, we still write 0 cov. - if l_end + 1 < region.2 { - writeln!(writer, "{}\t{}\t{}\t{}", region.0, l_end + 1, region.2, 0 as f32).unwrap(); + }, + "-" => { + match (&self.start, &self.end) { + (Revalue::U(start), Revalue::U(end)) => { + // No exons, negative strand. divide start - end as such: + // |---un3prime---|---bodylength---|---un5prime---| + let mut un5bins: Vec = Vec::new(); + let mut un3bins: Vec = Vec::new(); + let mut innerbins: Vec = Vec::new(); + if scale_regions.unscaled5prime > 0 { + un5bins.extend((0..scale_regions.unscaled5prime) + .step_by(scale_regions.binsize as usize) + .map(|i| Bin::Conbin(*end - i - scale_regions.binsize, *end - i)) + .collect::>()); + } + + if scale_regions.unscaled3prime > 0 { + un3bins.extend( (0..scale_regions.unscaled3prime) + .step_by(scale_regions.binsize as usize) + .rev() + .map(|i| Bin::Conbin(*start + scale_regions.unscaled3prime - i - scale_regions.binsize, *start + scale_regions.unscaled3prime - i)) + .collect::>() ); + } + let bodystart = *start + scale_regions.unscaled3prime; + let bodyend = *end - scale_regions.unscaled5prime; + + // Get the bins over the body length. These need to be scaled, so similar to deeptools < 4, linspace is used. + let neededbins = (scale_regions.regionbodylength / scale_regions.binsize) as usize; + // There's multiple options here: + // transcriptlength >= regionbodylength -> linspace + // regionbodylength / binsize > transcriptlength <= regionbodylength -> 1 >= binsize > binsize. + // transcriptlength <= regionbodylength / binsize -> index repetitions with binsize of one. + let mut scaledbinsize = (bodyend - bodystart)/neededbins as u32; + if scaledbinsize == 0 { + scaledbinsize = 1; + } + if scaledbinsize > scale_regions.binsize { + scaledbinsize = scale_regions.binsize; + } + + innerbins.extend( Array1::linspace(bodystart as f32, (bodyend - scaledbinsize) as f32, neededbins) + .mapv(|x| x as u32) + .map(|x| Bin::Conbin(*x, *x + scaledbinsize)) + .into_iter() + .collect::>() ); + + // Reverse innerbins to go from 3' -> 5' + innerbins.reverse(); + // Combine the vectors and return + let mut combined_bins = Vec::new(); + if scale_regions.unscaled3prime > 0 { + combined_bins.extend(un3bins.into_iter()); + } + combined_bins.extend(innerbins.into_iter()); + if scale_regions.unscaled5prime > 0 { + combined_bins.extend(un5bins.into_iter()); + } + return combined_bins; + }, + (Revalue::V(start), Revalue::V(end)) => { + let exons: Vec<(u32, u32)> = start.iter().zip(end.iter()) + .map(|(&s, &e)| (s, e)) + .collect(); + let mut un5bins: Vec = Vec::new(); + let mut un3bins: Vec = Vec::new(); + if scale_regions.unscaled5prime > 0 { + let mut walked_bps: u32 = 0; + let mut lastanchor: u32 = *end.last().unwrap(); + + while walked_bps < scale_regions.unscaled5prime { + let (bin, retanch) = refpoint_exonwalker( + &exons, + lastanchor, + scale_regions.binsize, + chromend, + scale_regions.nan_after_end, + false + ); + un5bins.push(bin); + walked_bps += scale_regions.binsize; + lastanchor = retanch; + } + } + un5bins.reverse(); + + if scale_regions.unscaled3prime > 0 { + let mut walked_bps: u32 = 0; + let mut lastanchor: u32 = start[0]; + + while walked_bps < scale_regions.unscaled3prime { + let (bin, retanch) = refpoint_exonwalker( + &exons, + lastanchor, + scale_regions.binsize, + chromend, + scale_regions.nan_after_end, + true + ); + un3bins.push(bin); + walked_bps += scale_regions.binsize; + lastanchor = retanch; + } + } + + let bodystart: u32; + let bodyend: u32; + if scale_regions.unscaled3prime > 0 { + bodystart = un3bins.last().unwrap().get_end(); + } else { + bodystart = *start.first().unwrap(); + } + if scale_regions.unscaled5prime > 0 { + bodyend = un5bins.first().unwrap().get_start(); + } else { + bodyend = *end.last().unwrap(); + } + let truebodylength = self.regionlength - scale_regions.unscaled5prime - scale_regions.unscaled3prime; + let neededbins = (scale_regions.regionbodylength / scale_regions.binsize) as usize; + let scaledbinsize = std::cmp::min(std::cmp::max(truebodylength / neededbins as u32, 1), scale_regions.binsize); + // Things are a bit tricky now, as we can do a linspace over the region, but we don't have a notion of the exons. + // I think easiest is to just pull a hashmap over the entire region, get linspace from hashmap to vec, and be done with it. + // technically we fetch a bunch of regions we don't need, but this operation is not too expensive. + + let mut binmap: HashMap = HashMap::new(); + let mut lastanchor: u32 = bodystart; + + for ix in 0..((truebodylength/scaledbinsize)+1) { + let (bin, anchor) = refpoint_exonwalker( + &exons, + lastanchor, + scaledbinsize, + chromend, + scale_regions.nan_after_end, + true + ); + lastanchor = anchor; + match bin { + Bin::Conbin(start, end) => { + if end > bodyend { + binmap.insert(ix, Bin::Conbin(start, bodyend)); + } else { + binmap.insert(ix, Bin::Conbin(start, end)); + } + }, + Bin::Catbin(bins) => { + if bins.last().unwrap().1 > bodyend { + let mut newbins: Vec<(u32, u32)> = Vec::new(); + for (s, e) in bins.iter() { + if *e > bodyend { + newbins.push((*s, bodyend)); + } else { + newbins.push((*s, *e)); + } + } + binmap.insert(ix, Bin::Catbin(newbins)); + } else { + binmap.insert(ix, Bin::Catbin(bins)); + } + }, + } + } + + let innerbins = Array1::linspace(0 as f32, ((truebodylength)/scaledbinsize) as f32, neededbins) + .mapv(|x| x as u32) + .map(|x| binmap.get(&x).unwrap().clone()) + .into_iter() + .collect::>(); + // Combine the vectors and return + let mut combined_bins = Vec::new(); + if scale_regions.unscaled5prime > 0 { + combined_bins.extend(un5bins.into_iter()); + } + combined_bins.extend(innerbins.into_iter()); + if scale_regions.unscaled3prime > 0 { + combined_bins.extend(un3bins.into_iter()); + } + return combined_bins; + }, + _ => panic!("Start and End are not either both u32, or Vecs. This means your regions file is ill-defined."), } - } else { - for p in l_start..l_end + 1 { - writeln!(writer, "{}\t{}\t{}\t{}", region.0, p, p + 1, l_cov as f32).unwrap(); + }, + _ => panic!("Strand should either be + or - or . {:?} is not supported.", self.strand), + } + } +} + +fn refpoint_exonwalker(exons: &Vec<(u32, u32)>, anchor: u32, binsize: u32, chromend: u32, nan_after_end: bool, forward: bool) -> (Bin, u32) { + // Basic function that walks over exons, and returns a Bin (Either Conbin or Catbin) and the last anchorpoint. + let mut anchorix: Option = None; + + for (ix, exon) in exons.iter().enumerate() { + if anchor >= exon.0 && anchor <= exon.1 { + anchorix = Some(ix); + } + } + if forward { + // Walk forward (downstream, towards chromosome end) + match anchorix { + Some(i) => { + // anchor sits in an exon. Check if anchor + binsize is also in same exon. + if anchor + binsize <= exons[i].1 { + (Bin::Conbin(anchor, anchor + binsize), anchor + binsize) + } else { + // anchor + binsize is not in same exon. We need a Catbin. + // Things are a bit more difficult here as well, as we need to walk exons. + let mut start_end_vec: Vec<(u32, u32)> = Vec::new(); + start_end_vec.push( (anchor, exons[i].1) ); + + let mut remainingbin: u32 = binsize - (exons[i].1 - anchor); + let mut lastix: usize = i; + let mut lastanchor: u32 = exons[i].1; + + while remainingbin != 0 { + if lastix + 1 < exons.len() { + // next exon is available. + // Two options here: + // the remainder fits in the lastix + 1 exon. We are done. + // the remainder doesn't fit in the lastix + 1 exon. We need to walk further. + if exons[lastix+1].1 - exons[lastix+1].0 >= remainingbin { + // remainder fits in next exon. + start_end_vec.push( (exons[lastix+1].0, exons[lastix+1].0 + remainingbin) ); + lastanchor = exons[lastix+1].0 + remainingbin; + remainingbin = 0; + } else { + // Remainder is larger then our exon. We need another walk. + start_end_vec.push( (exons[lastix+1].0, exons[lastix+1].1) ); + remainingbin -= exons[lastix+1].1 - exons[lastix+1].0; + lastix += 1; + lastanchor = exons[lastix].1; + } + } else { + // No next exon available. Remainder can just be genomic. + // The last entry here can be changed to include the last part. + if nan_after_end { + start_end_vec.push((0,0)); + } else { + let last = start_end_vec.last_mut().unwrap(); + assert_eq!( + last.1, + lastanchor, + "In the exon - genomic walk, our coordinates are not contiguous" + ); + // Check we don't fall of the chromosome. + if lastanchor + remainingbin > chromend { + last.1 = chromend; + lastanchor = chromend; + } else { + last.1 = lastanchor + remainingbin; + lastanchor = lastanchor + remainingbin; + } + } + remainingbin = 0; + } + } + // We now have a Vec of start - end, we can construct a CatBin. + // Note that CatBins are (absstart, absstop, ((intstart1, intstart2), ...)) + // This seems weird, but makes sure we need to slice the bigwig file only once per bin. + if start_end_vec.len() == 1 { + (Bin::Conbin(anchor, lastanchor), lastanchor) + } else { + (Bin::Catbin(start_end_vec), lastanchor) + } } - if l_end + 1 < region.2 { - for p in l_end + 1..region.2 + 1 { - writeln!(writer, "{}\t{}\t{}\t{}", region.0, p, p + 1, 0 as f32).unwrap(); + }, + None => { + // our anchor doesn't sit in exons. We just return the anchor + binsize as Bin + if anchor + binsize > chromend { + (Bin::Conbin(anchor, chromend), chromend) + } else { + (Bin::Conbin(anchor, anchor + binsize), anchor + binsize) + } + } + } + } else { + // Walk backwards (upstream, towards chromosome start) + match anchorix { + Some(i) => { + // anchor sits in an exon. Check if anchor - binsize is also in same exon. + if anchor - binsize >= exons[i].0 { + (Bin::Conbin(anchor - binsize, anchor), anchor - binsize) + } else { + // anchor + binsize is not in same exon. We need a Catbin. + // Things are a bit more difficult here as well, as we need to walk exons. + let mut start_end_vec: Vec<(u32, u32)> = Vec::new(); + start_end_vec.push( (exons[i].0, anchor) ); + + let mut remainingbin: u32 = binsize - (anchor - exons[i].0); + let mut lastix: usize = i; + let mut lastanchor: u32 = exons[i].0; + + while remainingbin != 0 { + if lastix >= 1 { + // previous exon is available. + // Two options here: + // the remainder fits in the previous exon. We are done. + // the remainder doesn't fit in the previous exon. We need to walk further. + if exons[lastix-1].1 - exons[lastix-1].0 >= remainingbin { + // remainder fits in next exon. + start_end_vec.push( (exons[lastix-1].1 - remainingbin, exons[lastix-1].1) ); + lastanchor = exons[lastix-1].1 - remainingbin; + remainingbin = 0; + } else { + // Remainder is larger then our exon. We need another walk. + start_end_vec.push( (exons[lastix-1].0, exons[lastix-1].1 ) ); + remainingbin -= exons[lastix-1].1 - exons[lastix-1].0; + lastix -= 1; + lastanchor = exons[lastix].0; + } + } else { + // No previous exon available. Remainder can just be genomic. + // The last entry here can be changed to include the last part. + if nan_after_end { + start_end_vec.push( (0,0) ); + } else { + let last = start_end_vec.last_mut().unwrap(); + assert_eq!( + last.0, + lastanchor, + "In the exon - genomic walk (reverse), our coordinates are not contiguous" + ); + // Check we don't go in the negative. + if lastanchor < remainingbin { + last.0 = 0; + lastanchor = 0; + } else { + last.0 = lastanchor - remainingbin; + lastanchor = lastanchor - remainingbin; + } + } + remainingbin = 0; + } + } + // We now have a Vec of start - end, we can construct a CatBin. + // Note that CatBins are (absstart, absstop, ((intstart1, intstart2), ...)) + // This seems weird, but makes sure we need to slice the bigwig file only once per bin. + if start_end_vec.len() == 1 { + (Bin::Conbin(lastanchor, anchor), lastanchor) + } else { + start_end_vec.reverse(); + (Bin::Catbin(start_end_vec), lastanchor) } } + }, + None => { + // our anchor doesn't sit in exons. We just return the anchor - binsize as Bin + if anchor < binsize { + (Bin::Conbin(0, anchor), 0) + } else { + (Bin::Conbin(anchor - binsize, anchor), anchor - binsize) + } } } } - let bgpath = bg.into_temp_path(); - let tmpvec = vec![bgpath]; - return (tmpvec, mapped_reads, unmapped_reads, readlens, fraglens); } -/// Extract contigious blocks from a bam record -/// Blocks are split per insertion, padding, deletion and ref skip -fn bam_blocks(rec: bam::Record) -> Vec<(u32, u32)> { - let mut blocks: Vec<(u32, u32)> = Vec::new(); - let mut pos = rec.pos(); - - for c in rec.cigar().iter() { - match c { - Cigar::Match(len) | Cigar::Equal(len) | Cigar::Diff(len) => { - let start = pos; - let end = pos + *len as i64 -1; - blocks.push((start as u32, end as u32)); - pos = end; - } - Cigar::Ins(len) | Cigar::Pad(len) => { - pos += *len as i64; - } - Cigar::Del(len) | Cigar::RefSkip(len) => { - pos += *len as i64; + +pub fn region_divider(regs: &Vec) -> Vec> { + // This function decides on how regions are divided to process in parallel. + // Since the Vec could be chromosomes on one hand, or genes on the other, we can decide on how to chop them up. + // Note that this somehow relates to 'genomeChunkLength', but not entirely. The sweet spot is bp length is ~ 1000000 + let mut bplen: u32 = 0; + let mut blocks: Vec> = Vec::new(); + let mut tempregionvec: Vec = Vec::new(); + + for reg in regs.iter() { + if reg.regionlength > 1000000 { + if tempregionvec.len() > 0 { + blocks.push(tempregionvec.clone()); + tempregionvec = Vec::new(); + bplen = 0 } - _ => (), + blocks.push(vec![reg.clone()]); + } else { + tempregionvec.push(reg.clone()); + bplen += reg.regionlength; + } + if bplen > 1000000 { + blocks.push(tempregionvec.clone()); + tempregionvec = Vec::new(); + bplen = 0; } } - return blocks; + if tempregionvec.len() > 0 { + blocks.push(tempregionvec.clone()); + } + blocks } -pub struct Alignmentfilters { - pub minmappingquality: u8, - pub samflaginclude: u16, - pub samflagexclude: u16, - pub minfraglen: u32, - pub maxfraglen: u32, -} \ No newline at end of file + +#[derive(Debug)] +pub struct Scalingregions { + pub upstream: u32, + pub downstream: u32, + pub unscaled5prime: u32, + pub unscaled3prime: u32, + pub regionbodylength: u32, + pub binsize: u32, + pub cols_expected: usize, + pub bpsum: u32, + pub missingdata_as_zero: bool, + pub scale: f32, + pub nan_after_end: bool, + pub skipzero: bool, + pub minthresh: f32, + pub maxthresh: f32, + pub referencepoint: String, + pub mode: String, + pub bwfiles: usize, + pub avgtype: String, + pub verbose: bool, + pub proc_number: usize, + pub regionlabels: Vec, + pub bwlabels: Vec +} + +#[derive(Clone)] +pub struct Gtfparse { + pub metagene: bool, + pub txnid: String, + pub exonid: String, + pub txniddesignator: String, +} + +#[derive(Clone)] +pub enum Revalue { + U(u32), + V(Vec), +} + +impl Revalue { + pub fn rewrites(&self) -> String { + match self { + Revalue::U(v) => format!("{}", v), + Revalue::V(vs) => vs.iter() + .map(|v| v.to_string()) + .collect::>() + .join(","), + } + } +} + +impl fmt::Debug for Revalue { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + Revalue::U(value) => write!(f, "U({})", value), + Revalue::V(values) => write!(f, "V({:?})", values), + } + } +} + +impl fmt::Display for Revalue { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + Revalue::U(value) => write!(f, "U({})", value), + Revalue::V(values) => write!(f, "V({})", values.iter().map(|v| v.to_string()).collect::>().join(", ")), + } + } +} + +#[derive(Clone, Debug)] +pub enum Bin { + Conbin(u32, u32), + Catbin(Vec<(u32, u32)>), +} + +impl Bin { + pub fn get_start(&self) -> u32 { + match self { + Bin::Conbin(start, _) => *start, + Bin::Catbin(starts) => starts.first().unwrap().0, + } + } + pub fn get_end(&self) -> u32 { + match self { + Bin::Conbin(_, end) => *end, + Bin::Catbin(ends) => ends.last().unwrap().1, + } + } +} + +pub struct TempZip +where I: Iterator { + pub iterators: Vec +} + +impl Iterator for TempZip +where I: Iterator { + type Item = Vec; + fn next(&mut self) -> Option { + let o: Option> = self.iterators.iter_mut().map(|x| x.next()).collect(); + o + } +} diff --git a/src/filehandler.rs b/src/filehandler.rs index 0a900bb90e..b9018a3c3a 100644 --- a/src/filehandler.rs +++ b/src/filehandler.rs @@ -1,4 +1,4 @@ -use rust_htslib::bam::{Read, Reader}; +use rust_htslib::bam::{Read, Reader, IndexedReader}; use itertools::Itertools; use std::io::{BufReader, BufWriter, Write}; use std::io::prelude::*; @@ -9,7 +9,7 @@ use bigtools::beddata::BedParserStreamingIterator; use std::collections::HashMap; use flate2::write::GzEncoder; use flate2::Compression; -use crate::computematrix::{Scalingregions, Gtfparse, Revalue, Region, Bin}; +use crate::covcalc::{Scalingregions, Gtfparse, Revalue, Region, Bin}; use crate::calc::{mean_float, median_float, min_float, max_float, sum_float, std_float}; pub fn bam_ispaired(bam_ifile: &str) -> bool { @@ -47,6 +47,25 @@ where } } +pub fn is_bed_or_gtf(fp: &str) -> String { + // Check if file is a bed or gtf file. + let file = File::open(fp).expect(format!("Failed to open file: {}", fp).as_str()); + let reader = BufReader::new(file); + // Get the first line that doesn't start with # + for line in reader.lines() { + let line = line.unwrap(); + if !line.starts_with('#') { + let fields: Vec<&str> = line.split('\t').collect(); + if fields.len() == 9 { + return "gtf".to_string(); + } else { + return "bed".to_string(); + } + } + } + "Unknown".to_string() +} + pub fn read_gtffile(gtf_file: &String, gtfparse: &Gtfparse, chroms: Vec<&String>) -> (Vec, (String, u32)) { // At some point this zoo of String clones should be refactored. Not now though, We have a deadline. let mut regions: Vec = Vec::new(); @@ -107,8 +126,8 @@ pub fn read_gtffile(gtf_file: &String, gtfparse: &Gtfparse, chroms: Vec<&String> let (starts, ends): (Vec, Vec) = txnentry.iter().map(|(s, e)| (*s, *e)).unzip(); let chrom = txn_chrom.get(&txnid).unwrap().to_string(); - if !chroms.contains(&&chrom) { - println!("Warning, region {} not found in at least one of the bigwig files. Skipping {}.", chrom, txnid); + if !chroms.contains(&&chrom.to_string()) { + println!("Warning, region {} not found in at least one of the bigwig/bam files. Skipping {}.", chrom, txnid); } else { regions.push( Region { @@ -151,9 +170,8 @@ pub fn read_gtffile(gtf_file: &String, gtfparse: &Gtfparse, chroms: Vec<&String> } else { names.insert(entryname.clone(), 0); } - if !chroms.contains(&&fields[0].to_string()) { - println!("Warning, region {} not found in at least one of the bigwig files. Skipping {}.", fields[0], entryname); + println!("Warning, region {} not found in at least one of the bigwig/bam files. Skipping {}.", fields[0], entryname); } else { regions.push( Region { @@ -203,8 +221,10 @@ pub fn read_bedfile(bed_file: &String, metagene: bool, chroms: Vec<&String>) -> } let chrom = fields[0]; let mut entryname = format!("{}:{}-{}", fields[0], fields[1], fields[2]); + // Only check for valid chroms, if chroms vec is not empty. + if !chroms.contains(&&chrom.to_string()) { - println!("Warning, region {} not found in at least one of the bigwig files. Skipping {}.", chrom, entryname); + println!("Warning, region {} not found in at least one of the bigwig/bam files. Skipping {}.", chrom, entryname); continue; } if names.contains_key(&entryname) { @@ -236,7 +256,7 @@ pub fn read_bedfile(bed_file: &String, metagene: bool, chroms: Vec<&String>) -> let chrom = fields[0]; let mut entryname = fields[3].to_string(); if !chroms.contains(&&chrom.to_string()) { - println!("Warning, region {} not found in at least one of the bigwig files. Skipping {}.", chrom, entryname); + println!("Warning, region {} not found in at least one of the bigwig/bam files. Skipping {}.", chrom, entryname); continue; } let start = fields[1].parse().unwrap(); @@ -265,7 +285,7 @@ pub fn read_bedfile(bed_file: &String, metagene: bool, chroms: Vec<&String>) -> let chrom = fields[0]; let mut entryname = fields[3].to_string(); if !chroms.contains(&&chrom.to_string()) { - println!("Warning, region {} not found in at least one of the bigwig files. Skipping {}.", chrom, entryname); + println!("Warning, region {} not found in at least one of the bigwig/bam files. Skipping {}.", chrom, entryname); continue; } if names.contains_key(&entryname) { @@ -351,6 +371,45 @@ pub fn chrombounds_from_bw(bwfile: &str) -> HashMap { chromsizes } +pub fn chrombounds_from_bam(bamfiles: Vec<&str>) -> HashMap { + let mut found_chroms: HashMap = HashMap::new(); + for bam in bamfiles.iter() { + let bam = IndexedReader::from_path(bam).unwrap(); + let chroms: Vec = bam.header().target_names().iter().map(|x| String::from_utf8(x.to_vec()).unwrap()).collect(); + for chrom in chroms.iter() { + // if it's not in the hashmap, add it, else increment count + if !found_chroms.contains_key(chrom) { + found_chroms.insert(chrom.clone(), 1); + } else { + let count = found_chroms.get_mut(chrom).unwrap(); + *count += 1; + } + } + } + let mut validchroms: Vec = Vec::new(); + // loop over all chroms in the hashmap, if the count is expected, include them + for (chrom, count) in found_chroms.iter() { + if *count == bamfiles.len() { + validchroms.push(chrom.clone()); + } else { + println!("Chromosome {} is missing in at least one bam file, and thus ignored!", chrom); + } + } + let bam = IndexedReader::from_path(bamfiles[0]).unwrap(); + let header = bam.header().clone(); + let mut chromsizes = HashMap::new(); + for tid in 0..header.target_count() { + let chromname = String::from_utf8(header.tid2name(tid).to_vec()) + .expect("Invalid UTF-8 in chromosome name"); + let chromlen = header.target_len(tid) + .expect("Error retrieving length for chromosome"); + if validchroms.contains(&chromname) { + chromsizes.insert(chromname, chromlen as u32); + } + } + chromsizes +} + pub fn bwintervals( bwfile: &str, regions: &Vec, diff --git a/src/multibamsummary.rs b/src/multibamsummary.rs index 6458656d46..03efa5c01e 100644 --- a/src/multibamsummary.rs +++ b/src/multibamsummary.rs @@ -4,16 +4,21 @@ use rayon::prelude::*; use rayon::ThreadPoolBuilder; use itertools::{multizip, multiunzip, izip}; use std::io::prelude::*; -use std::io::BufReader; +use std::io::{BufReader, BufWriter}; use std::fs::File; -use ndarray::Array2; -use ndarray::Array1; +use ndarray::{Array1, Array2, stack, Axis}; use std::io; -use crate::covcalc::{bam_pileup, parse_regions, Alignmentfilters}; -use crate::filehandler::{bam_ispaired}; -use crate::calc::{median, calc_ratio}; +use ndarray_npy::NpzWriter; +use std::borrow::Cow; +use std::collections::HashMap; +use std::path::Path; +use std::sync::{Arc, Mutex}; +use crate::covcalc::{bam_pileup, parse_regions, Alignmentfilters, TempZip, region_divider}; +use crate::filehandler::{bam_ispaired, read_bedfile, read_gtffile, chrombounds_from_bam, is_bed_or_gtf}; +use crate::calc::{median, calc_ratio, deseq_scalefactors}; use crate::bamcompare::ParsedBamFile; use crate::normalization::scale_factor_bamcompare; +use crate::covcalc::{Region, Gtfparse}; #[pyfunction] pub fn r_mbams( @@ -26,13 +31,13 @@ pub fn r_mbams( scaling_factors: &str, // optional parameters labels: Py, - binsize: u32, - distance_between_bins: u32, + mut binsize: u32, + mut distance_between_bins: u32, nproc: usize, - _bed_file: &str, - regions: Vec<(String, u32, u32)>, + bed_file: Py, + sup_regions: Vec<(String, u32, u32)>, _blacklist: &str, - _verbose: bool, + verbose: bool, _extend_reads: u32, _center_reads: bool, sam_flag_incl: u16, // sam flag include @@ -40,17 +45,24 @@ pub fn r_mbams( min_fragment_length: u32, // minimum fragment length. max_fragment_length: u32, // maximum fragment length. min_mapping_quality: u8, // minimum mapping quality. - _keep_exons: bool, - _txnid: &str, // transcript id to use when parsing GTF file - _exonid: &str, // exon id to use when parsing GTF file - _txniddesignator: &str, // designator to use when parsing GTF file + metagene: bool, // metagene mode or not. + txnid: &str, // transcript id to use when parsing GTF file. + exonid: &str, // exon id to use when parsing GTF file. + txniddesignator: &str, // designator to use when parsing GTF file. ) -> PyResult<()> { let mut bamfiles: Vec = Vec::new(); let mut bamlabels: Vec = Vec::new(); + let mut bedfiles: Vec = Vec::new(); let mut ignorechr: Vec = Vec::new(); Python::with_gil(|py| { bamfiles = bam_files.extract(py).expect("Failed to retrieve bam files."); bamlabels = labels.extract(py).expect("Failed to retrieve labels."); + bedfiles = bed_file.extract(py).expect("Failed to retrieve bedfiles."); + }); + + let max_len = bamlabels.iter().map(|s| s.len()).max().unwrap_or(0); + let bamlabels_arr: Array2 = Array2::from_shape_fn((bamlabels.len(), max_len), |(i, j)| { + bamlabels[i].as_bytes().get(j).copied().unwrap_or(0) }); // Get paired-end information @@ -59,10 +71,12 @@ pub fn r_mbams( .collect::>(); // zip through ispe and bamfiles - for (_ispe, _bf) in ispe.iter().zip(bamfiles.iter()) { - println!("Sample: {} is-paired: {}", _bf, _ispe); + if verbose { + for (_ispe, _bf) in ispe.iter().zip(bamfiles.iter()) { + println!("Sample: {} is-paired: {}", _bf, _ispe); + } } - + let filters: Alignmentfilters = Alignmentfilters { minmappingquality: min_mapping_quality, samflaginclude: sam_flag_incl, @@ -71,18 +85,69 @@ pub fn r_mbams( maxfraglen: max_fragment_length }; - let (regions, chromsizes) = parse_regions(®ions, bamfiles.get(0).unwrap()); - let pool = ThreadPoolBuilder::new().num_threads(nproc).build().unwrap(); + let mut regions: Vec = Vec::new(); + let mut gene_mode = false; + if mode == "BED-file" { + if verbose { + println!("BED file mode. with files: {:?}", bedfiles); + } + let gtfparse = Gtfparse { + metagene: metagene, + txnid: txnid.to_string(), + exonid: exonid.to_string(), + txniddesignator: txniddesignator.to_string(), + }; + // From the first bamfile, get the chromosome sizes. Only the chromosome names are needed, to make sure no invalid regions are included later on. + let chromsizes = chrombounds_from_bam(bamfiles.iter().map(|x| x.as_str()).collect()); + + binsize = 1; + distance_between_bins = 0; + + // Parse regions from bed files. Note that we retain the name of the bed file (in case there are more then 1) + // Additionaly, score and strand are also retained, if it's a 3-column bed file we just fill in '.' + let mut regionsizes: HashMap = HashMap::new(); + bedfiles.iter() + .map(|r| { + let ftype = is_bed_or_gtf(r); + + match ftype.as_str() { + "gtf" => read_gtffile(r, >fparse, chromsizes.keys().collect()), + "bed" => read_bedfile(r, metagene, chromsizes.keys().collect()), + _ => panic!("Only .bed and .gtf files are allowed (as determined by the number of columns). File = {}", ftype), + } + }) + .for_each(|(reg, regsize)| { + regions.extend(reg); + regionsizes.insert(regsize.0, regsize.1); + }); + gene_mode = true; + } else { + if verbose { + println!("BINS mode. with binsize: {}, distance between bins: {}", binsize, distance_between_bins); + } + let (parsedregions, chromsizes) = parse_regions(&sup_regions, bamfiles.iter().map(|x| x.as_str()).collect()); + regions = parsedregions; + } + let pool = ThreadPoolBuilder::new().num_threads(nproc).build().unwrap(); // Zip together bamfiles and ispe into a vec of tuples. let bampfiles: Vec<_> = bamfiles.into_iter().zip(ispe.into_iter()).collect(); + // Divide up the regions into regionBlocks + let regionblocks = region_divider(®ions); + + assert!(regionblocks.len() > 0, "No regions to process. Exiting."); + if verbose { + println!("Regions divided into {} parallel blocks", regionblocks.len()); + println!("Start coverage calculation"); + } + let covcalcs: Vec<_> = pool.install(|| { bampfiles.par_iter() .map(|(bamfile, ispe)| { - let (bg, mapped, unmapped, readlen, fraglen) = regions.par_iter() - .map(|i| bam_pileup(bamfile, &i, &binsize, &ispe, &ignorechr, &filters, false)) + let (bg, _mapped, _unmapped, _readlen, _fraglen) = regionblocks.par_iter() + .map(|i| bam_pileup(bamfile, &i, &binsize, &ispe, &ignorechr, &filters, false, gene_mode)) .reduce( || (vec![], 0, 0, vec![], vec![]), |(mut _bg, mut _mapped, mut _unmapped, mut _readlen, mut _fraglen), (bg, mapped, unmapped, readlen, fraglen)| { @@ -98,82 +163,109 @@ pub fn r_mbams( }) .collect() }); - + if verbose { + println!("Coverage calculation done"); + println!("Define output file"); + } - // Scale factors (when needed) - // relevant python code. - // loggeomeans = np.sum(np.log(m), axis=1) / m.shape[1] - // # Mask after computing the geometric mean - // m = np.ma.masked_where(m <= 0, m) - // loggeomeans = np.ma.masked_where(np.isinf(loggeomeans), loggeomeans) - // # DESeq2 ratio-based size factor - // sf = np.exp(np.ma.median((np.log(m).T - loggeomeans).T, axis=0)) - // return 1. / sf - // create output file to write to - - // create output file to write lines into - let mut file = File::create(out_raw_counts).unwrap(); - - let its: Vec<_> = covcalcs.iter().map(|x| x.iter()).collect(); + // Collate the coverage files into a matrix. + let its: Vec<_> = covcalcs.iter().map(|x| x.into_iter()).collect(); let zips = TempZip { iterators: its }; - for c in zips { - // set up Readers - let readers: Vec<_> = c.iter().map(|x| BufReader::new(File::open(x).unwrap()).lines()).collect(); - - for mut _l in (TempZip { iterators: readers }) { - // unwrap all lines in _l - let lines: Vec<_> = _l - .iter_mut() - .map(|x| x.as_mut().unwrap()) - .map(|x| x.split('\t').collect()) - .map(|x: Vec<&str> | ( x[0].to_string(), x[1].parse::().unwrap(), x[2].parse::().unwrap(), x[3].parse::().unwrap() ) ) - .collect(); - // collect all fields 3 together - let mut line: Vec = Vec::new(); - line.push(Countline::Text(lines[0].0.clone())); - line.push(Countline::Int(lines[0].1)); - line.push(Countline::Int(lines[0].2)); - for _line in lines { - line.push(Countline::Float(_line.3)); - } - println!("{:?}", line); - let fline = line.iter().map(|x| x.to_string()).collect::>().join("\t"); - writeln!(file, "{}", fline).unwrap(); - } + if verbose { + println!("Start iterating through temp coverage files and create output npy."); } + let zips_vec: Vec<_> = zips.collect(); + println!(" Length of ziperators = {}", zips_vec.len()); + let mut matvec: Vec> = Vec::new(); + let matvec: Vec<_> = pool.install(|| { + let _m: Vec<_> = zips_vec + .par_iter() + .flat_map(|c| { + let readers: Vec<_> = c.par_iter().map(|x| BufReader::new(File::open(x).unwrap()).lines()).collect(); + let mut _matvec: Vec> = Vec::new(); + let mut _regions: Vec<(String, String, String)> = Vec::new(); + for mut _l in (TempZip { iterators: readers }) { + // unwrap all lines in _l + let lines: Vec<_> = _l + .par_iter_mut() + .map(|x| x.as_mut().unwrap()) + .map(|x| x.split('\t').collect()) + .map(|x: Vec<&str> | ( x[0].to_string(), x[1].to_string(), x[2].to_string(), x[3].parse::().unwrap() ) ) + .collect(); + let counts = lines.par_iter().map(|x| x.3).collect::>(); + let regions: (String, String, String) = (lines[0].0.clone(), lines[0].1.clone(), lines[0].2.clone()); + _matvec.push(counts); + _regions.push(regions); + } + (_matvec, _regions) + }) + .collect(); + _m + }); + // Seperate the matrices and regions + let (matvec, regions): (Vec<_>, Vec<_>) = multiunzip(matvec); - Ok(()) -} - -#[derive(Debug)] -enum Countline { - Int(u32), - Float(f32), - Text(String), -} + // Write out the count files, if appropriate -impl Countline { - fn to_string(&self) -> String { - match self { - Countline::Int(i) => i.to_string(), - Countline::Float(f) => f.to_string(), - Countline::Text(t) => t.clone(), + if out_raw_counts != "None" { + if verbose { + println!("Writing raw counts to disk."); + } + let mut cfile = BufWriter::new(File::create(out_raw_counts).unwrap()); + // Write the header to the file. + let mut headstr = String::new(); + headstr.push_str("#\'chr\'\t\'start\'\t\'end\'"); + for label in bamlabels.iter() { + headstr.push_str(&format!("\t\'{}\'", label)); + } + writeln!(cfile, "{}", headstr).unwrap(); + let outlines: Vec = pool.install(|| { + regions.par_iter().zip(matvec.par_iter()) + .map(|(region, counts)| { + let mut outstr = String::new(); + outstr.push_str(&format!("{}\t{}\t{}", region.0, region.1, region.2)); + for count in counts.iter() { + outstr.push_str(&format!("\t{}", count)); + } + outstr + }) + .collect() + }); + for line in outlines { + writeln!(cfile, "{}", line).unwrap(); } } -} -struct TempZip -where I: Iterator { - iterators: Vec -} + // Create 2darray from matvec + let matarr: Array2 = Array2::from_shape_vec( + (matvec.len(), matvec[0].len()), matvec.into_iter().flatten().collect() + ).unwrap(); + + // If scalefactors are required, calc and save them now. + if scaling_factors != "None" { + if verbose { + println!("Calculating scale factors."); + } + let sf = deseq_scalefactors(&matarr); + // save scalefactors to file + let mut sf_file = File::create(scaling_factors).unwrap(); + writeln!(sf_file, "Sample\tscalingFactor").unwrap(); + for (sf, label) in sf.iter().zip(bamlabels.iter()) { + writeln!(sf_file, "{}\t{}", label, sf).unwrap(); + } + } -impl Iterator for TempZip -where I: Iterator { - type Item = Vec; - fn next(&mut self) -> Option { - let o: Option> = self.iterators.iter_mut().map(|x| x.next()).collect(); - o + if verbose { + println!("Writing matrix to disk."); + } + let mut npz = NpzWriter::new_compressed(File::create(ofile).unwrap()); + npz.add_array("matrix", &matarr).unwrap(); + npz.add_array("labels", &bamlabels_arr).unwrap(); + npz.finish().unwrap(); + if verbose { + println!("Matrix written."); } + Ok(()) } \ No newline at end of file