From c026791c31c98ce6324053cd6ddfc885f2481691 Mon Sep 17 00:00:00 2001 From: Jordi Abante Date: Mon, 19 Aug 2019 16:00:35 -0400 Subject: [PATCH] EM improvements --- LICENSE.md | 7 + Manifest.toml | 535 +++++++ Project.toml | 29 + README.md | 64 + src/JuliASM.jl | 68 + src/juliASM_bioinformatics.jl | 1391 +++++++++++++++++ src/juliASM_estimation.jl | 746 +++++++++ src/juliASM_output.jl | 683 ++++++++ src/juliASM_plots.jl | 71 + src/juliASM_simulations.jl | 285 ++++ test/bam/example.a1.bam | Bin 0 -> 28956 bytes test/bam/example.a2.bam | Bin 0 -> 30345 bytes test/bam/example_a1_R1_bismark_bt2_pe.bam | Bin 0 -> 29291 bytes test/bam/example_a2_R1_bismark_bt2_pe.bam | Bin 0 -> 31444 bytes .../example_a1_R1_bismark_bt2_PE_report.txt | 42 + .../example_a2_R1_bismark_bt2_PE_report.txt | 42 + .../CT_conversion/BS_CT.1.bt2 | Bin 0 -> 4816612 bytes .../CT_conversion/BS_CT.2.bt2 | Bin 0 -> 120 bytes .../CT_conversion/BS_CT.3.bt2 | Bin 0 -> 98 bytes .../CT_conversion/BS_CT.4.bt2 | Bin 0 -> 220 bytes .../CT_conversion/BS_CT.rev.1.bt2 | Bin 0 -> 4715658 bytes .../CT_conversion/BS_CT.rev.2.bt2 | Bin 0 -> 122 bytes .../CT_conversion/genome_mfa.CT_conversion.fa | 4 + .../GA_conversion/BS_GA.1.bt2 | Bin 0 -> 4741435 bytes .../GA_conversion/BS_GA.2.bt2 | Bin 0 -> 128 bytes .../GA_conversion/BS_GA.3.bt2 | Bin 0 -> 98 bytes .../GA_conversion/BS_GA.4.bt2 | Bin 0 -> 138 bytes .../GA_conversion/BS_GA.rev.1.bt2 | Bin 0 -> 4704687 bytes .../GA_conversion/BS_GA.rev.2.bt2 | Bin 0 -> 128 bytes .../GA_conversion/genome_mfa.GA_conversion.fa | 4 + test/fasta/allele-specific/example.g1.fa | 4 + test/fasta/allele-specific/example.g2.fa | 4 + test/fasta/example.1.bt2 | Bin 0 -> 4921272 bytes test/fasta/example.2.bt2 | Bin 0 -> 126 bytes test/fasta/example.3.bt2 | Bin 0 -> 98 bytes test/fasta/example.4.bt2 | Bin 0 -> 173 bytes test/fasta/example.fa | 4 + test/fasta/example.fa.fai | 2 + test/fasta/example.rev.1.bt2 | Bin 0 -> 4995089 bytes test/fasta/example.rev.2.bt2 | Bin 0 -> 124 bytes test/runtests.jl | 52 + test/vcf/example.vcf | 12 + 42 files changed, 4049 insertions(+) create mode 100644 LICENSE.md create mode 100644 Manifest.toml create mode 100644 Project.toml create mode 100644 README.md create mode 100644 src/JuliASM.jl create mode 100644 src/juliASM_bioinformatics.jl create mode 100644 src/juliASM_estimation.jl create mode 100644 src/juliASM_output.jl create mode 100644 src/juliASM_plots.jl create mode 100644 src/juliASM_simulations.jl create mode 100644 test/bam/example.a1.bam create mode 100644 test/bam/example.a2.bam create mode 100644 test/bam/example_a1_R1_bismark_bt2_pe.bam create mode 100644 test/bam/example_a2_R1_bismark_bt2_pe.bam create mode 100644 test/bismark/example_a1_R1_bismark_bt2_PE_report.txt create mode 100644 test/bismark/example_a2_R1_bismark_bt2_PE_report.txt create mode 100644 test/fasta/Bisulfite_Genome/CT_conversion/BS_CT.1.bt2 create mode 100644 test/fasta/Bisulfite_Genome/CT_conversion/BS_CT.2.bt2 create mode 100644 test/fasta/Bisulfite_Genome/CT_conversion/BS_CT.3.bt2 create mode 100644 test/fasta/Bisulfite_Genome/CT_conversion/BS_CT.4.bt2 create mode 100644 test/fasta/Bisulfite_Genome/CT_conversion/BS_CT.rev.1.bt2 create mode 100644 test/fasta/Bisulfite_Genome/CT_conversion/BS_CT.rev.2.bt2 create mode 100644 test/fasta/Bisulfite_Genome/CT_conversion/genome_mfa.CT_conversion.fa create mode 100644 test/fasta/Bisulfite_Genome/GA_conversion/BS_GA.1.bt2 create mode 100644 test/fasta/Bisulfite_Genome/GA_conversion/BS_GA.2.bt2 create mode 100644 test/fasta/Bisulfite_Genome/GA_conversion/BS_GA.3.bt2 create mode 100644 test/fasta/Bisulfite_Genome/GA_conversion/BS_GA.4.bt2 create mode 100644 test/fasta/Bisulfite_Genome/GA_conversion/BS_GA.rev.1.bt2 create mode 100644 test/fasta/Bisulfite_Genome/GA_conversion/BS_GA.rev.2.bt2 create mode 100644 test/fasta/Bisulfite_Genome/GA_conversion/genome_mfa.GA_conversion.fa create mode 100644 test/fasta/allele-specific/example.g1.fa create mode 100644 test/fasta/allele-specific/example.g2.fa create mode 100644 test/fasta/example.1.bt2 create mode 100644 test/fasta/example.2.bt2 create mode 100644 test/fasta/example.3.bt2 create mode 100644 test/fasta/example.4.bt2 create mode 100644 test/fasta/example.fa create mode 100644 test/fasta/example.fa.fai create mode 100644 test/fasta/example.rev.1.bt2 create mode 100644 test/fasta/example.rev.2.bt2 create mode 100644 test/runtests.jl create mode 100644 test/vcf/example.vcf diff --git a/LICENSE.md b/LICENSE.md new file mode 100644 index 0000000..fc13f84 --- /dev/null +++ b/LICENSE.md @@ -0,0 +1,7 @@ +Copyright 2019 JORDI ABANTE + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/Manifest.toml b/Manifest.toml new file mode 100644 index 0000000..667b263 --- /dev/null +++ b/Manifest.toml @@ -0,0 +1,535 @@ +[[Arpack]] +deps = ["BinaryProvider", "Libdl", "LinearAlgebra"] +git-tree-sha1 = "07a2c077bdd4b6d23a40342a8a108e2ee5e58ab6" +uuid = "7d9fca2a-8960-54d3-9f78-7d1dccf2cb97" +version = "0.3.1" + +[[ArrayInterface]] +deps = ["LinearAlgebra", "Requires", "SparseArrays"] +git-tree-sha1 = "981354dab938901c2b607a213e62d9defa50b698" +uuid = "4fba245c-0d91-5ea0-9b3e-6abc04ee57a9" +version = "1.2.1" + +[[Automa]] +deps = ["DataStructures", "Printf", "Random", "Test", "TranscodingStreams"] +git-tree-sha1 = "c81526bf5f6fb4616b4e22a3cd62ac20e255fd3c" +uuid = "67c07d97-cdcb-5c2c-af73-a7f9c32a568b" +version = "0.8.0" + +[[BGZFStreams]] +deps = ["CodecZlib", "Test"] +git-tree-sha1 = "b0e322aef9f1895a09a0c48a118111fd509f666a" +uuid = "28d598bf-9b8f-59f1-b38c-5a06b4a0f5e6" +version = "0.3.0" + +[[Base64]] +uuid = "2a0f44e3-6c83-55bd-87e4-b1978d98bd5f" + +[[BinDeps]] +deps = ["Compat", "Libdl", "SHA", "URIParser"] +git-tree-sha1 = "12093ca6cdd0ee547c39b1870e0c9c3f154d9ca9" +uuid = "9e28174c-4ba2-5203-b857-d8d62c4213ee" +version = "0.8.10" + +[[BinaryProvider]] +deps = ["Libdl", "Logging", "SHA"] +git-tree-sha1 = "c7361ce8a2129f20b0e05a89f7070820cfed6648" +uuid = "b99e7846-7c00-51b0-8f62-c81ae34c0232" +version = "0.5.6" + +[[BioAlignments]] +deps = ["Automa", "BGZFStreams", "BioCore", "BioSequences", "BioSymbols", "BufferedStreams", "GenomicFeatures", "IntervalTrees", "LinearAlgebra", "Printf", "Test"] +git-tree-sha1 = "b6f2fc06b7c20d7c0538ddb99bd593cd8b4bd6dc" +uuid = "00701ae9-d1dc-5365-b64a-a3a3ebf5695e" +version = "1.0.0" + +[[BioCore]] +deps = ["Automa", "BufferedStreams", "YAML"] +git-tree-sha1 = "476edbf4ef94594fff430a84ca96f86cb2327a71" +uuid = "37cfa864-2cd6-5c12-ad9e-b6597d696c81" +version = "2.0.5" + +[[BioSequences]] +deps = ["Automa", "BioCore", "BioSymbols", "BufferedStreams", "Combinatorics", "IndexableBitVectors", "IntervalTrees", "LinearAlgebra", "Printf", "Random", "Test", "Twiddle"] +git-tree-sha1 = "29341326bfab7ebef261dab128874b9e3fece5c2" +uuid = "7e6ae17a-c86d-528c-b3b9-7f778a29fe59" +version = "1.1.0" + +[[BioSymbols]] +deps = ["Automa", "Test"] +git-tree-sha1 = "36bd8fc32e02b60dba123d5eecc7b4a90ef7d265" +uuid = "3c28c6f8-a34d-59c4-9654-267d177fcfa9" +version = "3.1.0" + +[[BufferedStreams]] +deps = ["Compat", "Test"] +git-tree-sha1 = "5d55b9486590fdda5905c275bb21ce1f0754020f" +uuid = "e1450e63-4bb3-523b-b2a4-4ffa8c0fd77d" +version = "1.0.0" + +[[Calculus]] +deps = ["Compat"] +git-tree-sha1 = "bd8bbd105ba583a42385bd6dc4a20dad8ab3dc11" +uuid = "49dc2e85-a5d0-5ad3-a950-438e2897f1b9" +version = "0.5.0" + +[[CodecZlib]] +deps = ["BinaryProvider", "Libdl", "TranscodingStreams"] +git-tree-sha1 = "05916673a2627dd91b4969ff8ba6941bc85a960e" +uuid = "944b1d66-785c-5afd-91f1-9de20f533193" +version = "0.6.0" + +[[Codecs]] +deps = ["Test"] +git-tree-sha1 = "70885e5e038cba1c4c17a84ad6c40756e10a4fb5" +uuid = "19ecbf4d-ef7c-5e4b-b54a-0a0ff23c5aed" +version = "0.5.0" + +[[ColorTypes]] +deps = ["FixedPointNumbers", "Random"] +git-tree-sha1 = "10050a24b09e8e41b951e9976b109871ce98d965" +uuid = "3da002f7-5984-5a60-b8a6-cbb66c0b333f" +version = "0.8.0" + +[[Colors]] +deps = ["ColorTypes", "FixedPointNumbers", "InteractiveUtils", "Printf", "Reexport", "Test"] +git-tree-sha1 = "9f0a0210450acb91c730b730a994f8eef1d3d543" +uuid = "5ae59095-9a9b-59fe-a467-6f913c188581" +version = "0.9.5" + +[[Combinatorics]] +deps = ["LinearAlgebra", "Polynomials", "Test"] +git-tree-sha1 = "50b3ae4d643dc27eaff69fb6be06ee094d5500c9" +uuid = "861a8166-3701-5b0c-9a16-15d98fcdc6aa" +version = "0.7.0" + +[[CommonSubexpressions]] +deps = ["Test"] +git-tree-sha1 = "efdaf19ab11c7889334ca247ff4c9f7c322817b0" +uuid = "bbf7d656-a473-5ed7-a52c-81e309532950" +version = "0.2.0" + +[[Compat]] +deps = ["Base64", "Dates", "DelimitedFiles", "Distributed", "InteractiveUtils", "LibGit2", "Libdl", "LinearAlgebra", "Markdown", "Mmap", "Pkg", "Printf", "REPL", "Random", "Serialization", "SharedArrays", "Sockets", "SparseArrays", "Statistics", "Test", "UUIDs", "Unicode"] +git-tree-sha1 = "84aa74986c5b9b898b0d1acaf3258741ee64754f" +uuid = "34da2185-b29b-5c13-b0c7-acf172513d20" +version = "2.1.0" + +[[Contour]] +deps = ["LinearAlgebra", "StaticArrays", "Test"] +git-tree-sha1 = "b974e164358fea753ef853ce7bad97afec15bb80" +uuid = "d38c429a-6771-53c6-b99e-75d170b6e991" +version = "0.5.1" + +[[DataAPI]] +git-tree-sha1 = "8903f0219d3472543fc4b2f5ebaf675a07f817c0" +uuid = "9a962f9c-6df0-11e9-0e5d-c546b8b5ee8a" +version = "1.0.1" + +[[DataStructures]] +deps = ["InteractiveUtils", "OrderedCollections"] +git-tree-sha1 = "0809951a1774dc724da22d26e4289bbaab77809a" +uuid = "864edb3b-99cc-5e75-8d2d-829cb0a9cfe8" +version = "0.17.0" + +[[Dates]] +deps = ["Printf"] +uuid = "ade2ca70-3891-5945-98fb-dc099432e06a" + +[[DelimitedFiles]] +deps = ["Mmap"] +uuid = "8bb1440f-4735-579b-a4ab-409b98df4dab" + +[[DiffEqDiffTools]] +deps = ["ArrayInterface", "LinearAlgebra", "SparseArrays", "StaticArrays"] +git-tree-sha1 = "d6582a0e9e26a6453a4c03f2837b1049f7007a3f" +uuid = "01453d9d-ee7c-5054-8395-0335cb756afa" +version = "1.2.0" + +[[DiffResults]] +deps = ["Compat", "StaticArrays"] +git-tree-sha1 = "34a4a1e8be7bc99bc9c611b895b5baf37a80584c" +uuid = "163ba53b-c6d8-5494-b064-1a9d43ac40c5" +version = "0.0.4" + +[[DiffRules]] +deps = ["Random", "Test"] +git-tree-sha1 = "dc0869fb2f5b23466b32ea799bd82c76480167f7" +uuid = "b552c78f-8df3-52c6-915a-8e097449b14b" +version = "0.0.10" + +[[Distances]] +deps = ["LinearAlgebra", "Printf", "Random", "Statistics", "Test"] +git-tree-sha1 = "a135c7c062023051953141da8437ed74f89d767a" +uuid = "b4f34e82-e78d-54a5-968a-f98e89d6e8f7" +version = "0.8.0" + +[[Distributed]] +deps = ["LinearAlgebra", "Random", "Serialization", "Sockets"] +uuid = "8ba89e20-285c-5b6f-9357-94700520ee1b" + +[[Distributions]] +deps = ["LinearAlgebra", "PDMats", "Printf", "QuadGK", "Random", "SpecialFunctions", "Statistics", "StatsBase", "StatsFuns"] +git-tree-sha1 = "baaf9e165ba8a2d11fb4fb3511782ee070ee3694" +uuid = "31c24e10-a181-5473-b8eb-7969acd0382f" +version = "0.21.1" + +[[FFMPEG]] +deps = ["BinaryProvider", "Libdl"] +git-tree-sha1 = "1dd2128ff10894081f30931b355dc892d1352de9" +uuid = "c87230d0-a227-11e9-1b43-d7ebe4e7570a" +version = "0.2.2" + +[[FillArrays]] +deps = ["LinearAlgebra", "Random", "SparseArrays", "Test"] +git-tree-sha1 = "9ab8f76758cbabba8d7f103c51dce7f73fcf8e92" +uuid = "1a297f60-69ca-5386-bcde-b61e274b549b" +version = "0.6.3" + +[[FixedPointNumbers]] +deps = ["Test"] +git-tree-sha1 = "b8045033701c3b10bf2324d7203404be7aef88ba" +uuid = "53c48c17-4a7d-5ca2-90c5-79b7896eea93" +version = "0.5.3" + +[[ForwardDiff]] +deps = ["CommonSubexpressions", "DiffResults", "DiffRules", "InteractiveUtils", "LinearAlgebra", "NaNMath", "Random", "SparseArrays", "SpecialFunctions", "StaticArrays", "Test"] +git-tree-sha1 = "4c4d727f1b7e0092134fabfab6396b8945c1ea5b" +uuid = "f6369f11-7733-5829-9624-2563aa707210" +version = "0.10.3" + +[[GR]] +deps = ["Base64", "DelimitedFiles", "LinearAlgebra", "Pkg", "Printf", "Random", "Serialization", "Sockets", "Test"] +git-tree-sha1 = "b4c31b6377b6d51b6c69a3a9737d10c34d43974e" +uuid = "28b8d3ca-fb5f-59d9-8090-bfdbd6d07a71" +version = "0.41.0" + +[[GeneticVariation]] +deps = ["Automa", "BGZFStreams", "BioCore", "BioSequences", "BufferedStreams", "Combinatorics", "IntervalTrees", "Test", "Twiddle"] +git-tree-sha1 = "b7cc1465200d1c82666754930a55763b507f097e" +uuid = "9bc6ac9d-e6b2-5f70-b0a8-242a01662520" +version = "0.4.0" + +[[GenomicFeatures]] +deps = ["Automa", "BGZFStreams", "BioCore", "BioSequences", "BufferedStreams", "ColorTypes", "DataStructures", "FixedPointNumbers", "IntervalTrees", "Libz", "Random", "Test", "URIParser"] +git-tree-sha1 = "3d6dd4ec649a45a7a7d0096d388e2701af9946f4" +uuid = "899a7d2d-5c61-547b-bef9-6698a8d05446" +version = "1.0.0" + +[[GeometryTypes]] +deps = ["ColorTypes", "FixedPointNumbers", "IterTools", "LinearAlgebra", "StaticArrays"] +git-tree-sha1 = "2b0bfb379a54bdfcd2942f388f7d045f8952373d" +uuid = "4d00f742-c7ba-57c2-abde-4428a4b178cb" +version = "0.7.5" + +[[IndexableBitVectors]] +deps = ["Random", "Test"] +git-tree-sha1 = "b7f5e42dc867b8a8654a5f899064632dac05bc82" +uuid = "1cb3b9ac-1ffd-5777-9e6b-a3d42300664d" +version = "1.0.0" + +[[InteractiveUtils]] +deps = ["LinearAlgebra", "Markdown"] +uuid = "b77e0a4c-d291-57a0-90e8-8db25a27a240" + +[[IntervalTrees]] +deps = ["InteractiveUtils", "Profile", "Random", "Test"] +git-tree-sha1 = "6c9fcd87677231ae293f6806fad928c216ab6658" +uuid = "524e6230-43b7-53ae-be76-1e9e4d08d11b" +version = "1.0.0" + +[[IterTools]] +git-tree-sha1 = "2ebe60d7343962966d1779a74a760f13217a6901" +uuid = "c8e1da08-722c-5040-9ed9-7db0dc04731e" +version = "1.2.0" + +[[JSON]] +deps = ["Dates", "Mmap", "Parsers", "Unicode"] +git-tree-sha1 = "b34d7cef7b337321e97d22242c3c2b91f476748e" +uuid = "682c06a0-de6a-54ab-a142-c8b1cf79cde6" +version = "0.21.0" + +[[LaTeXStrings]] +deps = ["Compat"] +git-tree-sha1 = "7ab9b8788cfab2bdde22adf9004bda7ad9954b6c" +uuid = "b964fa9f-0449-5b57-a5c2-d3ea65f4040f" +version = "1.0.3" + +[[LibGit2]] +uuid = "76f85450-5226-5b5a-8eaa-529ad045b433" + +[[Libdl]] +uuid = "8f399da3-3557-5675-b5ff-fb832c97cbdb" + +[[Libz]] +deps = ["BufferedStreams", "Random", "Test"] +git-tree-sha1 = "d405194ffc0293c3519d4f7251ce51baac9cc871" +uuid = "2ec943e9-cfe8-584d-b93d-64dcb6d567b7" +version = "1.0.0" + +[[LineSearches]] +deps = ["LinearAlgebra", "NLSolversBase", "NaNMath", "Parameters", "Printf", "Test"] +git-tree-sha1 = "54eb90e8dbe745d617c78dee1d6ae95c7f6f5779" +uuid = "d3d80556-e9d4-5f37-9878-2ab0fcc64255" +version = "7.0.1" + +[[LinearAlgebra]] +deps = ["Libdl"] +uuid = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" + +[[Logging]] +uuid = "56ddb016-857b-54e1-b83d-db4d58db5568" + +[[Markdown]] +deps = ["Base64"] +uuid = "d6f4376e-aef5-505a-96c1-9c027394607a" + +[[Measures]] +deps = ["Test"] +git-tree-sha1 = "ddfd6d13e330beacdde2c80de27c1c671945e7d9" +uuid = "442fdcdd-2543-5da2-b0f3-8c86c306513e" +version = "0.3.0" + +[[Missings]] +deps = ["SparseArrays", "Test"] +git-tree-sha1 = "f0719736664b4358aa9ec173077d4285775f8007" +uuid = "e1d29d7a-bbdc-5cf2-9ac0-f12de2c33e28" +version = "0.4.1" + +[[Mmap]] +uuid = "a63ad114-7e13-5084-954f-fe012c677804" + +[[MultipleTesting]] +deps = ["Distributions", "Random", "SpecialFunctions", "StatsBase", "Test"] +git-tree-sha1 = "d6c79f17fbcdf492ca969ab1d3c3c402fd25d323" +uuid = "f8716d33-7c4a-5097-896f-ce0ecbd3ef6b" +version = "0.4.1" + +[[NLSolversBase]] +deps = ["Calculus", "DiffEqDiffTools", "DiffResults", "Distributed", "ForwardDiff"] +git-tree-sha1 = "1c4b1d76f731dee88a0f494c59c750f3fd7d9ddd" +uuid = "d41bc354-129a-5804-8e4c-c37616107c6c" +version = "7.4.0" + +[[NLsolve]] +deps = ["DiffEqDiffTools", "Distances", "ForwardDiff", "LineSearches", "LinearAlgebra", "NLSolversBase", "Printf", "Reexport"] +git-tree-sha1 = "c9578878f56f425a2160f5b436c7f79a154d154c" +uuid = "2774e3e8-f4cf-5e23-947b-6d7e65073b56" +version = "4.1.0" + +[[NaNMath]] +deps = ["Compat"] +git-tree-sha1 = "ce3b85e484a5d4c71dd5316215069311135fa9f2" +uuid = "77ba4419-2d1f-58cd-9bb1-8ffee604a2e3" +version = "0.3.2" + +[[Optim]] +deps = ["Calculus", "DiffEqDiffTools", "FillArrays", "ForwardDiff", "LineSearches", "LinearAlgebra", "NLSolversBase", "NaNMath", "Parameters", "PositiveFactorizations", "Printf", "Random", "SparseArrays", "StatsBase"] +git-tree-sha1 = "ca8f8917df469d607f8cf116784e58c9c084d0b4" +uuid = "429524aa-4258-5aef-a3af-852621145aeb" +version = "0.19.2" + +[[OrderedCollections]] +deps = ["Random", "Serialization", "Test"] +git-tree-sha1 = "c4c13474d23c60d20a67b217f1d7f22a40edf8f1" +uuid = "bac558e1-5e72-5ebc-8fee-abe8a469f55d" +version = "1.1.0" + +[[PDMats]] +deps = ["Arpack", "LinearAlgebra", "SparseArrays", "SuiteSparse", "Test"] +git-tree-sha1 = "f99548922adf8dd5df2f02ab0063944201a12ed8" +uuid = "90014a1f-27ba-587c-ab20-58faa44d9150" +version = "0.9.8" + +[[Parameters]] +deps = ["Markdown", "OrderedCollections", "REPL", "Test"] +git-tree-sha1 = "70bdbfb2bceabb15345c0b54be4544813b3444e4" +uuid = "d96e819e-fc66-5662-9728-84c9c7592b0a" +version = "0.10.3" + +[[Parsers]] +deps = ["Dates", "Test"] +git-tree-sha1 = "db2b35dedab3c0e46dc15996d170af07a5ab91c9" +uuid = "69de0a69-1ddd-5017-9359-2bf0b02dc9f0" +version = "0.3.6" + +[[Pkg]] +deps = ["Dates", "LibGit2", "Markdown", "Printf", "REPL", "Random", "SHA", "UUIDs"] +uuid = "44cfe95a-1eb2-52ea-b672-e2afdf69b78f" + +[[PlotThemes]] +deps = ["PlotUtils", "Requires", "Test"] +git-tree-sha1 = "f3afd2d58e1f6ac9be2cea46e4a9083ccc1d990b" +uuid = "ccf2f8ad-2431-5c83-bf29-c5338b663b6a" +version = "0.3.0" + +[[PlotUtils]] +deps = ["Colors", "Dates", "Printf", "Random", "Reexport", "Test"] +git-tree-sha1 = "8e87bbb778c26f575fbe47fd7a49c7b5ca37c0c6" +uuid = "995b91a9-d308-5afd-9ec6-746e21dbc043" +version = "0.5.8" + +[[Plots]] +deps = ["Base64", "Contour", "Dates", "FFMPEG", "FixedPointNumbers", "GR", "GeometryTypes", "JSON", "LinearAlgebra", "Measures", "NaNMath", "Pkg", "PlotThemes", "PlotUtils", "Printf", "REPL", "Random", "RecipesBase", "Reexport", "Requires", "Showoff", "SparseArrays", "Statistics", "StatsBase", "UUIDs"] +git-tree-sha1 = "e9f562ec6fc69eadac478be600fa90950e149f99" +uuid = "91a5bcdd-55d7-5caf-9e0b-520d859cae80" +version = "0.26.1" + +[[Polynomials]] +deps = ["LinearAlgebra", "SparseArrays", "Test"] +git-tree-sha1 = "62142bd65d3f8aeb2226ec64dd8493349147df94" +uuid = "f27b6e38-b328-58d1-80ce-0feddd5e7a45" +version = "0.5.2" + +[[PositiveFactorizations]] +deps = ["LinearAlgebra", "Test"] +git-tree-sha1 = "957c3dd7c33895469760ce873082fbb6b3620641" +uuid = "85a6dd25-e78a-55b7-8502-1745935b8125" +version = "0.2.2" + +[[Printf]] +deps = ["Unicode"] +uuid = "de0858da-6303-5e67-8744-51eddeeeb8d7" + +[[Profile]] +deps = ["Printf"] +uuid = "9abbd945-dff8-562f-b5e8-e1ebf5ef1b79" + +[[ProgressMeter]] +deps = ["Distributed", "Printf"] +git-tree-sha1 = "0f08e0e74e5b160ca20d3962a2620038b75881c7" +uuid = "92933f4c-e287-5a05-a399-4b506db050ca" +version = "1.0.0" + +[[QuadGK]] +deps = ["DataStructures", "LinearAlgebra", "Test"] +git-tree-sha1 = "3ce467a8e76c6030d4c3786e7d3a73442017cdc0" +uuid = "1fd47b50-473d-5c70-9696-f719f8f3bcdc" +version = "2.0.3" + +[[REPL]] +deps = ["InteractiveUtils", "Markdown", "Sockets"] +uuid = "3fa0cd96-eef1-5676-8a61-b3b8758bbffb" + +[[Random]] +deps = ["Serialization"] +uuid = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" + +[[RecipesBase]] +git-tree-sha1 = "7bdce29bc9b2f5660a6e5e64d64d91ec941f6aa2" +uuid = "3cdcf5f2-1ef4-517c-9805-6587b60abb01" +version = "0.7.0" + +[[Reexport]] +deps = ["Pkg"] +git-tree-sha1 = "7b1d07f411bc8ddb7977ec7f377b97b158514fe0" +uuid = "189a3867-3050-52da-a836-e630ba90ab69" +version = "0.2.0" + +[[Requires]] +deps = ["Test"] +git-tree-sha1 = "f6fbf4ba64d295e146e49e021207993b6b48c7d1" +uuid = "ae029012-a4dd-5104-9daa-d747884805df" +version = "0.5.2" + +[[Rmath]] +deps = ["BinaryProvider", "Libdl", "Random", "Statistics", "Test"] +git-tree-sha1 = "9a6c758cdf73036c3239b0afbea790def1dabff9" +uuid = "79098fc4-a85e-5d69-aa6a-4863f24498fa" +version = "0.5.0" + +[[SHA]] +uuid = "ea8e919c-243c-51af-8825-aaa63cd721ce" + +[[Serialization]] +uuid = "9e88b42a-f829-5b0c-bbe9-9e923198166b" + +[[SharedArrays]] +deps = ["Distributed", "Mmap", "Random", "Serialization"] +uuid = "1a1011a3-84de-559e-8e89-a11a2f7dc383" + +[[Showoff]] +deps = ["Dates"] +git-tree-sha1 = "e032c9df551fb23c9f98ae1064de074111b7bc39" +uuid = "992d4aef-0814-514b-bc4d-f2e9a6c4116f" +version = "0.3.1" + +[[Sockets]] +uuid = "6462fe0b-24de-5631-8697-dd941f90decc" + +[[SortingAlgorithms]] +deps = ["DataStructures", "Random", "Test"] +git-tree-sha1 = "03f5898c9959f8115e30bc7226ada7d0df554ddd" +uuid = "a2af1166-a08f-5f64-846c-94a0d3cef48c" +version = "0.3.1" + +[[SparseArrays]] +deps = ["LinearAlgebra", "Random"] +uuid = "2f01184e-e22b-5df5-ae63-d93ebab69eaf" + +[[SpecialFunctions]] +deps = ["BinDeps", "BinaryProvider", "Libdl", "Test"] +git-tree-sha1 = "0b45dc2e45ed77f445617b99ff2adf0f5b0f23ea" +uuid = "276daf66-3868-5448-9aa4-cd146d93841b" +version = "0.7.2" + +[[StaticArrays]] +deps = ["LinearAlgebra", "Random", "Statistics"] +git-tree-sha1 = "db23bbf50064c582b6f2b9b043c8e7e98ea8c0c6" +uuid = "90137ffa-7385-5640-81b9-e52037218182" +version = "0.11.0" + +[[Statistics]] +deps = ["LinearAlgebra", "SparseArrays"] +uuid = "10745b16-79ce-11e8-11f9-7d13ad32a3b2" + +[[StatsBase]] +deps = ["DataAPI", "DataStructures", "LinearAlgebra", "Missings", "Printf", "Random", "SortingAlgorithms", "SparseArrays", "Statistics"] +git-tree-sha1 = "c53e809e63fe5cf5de13632090bc3520649c9950" +uuid = "2913bbd2-ae8a-5f71-8c99-4fb6c76f3a91" +version = "0.32.0" + +[[StatsFuns]] +deps = ["Rmath", "SpecialFunctions", "Test"] +git-tree-sha1 = "b3a4e86aa13c732b8a8c0ba0c3d3264f55e6bb3e" +uuid = "4c63d2b9-4356-54db-8cca-17b64c39e42c" +version = "0.8.0" + +[[SuiteSparse]] +deps = ["Libdl", "LinearAlgebra", "SparseArrays"] +uuid = "4607b0f0-06f3-5cda-b6b1-a6196a1729e9" + +[[Test]] +deps = ["Distributed", "InteractiveUtils", "Logging", "Random"] +uuid = "8dfed614-e22c-5e08-85e1-65c5234f0b40" + +[[TranscodingStreams]] +deps = ["Random", "Test"] +git-tree-sha1 = "7c53c35547de1c5b9d46a4797cf6d8253807108c" +uuid = "3bb67fe8-82b1-5028-8e26-92a6c54297fa" +version = "0.9.5" + +[[Twiddle]] +deps = ["Test"] +git-tree-sha1 = "45a81952077aaf0396c3ddcbd561e660a44ce331" +uuid = "7200193e-83a8-5a55-b20d-5d36d44a0795" +version = "1.1.0" + +[[URIParser]] +deps = ["Test", "Unicode"] +git-tree-sha1 = "6ddf8244220dfda2f17539fa8c9de20d6c575b69" +uuid = "30578b45-9adc-5946-b283-645ec420af67" +version = "0.4.0" + +[[UUIDs]] +deps = ["Random"] +uuid = "cf7118a7-6976-5b1a-9a39-7adc72f591a4" + +[[Unicode]] +uuid = "4ec0a83e-493e-50e2-b9ac-8f72acf5a8f5" + +[[YAML]] +deps = ["Codecs", "Compat"] +git-tree-sha1 = "3bde77cee95cce0c0b9b18813d85e18e8ed4f415" +uuid = "ddb6d928-2868-570f-bddf-ab3f9cf99eb6" +version = "0.3.2" diff --git a/Project.toml b/Project.toml new file mode 100644 index 0000000..48c2c57 --- /dev/null +++ b/Project.toml @@ -0,0 +1,29 @@ +name = "JuliASM" +uuid = "182478e6-e505-11e8-0d37-f3ec3c522fa3" +authors = ["jordiabante "] +version = "0.1.0" + +[deps] +BioAlignments = "00701ae9-d1dc-5365-b64a-a3a3ebf5695e" +BioSequences = "7e6ae17a-c86d-528c-b3b9-7f778a29fe59" +Calculus = "49dc2e85-a5d0-5ad3-a950-438e2897f1b9" +Colors = "5ae59095-9a9b-59fe-a467-6f913c188581" +Combinatorics = "861a8166-3701-5b0c-9a16-15d98fcdc6aa" +Dates = "ade2ca70-3891-5945-98fb-dc099432e06a" +DelimitedFiles = "8bb1440f-4735-579b-a4ab-409b98df4dab" +Distributed = "8ba89e20-285c-5b6f-9357-94700520ee1b" +Distributions = "31c24e10-a181-5473-b8eb-7969acd0382f" +ForwardDiff = "f6369f11-7733-5829-9624-2563aa707210" +GeneticVariation = "9bc6ac9d-e6b2-5f70-b0a8-242a01662520" +GenomicFeatures = "899a7d2d-5c61-547b-bef9-6698a8d05446" +LaTeXStrings = "b964fa9f-0449-5b57-a5c2-d3ea65f4040f" +LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" +MultipleTesting = "f8716d33-7c4a-5097-896f-ce0ecbd3ef6b" +NLsolve = "2774e3e8-f4cf-5e23-947b-6d7e65073b56" +Optim = "429524aa-4258-5aef-a3af-852621145aeb" +Plots = "91a5bcdd-55d7-5caf-9e0b-520d859cae80" +ProgressMeter = "92933f4c-e287-5a05-a399-4b506db050ca" +Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" +SharedArrays = "1a1011a3-84de-559e-8e89-a11a2f7dc383" +StatsBase = "2913bbd2-ae8a-5f71-8c99-4fb6c76f3a91" +Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" diff --git a/README.md b/README.md new file mode 100644 index 0000000..e4270dd --- /dev/null +++ b/README.md @@ -0,0 +1,64 @@ +# JuliASM + +A `julia` package for allele-specific methylation (ASM) analysis. + +## Description + +`JuliASM` is based on the method in [CITE], and it draws ideas from +statistical physics and information theory to identify allele-specific +methylation events at the haplotype level. + +## Getting Started + +### Prerequisites + +* `julia v1.0.0` or greater. +* `git`. + +### Installing + +`JuliASM` and dependencies can be installed via the following command: +```julia +julia -e 'using Pkg; Pkg.add(PackageSpec(url="https://github.com/jordiabante/JuliASM.jl.git"))' +``` + +## Running the tests + +In a `julia` session run +```julia +(v1.0) pkg> test JuliASM +``` + +## Toy Example + +The package includes a small toy example for illustrative purposes. +The example consists of two alleles `a1` and `a2`. The former has a +mean-methylation level (MML) of 0.4, while that of the later is 0.6. +Nevertheless, given the symmetry of the problem, both alleles have +the same Shannon entropy. Thus differential analysis only identifies +differences in terms of MML. The output bedGraph files can be found +in `out_path`. To run the toy example run the following commands in +a `julia` session: + +```julia +using JuliASM +dir = "/path/to/JuliASM.jl/test/" +b1 = "$(dir)/bam/example.a1.bam" +b2 = "$(dir)/bam/example.a2.bam" +fa = "$(dir)/fasta/example.fa" +vcf = "$(dir)/vcf/example.vcf" +out = "$(dir)/out/" +run_analysis(b1,b2,b1,vcf,fa,out;blk_size=20,cov_ths=3,cov_b=20.0,win_exp=10,mc_null=1000,n_max=5) +``` + +## Authors + +* **Jordi Abante** + +## License + +This project is licensed under the MIT License - see the [LICENSE.md](LICENSE.md) +file for details. + +## References +[CITE] diff --git a/src/JuliASM.jl b/src/JuliASM.jl new file mode 100644 index 0000000..f243997 --- /dev/null +++ b/src/JuliASM.jl @@ -0,0 +1,68 @@ +__precompile__() + +module JuliASM +################################################################################################### +# DEPENDENCIES +################################################################################################### +using Distributed # For parallelization +using SharedArrays # For parallelization +using DelimitedFiles # For delimited files +using Random # For random number generation +using StatsBase # For statistics +using Calculus # For Hessian estimation +using LinearAlgebra # For Eigendecomposition of Σ +using Dates # For showing time +using Distributions # For sampling RVs +using Plots # For plots +using LaTeXStrings # For labels in plots +using ForwardDiff # For auto-differentiation +using Optim # For Simulated annealing +using NLsolve # For EM algorithm +using BioAlignments # For reading-in BAM/SAM files +using GenomicFeatures # For BED, GFF3, and bigWig files +using GeneticVariation # For VCF file +using BioSequences # For FASTA file +using Combinatorics # For permutation test +using MultipleTesting # For multiple hypothesis testing +################################################################################################### +# INCLUDES +################################################################################################### +include("juliASM_plots.jl") +include("juliASM_estimation.jl") +include("juliASM_simulations.jl") +include("juliASM_bioinformatics.jl") +include("juliASM_output.jl") +################################################################################################### +# EXPORTS +################################################################################################### + +# Data generating functions +export gen_x_mc # Generate a methylation vector using MC approach +export gen_ising_full_data # Generate a set of full observations using slow approach +export gen_ising_part_data # Generate a set of partial observations using slow approach + +# Different computations +export comp_Z # Partition function +export est_alpha # Estimate α for N=1 case +export est_theta_sa # Estimate θ in general case using Simulated Annealing +export est_theta_em # Estimate θ in general case using EM algorithm +export comp_lkhd # Compute likelihood +export comp_ex # Compute E[X] vector +export comp_exx # Compute E[XX] vector +export comp_cov # Compute Σ matrix +export comp_mml # Compute MML in `comp_tobs` +export comp_mml_∇ # Compute MML in `comp_tnull (uses ∇logZ) +export comp_nme # Compute NME in `comp_tobs` +export comp_nme_∇ # Compute NME in `comp_tnull` (uses ∇logZ) +export comp_nme_mix_mc # Compute NME in mixture model using MC technique +export comp_nme_mix_exact # Compute NME in mixture model recursively (N<17) +export comp_uc # Compute UC + +# General functions +export gen_gffs # Function to generate GFF files +export comp_tobs # Compute statistis in haplotypes +export comp_tnull # Generate null statistis +export comp_pvals # Compute p-values +export run_analysis # Run it all + +end # module diff --git a/src/juliASM_bioinformatics.jl b/src/juliASM_bioinformatics.jl new file mode 100644 index 0000000..f1bd27c --- /dev/null +++ b/src/juliASM_bioinformatics.jl @@ -0,0 +1,1391 @@ +################################################################################################### +# CONSTANTS +################################################################################################### +const BG_BUFFER = 50000 # Bytes of bedGraph records until write +const GFF_BUFFER = 500000 # Bytes of GFF records until write +const THRESH_MAPQ = 39 # MAPQ threshold (-10*log(p)) only true uni-reads +const FLAGS_ALLOWED = [0,16,83,99,147,163] # Flags allowed in BAM recs +################################################################################################### +# STRUCTS +################################################################################################### +struct AlignTemp + strand::String # Methylation call strand + R1::BAM.Record # First record from left to right + R2::BAM.Record # Second record from left to right +end +mutable struct AllAlignTemps + paired::Bool + templates::Array{AlignTemp,1} +end +################################################################################################### +# FUNCTIONS +################################################################################################### +""" + `get_align_strand(PAIRED_END,FLAG1,FLAG2)` + +Function that returns the strand of methylation call based on Bismark's logic. In single-end mode, +OT and CTOT reads will both receive a FLAG of 0 while OB and CTOB both receive a FLAG of 16. In +paired end mode: + + Read 1 Read 2 + OT: 99 147 + OB: 83 163 + CTOT: 147 99 + CTOB: 163 83 + +This table was extracted from + + https://github.com/FelixKrueger/Bismark/issues/151 + +# Examples +```julia-repl +julia> JuliASM.get_align_strand(true,UInt16(99),UInt16(147)) +"OT" +``` +""" +function get_align_strand(pe::Bool,flag1::UInt16,flag2::UInt16)::String + + # Treat SE and PE separately + if !pe + if flag1==0 + s="OT" + elseif flag1==16 + s="OB" + else + println(stderr,"[$(now())]: SE: was expecting FLAG 0 or and") + println(stderr,"[$(now())]: encountered $(flag1) instead.") + println(stderr,"[$(now())]: Exiting julia ...") + exit(1) + end + else + if flag1==99 && flag2==147 + s="OT" + elseif flag1==83 && flag2==163 + s="OB" + elseif flag1==147 && flag2==99 + s="CTOT" + elseif flag1==163 && flag2==83 + s="CTOB" + else + println(stderr, "[$(now())]: PE: unexpected flag combination.") + println(stderr, "[$(now())]: Expected 99/147, 147/99, 83/163, 163/83.") + println(stderr, "[$(now())]: Exiting julia ...") + exit(1) + end + end + + # Return strand + return s + +end # end get_align_strand +""" + `order_bams(PAIRED_END,RECORDS)` + +Function that returns an AlignTemp object with R1 as the first record in the forward strand and +with the methylation call strand taken from `get_align_strand`. + +# Examples +```julia-repl +julia> JuliASM.order_bams(true,RECORDS) +``` +""" +function order_bams(pe::Bool,records::Vector{BAM.Record})::AlignTemp + + # Check which record appears first in forward strand + if BAM.position(records[1])<=BAM.position(records[2]) + s = get_align_strand(pe, BAM.flag(records[1]), BAM.flag(records[2])) + return AlignTemp(s,records[1],records[2]) + else + s = get_align_strand(pe, BAM.flag(records[2]), BAM.flag(records[1])) + return AlignTemp(s,records[2],records[1]) + end + +end +""" + `clean_records(PAIRED_END,RECORDS)` + +Function that takes a set of records and returns an AllAlignTemps object that contains all the +properly aligned templates as an array of AlignTemp, which contains information about the +methylation call strand as well as the relevant BAM records. In the PE case, R1 corresponds to +the BAM record that appears before in the forward strand. + +# Examples +```julia-repl +julia> JuliASM.clean_records(true,RECORDS) +``` +""" +function clean_records(pe::Bool,records::Vector{BAM.Record})::AllAlignTemps + + # Initialize struct + out = AllAlignTemps(pe,[]) + + # Consider PE vs. SE + if pe + # Handle PE case, first retrieve unique template names + temp_names = unique([BAM.tempname(x) for x in records]) + for temp_name in temp_names + # Get records with same template name + temp_recs = filter(x->BAM.tempname(x)==temp_name,records) + + # There should only be two records with the same template name + length(temp_recs)==2 && push!(out.templates,order_bams(pe,temp_recs)) + end + else + # Handle SE case + out.templates = [AlignTemp(get_align_strand(pe,BAM.flag(x),UInt16(0)),x,BAM.Record()) for + x in records] + end + + # Return struct + return out + +end # end clean_records +""" + `try_olaps(READER,CHR,WINDOW)` + +Function that tries to find BAM records overlaping with `CHR` at positions `WINDOW`. + +# Examples +```julia-repl +julia> try_olaps(reader,chr,win) +``` +""" +function try_olaps(reader::BAM.Reader,chr::String,win::Vector{Int64})::Vector{BAM.Record} + + # NOTE: known bug that has to do w/ BioAlignments when close to end? + records_olap = + try + collect(eachoverlap(reader, chr, win[1]:win[2])) + catch + Array{BAM.Record,1}() + end + + return records_olap + +end # try_olaps +""" + `read_bam(BAM_PATH,CHR,FEAT_ST,FEAT_END,CPG_POS,PE,TRIM)` + +Function that reads in BAM file in `BAM_PATH` and returns methylation vectors for those records +that overlap with (1-based) genomic coordinates `chr:chrSt-chrEnd` at `cpg_pos`. A trimming given +by TRIM=(Rf_5p,Rf_3p,Rr_5p,Rr_3p) is applied to the reads. The information was taken from: + + XS: meth calls (https://github.com/FelixKrueger/Bismark/tree/master/Docs) + XS: uniqueness (http://bowtie-bio.sourceforge.net/bowtie2/manual.shtml) + +For info on OT, CTOT, OB, CTOB nomenclature see + + http://software.broadinstitute.org/software/igv/book/export/html/37. + +# Examples +```julia-repl +julia> read_bam(BAM_PATH,"chr1",30,80,[40,60],false,(0,0,0,0)) +``` +""" +function read_bam(bam::String,chr::String,f_st::Int64,f_end::Int64,cpg_pos::Vector{Int64}, + chr_size::Int64,pe::Bool,trim::NTuple{4,Int64})::Array{Vector{Int64},1} + + # Number of CpG sites is determined by that in the region + N = length(cpg_pos) + + # Expand window in PE case to include pair even if it's outside the window + exp_win = pe ? [max(1,f_st-75),min(chr_size,f_end+75)] : [f_st,f_end] + + # Get records overlapping window. + reader = open(BAM.Reader,bam,index=bam*".bai") + records_olap = try_olaps(reader,chr,exp_win) + length(records_olap)>0 || return Vector{Int64}[] + close(reader) + + # Relevant flags in BAM file (both Bismark and Arioc) + filter!(x-> (BAM.ismapped(x)) && (haskey(x,"XM")) && (!haskey(x,"XS")) && (BAM.flag(x) in + FLAGS_ALLOWED) && (BAM.mappingquality(x)>THRESH_MAPQ),records_olap) + + # Clean records & organize them + records_org = clean_records(pe,records_olap) + + # Loop over organized records + xobs = Vector{Int64}[] + for record in records_org.templates + # Get methylation call and offset (depends on strand where call is made) + if !(records_org.paired) + # Obtain methylation call from single end () + meth_call = record.R1[:"XM"] + meth_call = SubString(meth_call,(1+trim[1]):(length(meth_call)-trim[2])) + OFFSET= record.strand in ["OT","CTOT"] ? 1 : 2 + OFFSET -= BAM.position(record.R1)+trim[1] + else + # Obtain methylation call + R1_call = record.R1[:"XM"] + R2_call = record.R2[:"XM"] + R1_call = SubString(R1_call,(1+trim[1]):(length(R1_call)-trim[2])) + R2_call = SubString(R2_call,(1+trim[4]):(length(R2_call)-trim[3])) + dist_st = abs(BAM.position(record.R2)+trim[4] - BAM.position(record.R1)-trim[1]) + meth_call = R1_call * "."^max(0,dist_st-length(R1_call)) + meth_call *= R2_call[max(1,(length(R1_call)+1-dist_st)):end] + OFFSET= record.strand in ["OT","CTOT"] ? 1 : 2 + OFFSET -= BAM.position(record.R1)+trim[1] + end + + # Cross positions of CpG sites if template contains CpG sites + obs_cpgs = [x.offset for x in eachmatch(r"[zZ]",meth_call)] .- OFFSET + length(obs_cpgs)>0 || continue + + # If overlapping CpG sites then store and add to xobs + olap_cpgs = findall(x-> x in obs_cpgs, cpg_pos) + length(olap_cpgs)>0 || continue + x = zeros(Int64,N) + obs_cpgs = obs_cpgs[findall(x-> x in cpg_pos,obs_cpgs)] .+ OFFSET + x[olap_cpgs] = reduce(replace,["Z"=>1,"z"=>-1],init=split(meth_call[obs_cpgs],"")) + push!(xobs,x) + + end # end loop over templates sequenced + + # Return + return xobs + +end # end read_bam +""" + `write_gff!(OUT_GFF,GFF_RECORDS)` + +Function that appends `GFF_RECORDS` into `OUT_GFF`. + +# Examples +```julia-repl +julia> write_gff!(gff, gff_records) +``` +""" +function write_gff!(gff::String,gff_records::Vector{GFF3.Record}) + + # Append gff records + output = open(gff, "a") + writer = GFF3.Writer(output) + while length(gff_records)>0 + write(writer,popfirst!(gff_records)) + end + close(writer) + + # Return + return nothing + +end # end write_gff +""" + `next_record(READER,CHR_NAMES,RECORD)` + +Recursive function that returns next record in stream if in chr_names, and false if the stream +reached its end. This function is only used in `gen_gffs()`. + +# Examples +```julia-repl +julia> next_record(reader, chr_names, record) +``` +""" +function next_record(reader::VCF.Reader,chr_names::Vector{String},record::VCF.Record)::VCF.Record + + # Check if record in chr_names and end of reader + if VCF.chrom(record) in chr_names + # If we're good, return record + return record + elseif !eof(reader) + # If not end of file, call function again + read!(reader, record) + next_record(reader, chr_names, record) + else + # return empty record if finished stream + return VCF.Record() + end + +end # end next_record +""" + `is_het_cpg!(VAR,SEQ,H1,H2)` + +Function that adds position of heterozygous CpG site, if existant, to the correct haplotype. +Assumes that REF is the one pertaining to genome 1, and ALT is the one pertaining to genome 2. + +# Examples +```julia-repl +julia> is_het_cpg!(var,seq,h1,h2) +``` +""" +function is_het_cpg!(var::VCF.Record,seq::FASTA.Record,h1::Vector{Int64},h2::Vector{Int64}) + # Initialize + ref_var = join(VCF.ref(var)) + alt_var = join(VCF.alt(var)) + + # Check if heterozygous CpG site in XG context + if ((ref_var=="C") && (alt_var in ["A","G"])) + # If followed by G, then heterozygous CpG in haplotype 1 + if FASTA.sequence(seq,VCF.pos(var):(VCF.pos(var)+1))[2]==DNA_G + push!(h1,VCF.pos(var)) + end + elseif ((alt_var=="C") && (ref_var in ["A","G"])) + # If followed by G, then heterozygous CpG in haplotype 2 + if FASTA.sequence(seq,VCF.pos(var):(VCF.pos(var)+1))[2]==DNA_G + push!(h2,VCF.pos(var)) + end + end + + # Check if het CpG site in CX context + if ((ref_var=="G") && (alt_var in ["A","C","T"])) + # If preceeded by C, then heterozygous CpG in haplotype 1 + if FASTA.sequence(seq,(VCF.pos(var)-1):VCF.pos(var))[1]==DNA_C + push!(h1,VCF.pos(var)-1) + end + elseif ((alt_var=="G") && (ref_var in ["A","C","T"])) + # If preceeded by C, then heterozygous CpG in haplotype 2 + if FASTA.sequence(seq,(VCF.pos(var)-1):VCF.pos(var))[1]==DNA_C + push!(h2,VCF.pos(var)-1) + end + end + + # Return + return nothing + +end # end is_het_cpg! +""" + `get_records_ps!(VCF_READER,SEQ,RECORD,CURR_PS,WIN_END,H1,H2)` + +Recursive function that returns the end of current PS phased SNPs along the next SNP. This +function is only used in `gen_gffs()`. + +# Examples +```julia-repl +julia> get_records_ps!(reader,seq,record,curr_ps,wEnd,h1,h2) +``` +""" +function get_records_ps!(reader::VCF.Reader,seq::FASTA.Record,record::VCF.Record,curr_ps::String, + wEnd::Int64,h1::Vector{Int64},h2::Vector{Int64})::Tuple{VCF.Record,Int64} + + # Check if record has same PS + ind_PS = findfirst(x->x=="PS",VCF.format(record)) + VCF.genotype(record)[1][ind_PS]==curr_ps || return record,wEnd + + # Check GT string and update het. CpG sites + ind_GT = findfirst(x->x=="GT",VCF.format(record)) + curr_gt = VCF.genotype(record)[1][ind_GT] + curr_gt in ["0/1","0|1"] ? is_het_cpg!(record,seq,h1,h2) : is_het_cpg!(record,seq,h2,h1) + + # Continue reading + wEnd = VCF.pos(record) + if !eof(reader) + read!(reader, record) + if "PS" in VCF.format(record) + record,wEnd = get_records_ps!(reader,seq,record,curr_ps,wEnd,h1,h2) + else + return record,wEnd + end + else + # return empty record if finished stream + return VCF.Record(),wEnd + end + +end # end get_records_ps +""" + `expand_win(FIRST_SNP,LAST_SNP,WIN_EXP,BLOCK_SIZE,CHR_SIZE)` + +Function that returns an expanded window given the position of the first and last SNPs, the +expansion to be done to the left and right, of the first and last SNP respectively, to include +nearby CpG sites, and the size of the subregions into which the whole region will be divided into. + +# Examples +```julia-repl +julia> expand_win(50,80,10,50,2000) +?? +``` +""" +function expand_win(l_snp::Int64,r_snp::Int64,win_exp::Int64,blk_size::Int64, + chr_size::Int64)::Vector{Int64} + + # Expand left and right to include nearby CpG sites + l_snp -= win_exp + r_snp += win_exp + + # Add remaining to be multiple of blk_size + rmdr = (r_snp-l_snp+1)%blk_size==0 ? 0 : div(blk_size-(r_snp-l_snp+1)%blk_size,2) + + # Cap at 1 and end of chromosome + return [max(1,l_snp-rmdr),min(chr_size,r_snp+rmdr)] + +end # end expand_win +""" + `find_num_models(CPG_POS,NMAX,NMOD)` + +Function that returns the number of models required so as to avoid joint model with N>NMAX. + +# Examples +```julia-repl +julia> JuliASM.find_num_models([50,55,60,65],2,1) +2 +``` +""" +function find_num_models(cpg_pos::Vector{Int64},n_max::Int64,n_mod::Int64)::Int64 + + # Check if resulting models are acceptable + return length(cpg_pos)/n_mod>n_max ? find_num_models(cpg_pos,n_max,n_mod+1) : n_mod + +end # end find_num_models +""" + `gen_gffs([HET_GFF_PATH,HOM_GFF_PATH],FA_PATH,VCF_PATH,WIN_EXP,BLOCK_SIZE,NMAX)` + +Function that creates a GFF file containing the genomic regions to be analyzed by `JuliASM`. If a +set of SNPs is phased, this function will create a single window for all. In case, the set of SNPs +is not phased, then an individual window will be created for each SNP. The phasing of the VCF +records should be specified by means of the standard `PS` tag. In addition, a GFF file containing +the homozygous portion of the DNA is also generated together with the position of the CpG sites +in it. + +# Examples +```julia-repl +julia> gen_gffs([HET_GFF_PATH,HOM_GFF_PATH],FA_PATH,VCF_PATH,WIN_EXP,BLOCK_SIZE,NMAX) +``` +""" +function gen_gffs(gff::Vector{String},fa::String,vcf::String,win_exp::Int64,blk_size::Int64, + n_max::Int64) + + # Initialize VCF variables + het_records = Vector{GFF3.Record}() + hom_records = Vector{GFF3.Record}() + reader_vcf = open(VCF.Reader,vcf) + record = VCF.Record() + read!(reader_vcf,record) + + # Initialize FASTA variables + prev_end = 0 + reader_fa = open(FASTA.Reader, fa, index=fa*".fai") + chr_names = reader_fa.index.names + curr_chr = chr_names[1] + fa_record = reader_fa[curr_chr] + close(reader_fa) + + # Chrom sizes + chr_sizes = reader_fa.index.lengths + chr_size = chr_sizes[findfirst(x->x==curr_chr,chr_names)] + + # Loop over variants + while true + + # Check if chromosome is in FASTA file. If not, obtain the next valid 1 + record = next_record(reader_vcf, chr_names, record) + + # Check we have loaded the right chromosome from FASTA + if !(curr_chr == VCF.chrom(record)) + curr_chr = VCF.chrom(record) + reader_fa = open(FASTA.Reader,fa,index=fa*".fai") + fa_record = reader_fa[curr_chr] + chr_size = chr_sizes[findfirst(x->x==curr_chr, chr_names)] + close(reader_fa) + prev_end=0 + end + + # Get entire (contiguous) haplotype using the PS field + wSt = VCF.pos(record) + wEnd = VCF.pos(record) + het1 = Vector{Int64}() + het2 = Vector{Int64}() + if "PS" in VCF.format(record) + # If PS tag, then phased + ind_PS = findfirst(x->x=="PS",VCF.format(record)) + curr_ps = VCF.genotype(record)[1][ind_PS] + record,wEnd = get_records_ps!(reader_vcf,fa_record,record,curr_ps,wEnd,het1,het2) + else + # If no PS tag, then single SNP (marked as NOPS) + curr_ps = "NOPS" + is_het_cpg!(record,fa_record,het1,het2) + eof(reader_vcf) ? record=VCF.Record() : read!(reader_vcf, record) + end + + # Get remainder from block size and distribute it evenly + win = expand_win(wSt,wEnd,win_exp,blk_size,chr_size) + + # Obtain DNA sequence from reference and homozygous CpG loci from it + wSeq = convert(String,FASTA.sequence(fa_record,win[1]:win[2])) + cpg_pos = map(x->getfield(x,:offset),eachmatch(r"CG",wSeq)).+win[1].-1 + + # Store heterozygous haplotype & corresponding CpG sites if homozygous CpG site/s + if length(cpg_pos)>0 + + # Obtain required number of models based on homozygous CpG sites + n_mod = find_num_models(cpg_pos,n_max,1) + mod_size = div(length(cpg_pos),n_mod) + mod_rem = length(cpg_pos)-n_mod*mod_size + + # Print each set separately + for i=1:n_mod + # Index of subset of CpG sites in cpg_pos + hom_rng = (mod_size*(i-1)+1):min((mod_size*i),length(cpg_pos)) + # Add remainders to last block + i==n_mod && mod_rem>0 && (hom_rng=extrema(hom_rng)[1]:length(cpg_pos)) + # Get subset of CpG sites for each + hom_mod = cpg_pos[hom_rng] + # Get submodel boundaries + inf_bound = i==1 ? win[1] : cpg_pos[max(1,extrema(hom_rng)[1]-1)] + sup_bound = i==n_mod ? win[2] : hom_mod[end] + # Get heterozygous CpG sites in current submodel + het1_mod = het1[findall(x-> inf_bound <= x <= sup_bound,het1)] + het2_mod = het2[findall(x-> inf_bound <= x <= sup_bound,het2)] + # Make submodel window a multiple of G (no new CpGs included) + win_mod = expand_win(inf_bound,sup_bound,0,blk_size,chr_size) + # Push output string + out_str = "$(curr_chr)\t.\t$(curr_ps)-$(i)/$(n_mod)\t$(win_mod[1])\t$(win_mod[2])" + out_str *= "\t.\t.\t.\tN=$(length(hom_mod));CpGs=$(hom_mod)" + length(het1_mod)>0 && (out_str*=";hetCpGg1=$(het1_mod)") + length(het2_mod)>0 && (out_str*=";hetCpGg2=$(het2_mod)") + # Push GFF record + push!(het_records,GFF3.Record(out_str)) + end + + end + + # Check if het_records object is too big and empty it if so + sizeof(het_records)>GFF_BUFFER && write_gff!(gff[1],het_records) + + # Obtain homozygous portion + hom_win = [prev_end+1,win[1]-1] + hom_win = [max(1,hom_win[1]),min(chr_size,hom_win[2])] + + # Obtain DNA sequence from reference and homozygous CpG loci from it + wSeq = convert(String,FASTA.sequence(fa_record,hom_win[1]:hom_win[2])) + cpg_pos = map(x->getfield(x,:offset),eachmatch(r"CG",wSeq)).+hom_win[1].-1 + + # Store homozygous stretch of CpG sites found + if length(cpg_pos)>0 + out_str = "$(curr_chr)\t.\t.\t$(hom_win[1])\t$(hom_win[2])\t$(length(cpg_pos))\t.\t.\t" + out_str *= "CpGs=$(cpg_pos)" + push!(hom_records,GFF3.Record(out_str)) + end + + # Update previous end + prev_end = win[2] + + # Check if hom_records object is too big and empty it if so + sizeof(hom_records)>GFF_BUFFER && write_gff!(gff[2],hom_records) + + # If new record empty break while loop + VCF.haspos(record) || break + + end + + # Dump remaining records + write_gff!(gff[1],het_records) + write_gff!(gff[2],hom_records) + + # Return + return nothing + +end # end gen_gffs +""" + `read_gff_chr(GFF_PATH,CHR)` + +Function that reads in a GFF3 file in `GFF_PATH` and returns an array of GenomicFeatures Record +objects contained in chromosome `CHR`. The format is the standard defined by ENSEMBL in +https://useast.ensembl.org/info/website/upload/gff3.html. + +# Examples +```julia-repl +julia> read_gff_chr(GFF_PATH,"chr1") +``` +""" +function read_gff_chr(gff::String,chr::String)::Vector{GFF3.Record} + + # Load genomic features from a GFF3 file + features = open(collect,GFF3.Reader,gff) + + # Keep features in chr + filter!(x -> GFF3.seqid(x)==chr, features) + + # Return + return features + +end # end read_gff_chr +""" + `write_tobs(RECORDS,CHR,PATH)` + +Function that writes records in `RECORDS` into `PATH`. + +# Examples +```julia-repl +julia> write_tobs(RECORDS,CHR,PATH) +``` +""" +function write_tobs(recs::Vector{Tuple{Int64,Int64,Float64,Int64,Int64}},chr::String,path::String) + + # Open output bedGraph file in append mode (no need to close it) + open(path, "a") do f + for i=1:length(recs) + recs[i][1]!=0 || continue + write(f,"$(chr)\t"*join(string.(collect(recs[i])),"\t"),"\n") + end + end + + # Return + return nothing + +end # end write_tobs +""" + `get_cpg_pos(FEAT_ATTS)` + +Function that takes the attributes in the GFF file and returns the homozygous and heterozygous CpG +sites in it. + +# Examples +```julia-repl +julia> get_cpg_pos(feat_atts) +``` +""" +function get_cpg_pos(atts::Dict{String,Vector{String}})::Array{Vector{Int64},1} + + # Retrieve homozygous CpG sites + hom = [parse(Int64,replace(s,r"[\[\] ]"=>"")) for s in atts[:"CpGs"]] + + # Retrieve heterozygous CpG sites for each haplotype (if existant) + het1=Vector{Int64}() + het2=Vector{Int64}() + if haskey(atts,"hetCpGg1") + het1=[parse(Int64,replace(s,r"[\[\] ]"=>"")) for s in atts[:"hetCpGg1"]] + end + if haskey(atts,"hetCpGg2") + het2=[parse(Int64,replace(s,r"[\[\] ]"=>"")) for s in atts[:"hetCpGg2"]] + end + + return [hom,sort!(append!(het1,hom)),sort!(append!(het2,hom))] + +end # end get_cpg_pos +""" + `get_ns(CPG_POS,BLOCK_SIZE,FEAT_ST)` + +Functions that returns `[N1,...,NK]` given the position of the CpG sites and a block size +`BLOCK_SIZE` into which the region is partitioned. + +# Examples +```julia-repl +julia> get_ns([100,250,300,350],200,90) +2-element Vector{Int64}: + 2 + 2 +``` +""" +function get_ns(cpg_pos::Vector{Int64},blk_size::Int64,f_st::Int64)::Vector{Int64} + + # Check all cpg_pos are not upstream of f_st (provisional check) + if minimum(cpg_pos)=0) && ((p-f_st-(j+1)*blk_size)<=0) && break + j += 1 + end + push!(y,j) + end + + # Return array of arrays + return [sum(y.==i) for i in unique(y)] + +end # end get_ns +""" + `mean_cov(XOBS)` + +Function returns the average coverage per CpG given some observations `XOBS`. + +# Examples +```julia-repl +julia> xobs=[[1,-1] for i=1:10]; append!(xobs,[[1,0] for i=1:10]); +julia> mean_cov(xobs) +15.0 +``` +""" +function mean_cov(xobs::Array{Vector{Int64},1})::Float64 + + # Return 0 if no observations + return length(xobs)>0 ? norm(hcat(xobs...),1)/length(xobs[1]) : 0.0 + +end # end mean_cov +""" + `get_outpaths(OUTDIR,PREFIX)` + +Function that given outdir and prefix returns paths. + +# Examples +```julia-repl +julia> JuliASM.get_outpaths(outdir,prefix) +``` +""" +function get_outpaths(outdir::String,prefix::String) + + # Paths + tobs_path = "$(outdir)/$(prefix)" .* ["_mml1","_mml2","_nme1","_nme2","_uc"] .* ".bedGraph" + tnull_path = "$(outdir)/$(prefix)" .* ["_dmml_null","_dnme_null","_uc_null"] .* ".bedGraph" + p_path = "$(outdir)/$(prefix)" .* ["_dmml_pvals","_dnme_pvals","_uc_pvals"] .* ".bedGraph" + + # Return path for Tobs and Tnull + return tobs_path,tnull_path,p_path + +end # end get_outpaths +""" + `sort_bedgraphs(BEDGRAPH_FILES)` + +Function that sorts bedGraph files in vector BEDGRAPH_FILES. + +# Examples +```julia-repl +julia> JuliASM.sort_bedgraphs(bg_files) +``` +""" +function sort_bedgraphs(bg_files::Vector{String}) + + # Loop over files + for f in bg_files + run(`sort -V -k 1,1 -k 2,2n -o $f $f`) + end + + # Return + return nothing + +end # end sort_bedgraphs +""" + `print_log(MESSAGE)` + +Function that prints MESSAGE to stderr. + +# Examples +```julia-repl +julia> JuliASM.print_log("Hello") +Hello +``` +""" +function print_log(mess::String) + + # Right format for date + date = Dates.format(now(), "yyyy-mm-dd HH:MM:SS") + println(stderr,"[$(date)]: " * mess) + flush(stderr) + + # Return + return nothing + +end # end print_log +""" + `comp_tobs(BAM1_PATH,BAM2_PATH,GFF_PATH,FA_PATH,OUT_PATHS)` + +Function that computes MML1/2, NME1/2, and UC on a pair of BAM files (allele 1, allele 2) given a +(phased) VCF file that contains the heterozygous SNPs and a FASTA file that contains the reference +genome. + +# Examples +```julia-repl +julia> comp_tobs(BAM1_PATH,BAM2_PATH,GFF_PATH,FA_PATH,OUT_PATHS) +``` +""" +function comp_tobs(bam1::String,bam2::String,gff::String,fa::String,out_paths::Vector{String}; + pe::Bool=true,blk_size::Int64=300,cov_ths::Int64=5,trim::NTuple{4,Int64}= + (0,0,0,0)) + + # BigWig output files + mml1_path,mml2_path,nme1_path,nme2_path,uc_path = out_paths + + # Find chromosomes + reader_fa = open(FASTA.Reader,fa,index=fa*".fai") + chr_sizes = reader_fa.index.lengths + chr_names = reader_fa.index.names + close(reader_fa) + + # Loop over chromosomes + for chr in chr_names + + # Get windows pertaining to current chromosome + print_log("Processing chromosome $(chr) ...") + features_chr = read_gff_chr(gff,chr) + chr_size = chr_sizes[findfirst(x->x==chr, chr_names)] + + # bedGraph records + out_sa=SharedArray{Tuple{Int64,Int64,Float64,Int64,Int64},2}(length(features_chr),8) + + # Loop over windows in chromosome + @sync @distributed for i=1:length(features_chr) + + # Get window of interest + feat = features_chr[i] + f_st = GFF3.seqstart(feat) + f_end = GFF3.seqend(feat) + + # Get homozygous & heterozygous CpG sites (1:hom, 2:hap1, 3: hap2) + cpg_pos = get_cpg_pos(Dict(GFF3.attributes(feat))) + n = get_ns(cpg_pos[1],blk_size,f_st) + n1 = get_ns(cpg_pos[2],blk_size,f_st) + n2 = get_ns(cpg_pos[3],blk_size,f_st) + length(n)>0 || continue + + # Get vectors from BAM1/2 overlapping feature & compute average coverage + xobs1 = read_bam(bam1,chr,f_st,f_end,cpg_pos[2],chr_size,pe,trim) + cov_ths <= mean_cov(xobs1) <= 200 || continue + xobs2 = read_bam(bam2,chr,f_st,f_end,cpg_pos[3],chr_size,pe,trim) + cov_ths <= mean_cov(xobs2) <= 200 || continue + + # Check MLE exists + length(unique(xobs1))>1 || continue + length(unique(xobs2))>1 || continue + + # Estimate each single-allele model and check if on boundary of parameter space + θ1,converged = est_theta_em(n1,xobs1) + # converged || println("Failed to converge at $(xobs1)") + converged || continue + # converged && println("Converged at $(xobs1)") + # check_boundary(θ1) && println("Boundary at $(θ1) with $(xobs1)") + check_boundary(θ1) && continue + θ2,converged = est_theta_em(n2,xobs2) + # converged || println("Failed to converge at $(xobs2)") + converged || continue + # converged && println("Converged at $(xobs2)") + # check_boundary(θ2) && println("Boundary at $(θ2) with $(xobs2)") + check_boundary(θ2) && continue + + # Get binary vector with homozygous CpG sites + z1 = BitArray([p in cpg_pos[1] ? true : false for p in cpg_pos[2]]) + z2 = BitArray([p in cpg_pos[1] ? true : false for p in cpg_pos[3]]) + + # Estimate intermediate quantities + if all(z1) + # In case all are homozygous CpG sites + ∇1 = get_grad_logZ(n1,θ1) + else + # In case NOT all are homozygous CpG sites + ex1 = comp_ex(n1,θ1[1:(end-1)],θ1[end]) + exx1 = comp_exx(n1,θ1[1:(end-1)],θ1[end]) + end + if all(z2) + # In case all are homozygous CpG sites + ∇2 = get_grad_logZ(n2,θ2) + else + # In case NOT all are homozygous CpG sites + ex2 = comp_ex(n2,θ2[1:(end-1)],θ2[end]) + exx2 = comp_exx(n2,θ2[1:(end-1)],θ2[end]) + end + + # Compute output + mml1 = all(z1) ? comp_mml_∇(n1,∇1) : comp_mml(z1,ex1) + mml2 = all(z2) ? comp_mml_∇(n2,∇2) : comp_mml(z2,ex2) + nme1 = all(z1) ? comp_nme_∇(n1,θ1,∇1) : comp_nme(z1,n1,θ1[1:(end-1)],θ1[end],ex1,exx1) + nme2 = all(z2) ? comp_nme_∇(n2,θ2,∇2) : comp_nme(z2,n2,θ2[1:(end-1)],θ2[end],ex2,exx2) + uc = comp_uc(z1,z2,n1,n2,θ1,θ2,nme1,nme2) + + # Report positions based on CpG sites not f_st, f_end + bed_st = minimum(minimum.(cpg_pos)) + bed_end = maximum(maximum.(cpg_pos)) + + # Add statistics to output array + out_sa[i,1] = (bed_st,bed_end,mml1,sum(n),length(n1)) + out_sa[i,2] = (bed_st,bed_end,mml2,sum(n),length(n2)) + out_sa[i,3] = (bed_st,bed_end,nme1,sum(n),length(n1)) + out_sa[i,4] = (bed_st,bed_end,nme2,sum(n),length(n2)) + out_sa[i,5] = (bed_st,bed_end,uc,sum(n),length(n)) + + end + + # Add last to respective bedGraph file + write_tobs(out_sa[:,1],chr,mml1_path) + write_tobs(out_sa[:,2],chr,mml2_path) + write_tobs(out_sa[:,3],chr,nme1_path) + write_tobs(out_sa[:,4],chr,nme2_path) + write_tobs(out_sa[:,5],chr,uc_path) + + end + + # Sort + sort_bedgraphs([mml1_path,mml2_path,nme1_path,nme2_path,uc_path]) + + # Return + return nothing + +end # end comp_tobs +""" + `write_tnull(RECORDS,PATH)` + +Function that writes null records in `RECORDS` into `PATH`. + +# Examples +```julia-repl +julia> write_tnull(RECORDS,PATH) +``` +""" +function write_tnull(recs::Vector{Tuple{Int8,Int8,Float64}},path::String) + + # Open output bedGraph file in append mode (no need to close it) + open(path, "a") do f + for i=1:length(recs) + recs[i][1]!=0 || continue + write(f,join(string.(collect(recs[i])),"\t"),"\n") + end + end + + # Return + return nothing + +end # end write_tnull +""" + `get_kstar_table(GFF_PATH,CHR_NAMES,BLK_SIZE)` + +Function that returns a table with maximum K for each N in GFF_PATH. + +# Examples +```julia-repl +julia> get_kstar_table(GFF_PATH,CHR_NAMES,BLK_SIZE) +``` +""" +function get_kstar_table(gff::String,chr_names::Vector{String},blk_size::Int64)::Dict{Int64,Int64} + + # Loop over chromosomes + table = Dict{Int64,Int64}() + for chr in chr_names + hom_win = read_gff_chr(gff,chr) + # Loop over windows in chromosome + for win in hom_win + # Get window info + win_st = GFF3.seqstart(win) + cpg_pos = get_cpg_pos(Dict(GFF3.attributes(win))) + n = get_ns(cpg_pos[1],blk_size,win_st) + # Update table if necessary + haskey(table,sum(n)) || (table[sum(n)]=length(n)) + length(n)>table[sum(n)] && (table[sum(n)]=length(n)) + end + end + + # Return + return table + +end # end get_kstar_table +""" + `sample_win_n(GFF_PATH,CHR_NAMES,NTOT,MC_NULL)` + +Function that returns a set of size MC_NULL of homozygous genomic windows with at least NTOT CpG +sites. + +# Examples +```julia-repl +julia> sample_win_n(GFF_PATH,CHR_NAMES,NTOT,MC_NULL) +``` +""" +function sample_win_ntot(gff::String,chr_names::Vector{String},ntot::Int64, + mc_null::Int64)::Vector{GFF3.Record} + + # Load genomic features from a GFF3 file + features = open(collect,GFF3.Reader,gff) + + # Filter based on N and chromosomes + filter!(x -> (GFF3.score(x)>=ntot) && (GFF3.seqid(x) in chr_names),features) + + # Return + return features[sample(1:length(features),mc_null;replace=true)] + +end # end sample_win_n +""" + `sample_ntot_cpgs(NTOT,CPG_POS)` + +Function that samples NTOT contiguous CpG sites from CPG_POS. + +# Examples +```julia-repl +julia> sample_ntot_cpgs(4,[10,15,20,25,30,35,40]) +4-element Array{Int64,1}: + 10 + 15 + 20 + 25 +``` +""" +function sample_ntot_cpgs(ntot::Int64,cpg_pos::Vector{Int64})::Vector{Int64} + + # Get start index + st_ind = length(cpg_pos)>ntot ? sample(1:(length(cpg_pos)-(ntot-1))) : 1 + + # Return n + return cpg_pos[st_ind:(st_ind+ntot-1)] + +end # end sample_ntot_cpgs +""" + `get_nvec_kstar(NTOT,KSTAR)` + +Function that returns vector n with Ntot CpG sites divided into Kstar subregions. + +# Examples +```julia-repl +julia> get_nvec_kstar(10,4) +4-element Array{Int64,1}: + 3 + 2 + 2 + 3 +``` +""" +function get_nvec_kstar(ntot::Int64,kstar::Int64)::Vector{Int64} + + # Partition CpG sites into Kstar subregions + n = div(ntot,kstar) * ones(Int64,kstar) + if sum(n)x==i,cpg_ids)) for i=1:kstar] + end + + # Return n + return n + +end # end get_nvec_kstar +""" + `cov_obs_part(XOBS,COV_THS,COV_A,COV_B)` + +Function that partitions observations into two sets of observations that satisfy a minimum +coverage within [COV_THS-COV_A,COV_THS+COV_B]. If not partition is found that satisfies it, +then two empty vectors are returned. + +# Examples +```julia-repl +julia> cov_obs_part(xobs,cov_ths,cov_a,cov_b) +``` +""" +function cov_obs_part(xobs::Vector{Vector{Int64}},cov_ths::Int64,cov_a::Float64, + cov_b::Float64)::Tuple{Vector{Vector{Int64}},Vector{Vector{Int64}}} + + ## Part that takes care of minimum coverage. After this step an allele can have + ## more than cov_ths+b. Here we just guarantee mean_cov(xobsi)≧cov_ths. + + # Divide into two sets of equal size while checking bot have at least cov_ths + ct = 1 + fail = false + xobs1 = Vector{Int64}() + xobs2 = Vector{Int64}() + while true + # Partition + ind = sample(1:length(xobs),div(length(xobs),2),replace=false) + xobs1 = xobs[ind] + xobs2 = xobs[setdiff(1:length(xobs),ind)] + # If coverage okay break loop + (mean_cov(xobs1)>=cov_ths) && (mean_cov(xobs2)>=cov_ths) && break + # Check we haven't exceeded the maximum number of permutations + if ct>20 + # We failed and break + fail=true + break + else + # Increase counter + ct += 1 + end + end + + # Return empty arrays if fail=true + fail==false || return [],[] + # println("First OK: $(mean_cov(xobs1)) & $(mean_cov(xobs2))") + + ## Part extra to limit number of observations used. The goal is to reduce the size of + ## xobs1 & xobs2 until both coverages are within [cov_ths-cov_a,cov_ths+cov_b]. + + # Check for [cov_ths-cov_a,cov_ths+cov_b] for xobs1 + less_ok = false + while true + # Check if we can keep decreasing number + less_ok = mean_cov(xobs1[2:end])>=(cov_ths-cov_a) && mean_cov(xobs1)>=(cov_ths+cov_b) + xobs1 = less_ok ? xobs1=xobs1[2:end] : xobs1 + less_ok || break + end + + # Check if resulting observations meet b-bound as well + fail = mean_cov(xobs1)<=(cov_ths+cov_b) ? false : true + fail==false || return [],[] + # println("Second OK: $(mean_cov(xobs1))") + + # Check for [cov_ths-cov_a,cov_ths+cov_b] for xobs2 + less_ok = false + while true + # Check if we can keep decreasing number + less_ok = mean_cov(xobs2[2:end])>=(cov_ths-cov_a) && mean_cov(xobs2)>=(cov_ths+cov_b) + xobs2 = less_ok ? xobs2=xobs2[2:end] : xobs2 + less_ok || break + end + + # Check if resulting observations meet b-bound as well + fail = mean_cov(xobs2)<=(cov_ths+cov_b) ? false : true + fail==false || return [],[] + # println("Third OK: $(mean_cov(xobs2))") + + # Return partition + return xobs1,xobs2 + +end # end cov_obs_part +""" + `cov_ths_part(BAM_PATH,GFF_PATH,FA_PATH,OUT_PATH)` + +Function that computes null dMMLs, dNME, and UC from a BAM files at locations given by GFF that +contains the windows with not genetic variants and a FASTA file that contains the reference genome. + +# Examples +```julia-repl +julia> comp_tnull(BAM_PATH,GFF_PATH,FA_PATH,OUT_PATH) +``` +""" +function comp_tnull(bam::String,het_gff::String,hom_gff::String,fa::String,out_paths::Vector{String} + ;pe::Bool=true,blk_size::Int64=300,cov_ths::Int64=5,cov_a::Float64=0.0, + cov_b::Float64=1.0,trim::NTuple{4,Int64}=(0,0,0,0),mc_null::Int64=5000, + n_max::Int64=20) + + # BigWig output files + dmml_path,dnme_path,uc_path = out_paths + + # Find relevant chromosomes and sizes + reader_fa = open(FASTA.Reader,fa,index=fa*".fai") + chr_dic = Dict(zip(reader_fa.index.names,reader_fa.index.lengths)) + close(reader_fa) + + # Obtain Kstar for every N & maximum N to analyze + print_log("Generating Kstar table ...") + kstar_table = get_kstar_table(het_gff,collect(keys(chr_dic)),blk_size) + + # Cap Nmax + n_max = min(maximum(keys(kstar_table)),n_max) + + # Loop over Ns of interes + for ntot in keys(kstar_table) + + # Skip if greater than n_max + ntot>n_max && continue + + # Get kstar + kstar = kstar_table[ntot] + + # Print current N + print_log("Generating null statistics for N=$(ntot) with K*=$(kstar) ...") + + # Sample windows with N=ntot + print_log("Sampling $(mc_null) windows ...") + win_ntot = sample_win_ntot(hom_gff,collect(keys(chr_dic)),ntot,5*mc_null) + + # bedGraph records + print_log("Initializing output array ...") + out_sa = SharedArray{Tuple{Int8,Int8,Float64},2}(5*mc_null,3) + filled = SharedArray{Bool,1}(5*mc_null) + + # Produce a set of null statistics for each index + print_log("Computing null statistis ...") + @sync @distributed for i=1:length(win_ntot) + + # Check if enough Tnull have been generated and continue if so + sum(filled)>=mc_null && continue + + # Get homozygous window + feat = win_ntot[i] + chr = GFF3.seqid(feat) + chr_size = chr_dic[chr] + + # Sample ntot contiguous CpG sites and partition into Kstar + cpg_pos = get_cpg_pos(Dict(GFF3.attributes(feat)))[1] + cpg_pos = sample_ntot_cpgs(ntot,cpg_pos) + n = get_nvec_kstar(ntot,kstar) + + # Check average coverage is within normal limits (watch for repetitive regions) + xobs = read_bam(bam,chr,cpg_pos[1],cpg_pos[end],cpg_pos,chr_size,pe,trim) + 2*cov_ths <= mean_cov(xobs) <= 400 || continue + + # Randomly partition observations (sample minimum coverage) + xobs1,xobs2 = cov_obs_part(xobs,cov_ths,cov_a,cov_b) + (length(xobs1)>0) && (length(xobs2)>0) || continue + + # Check MLE exists + length(unique(xobs1))>1 || continue + length(unique(xobs2))>1 || continue + + # Estimate each single-allele model and check if on boundary of parameter space + θ1,converged = est_theta_em(n,xobs1) + # converged || println("Failed to converge at $(xobs1)") + converged || continue + # converged && println("Converged at $(xobs1)") + # check_boundary(θ1) && println("Boundary at $(θ1) with $(xobs1)") + check_boundary(θ1) && continue + θ2,converged = est_theta_em(n,xobs2) + # converged || println("Failed to converge at $(xobs2)") + converged || continue + # converged && println("Converged at $(xobs2)") + # check_boundary(θ2) && println("Boundary at $(θ2) with $(xobs2)") + check_boundary(θ2) && continue + + # Estimate moments + ∇1 = get_grad_logZ(n,θ1) + ∇2 = get_grad_logZ(n,θ2) + + # Estimate output quantities + nme1 = comp_nme_∇(n,θ1,∇1) + nme2 = comp_nme_∇(n,θ2,∇2) + uc = comp_uc(trues(ntot),trues(ntot),n,n,θ1,θ2,nme1,nme2) + + # Store output + out_sa[i,1] = (ntot,kstar,round(abs(comp_mml_∇(n,∇1)-comp_mml_∇(n,∇2));digits=8)) + out_sa[i,2] = (ntot,kstar,round(abs(nme1-nme2);digits=8)) + out_sa[i,3] = (ntot,kstar,uc) + filled[i] = true + + end + + # Add last to respective bedGraph file + write_tnull(out_sa[:,1],dmml_path) + write_tnull(out_sa[:,2],dnme_path) + write_tnull(out_sa[:,3],uc_path) + + end + + # Sort files + sort_bedgraphs([dmml_path,dnme_path,uc_path]) + + # Return nothing + return nothing + +end # end comp_tnull +""" + `comp_pvals_stat(TOBS_PATH,TNULL_PATH,N_MAX)` + +Function that computes adjusted p-values for each haplotype in TOBS_PATH from the empirical +distribution of the pertaining statistic in TNULL_PATH. The output file has the genomic +coordinates, the value of the statistic, and the adjusted p-value. + +# Examples +```julia-repl +julia> comp_pvals_stat(tobs_path,tnull_path) +``` +""" +function comp_pvals_stat(tobs_path::Vector{String},tnull_path::String,p_path::String,n_max::Int64) + + # Get null stats + tnull = readdlm(tnull_path,'\t',Any) + + # Consider case dMML/dNME VS UC + if length(tobs_path)>1 + # dMML/dNME. NOTE: both files need to have the same order of haplotypes! + tobs = readdlm(tobs_path[1],'\t',Any) + tobs[:,4] = abs.(tobs[:,4]-readdlm(tobs_path[2],'\t',Any)[:,4]) + else + # UC + tobs = readdlm(tobs_path[1],'\t',Any) + end + + # Initialize p-value matrix + pvals = tobs[:,1:5] + pvals[:,5] .= "NO DATA" + + # Compute p-values + for i=1:size(tobs)[1] + # Check we can compute p-value + tobs[i,5]<=n_max || continue + # Compute empirical p-value + pvals[i,5] = sum(tnull[tnull[:,1].==tobs[i,5],3].>=tobs[i,4]) / sum(tnull[:,1].==tobs[i,5]) + end + + # Multiple hypothesis testing correction + # NOTE: should we apply BH on each N independently? + pvals[:,5] = MultipleTesting.adjust(convert(Vector{Float64},pvals[:,5]),BenjaminiHochberg()) + + # Write to output + open(p_path,"w") do io + writedlm(io,pvals,'\t') + end + + # Return + return nothing + +end # end comp_pvals_stat +""" + `comp_pvals(TOBS_PATH,TNULL_PATH,PVALS_PATH,N_MAX)` + +Function that computes p-values from empirical null distribution. + +# Examples +```julia-repl +julia> comp_pvals(tobs_path,tnull_path,p_path,n_max) +``` +""" +function comp_pvals(tobs_path::Vector{String},tnull_path::Vector{String},p_path::Vector{String}, + n_max::Int64) + + # Compute three sets of pvalues + print_log("Computing p-values dMML...") + comp_pvals_stat(tobs_path[1:2],tnull_path[1],p_path[1],n_max) + print_log("Computing p-values dNME...") + comp_pvals_stat(tobs_path[3:4],tnull_path[2],p_path[2],n_max) + print_log("Computing p-values UC...") + comp_pvals_stat([tobs_path[5]],tnull_path[3],p_path[3],n_max) + print_log("Done with p-values...") + + # Return + return nothing + +end # end comp_pvals +""" + `run_analysis(BAM1_PATH,BAM2_PATH,BAMU_PATH,VCF_PATH,FA_PATH,OUT_PATH)` + +Function that estimates MML1/2, NME1/2, and NMI on a pair of BAM files (allele 1, allele 2) given a +(phased) VCF file that contains the heterozygous SNPs and a FASTA file that contains the reference +genome. An empirical null distribution for each quantity is estimated from a set of representative +homozygous regions from unassigned BAM records in BAMU_PATH. A p-value is computed for each +haplotype in the VCF file. + +# Examples +```julia-repl +julia> run_analysis(BAM1_PATH,BAM2_PATH,BAMU_PATH,VCF_PATH,FA_PATH,OUT_PATH) +``` +""" +function run_analysis(bam1::String,bam2::String,bamu::String,vcf::String,fa::String,outdir::String; + pe::Bool=true,blk_size::Int64=300,win_exp::Int64=100,cov_ths::Int64=5, + cov_a::Float64=0.0,cov_b::Float64=1.0,trim::NTuple{4,Int64}=(0,0,0,0), + mc_null::Int64=5000,n_max::Int64=25) + + # Print initialization of juliASM + print_log("Starting JuliASM analysis ...") + + # Check index files exist + if !(isfile.(bam1*".bai",bam1*".bai",fa*".fai")) + print_log("Index files for BAM or FASTA missing. Exiting julia ...") + exit(1) + end + + # Create output folder if it doesn't exist + isdir(outdir) || mkdir(outdir) + + # BigWig output files + prefix_sample = String(split(basename(bam1),".")[1]) + tobs_path,tnull_path,p_path = get_outpaths(outdir,prefix_sample) + + # Check for existance of at least an output files + if all(isfile.(vcat(tobs_path,tnull_path))) + print_log("At least an output file already exists. Exiting julia ...") + exit(1) + end + + # Create gff file with heterozygous loci + print_log("Reading in VCF & FASTA files ...") + het_gff = outdir * split(basename(vcf),".")[1] * "_het.juliasm.gff" + hom_gff = outdir * split(basename(vcf),".")[1] * "_hom.juliasm.gff" + if !(isfile(het_gff)) + print_log("Generating JuliASM GFF files ...") + gen_gffs([het_gff,hom_gff],fa,vcf,win_exp,blk_size,n_max) + end + + # Compute observed statistics from heterozygous loci + print_log("Computing observed statistics in heterozygous loci...") + comp_tobs(bam1,bam2,het_gff,fa,tobs_path;pe=pe,blk_size=blk_size,cov_ths=cov_ths,trim=trim) + + # Compute null statistics from homozygous loci + print_log("Generating null statistics in homozygous loci ...") + comp_tnull(bamu,het_gff,hom_gff,fa,tnull_path;pe=pe,blk_size=blk_size,cov_ths=cov_ths, + cov_a=cov_a,cov_b=cov_b,trim=trim,mc_null=mc_null,n_max=n_max) + + # Compute null statistics from heterozygous loci + print_log("Computing p-values in heterozygous loci ...") + comp_pvals(tobs_path,tnull_path,p_path,n_max) + + # Print number of features interrogated and finished message + print_log("Done.") + + # Return + return nothing + +end # end run_analysis diff --git a/src/juliASM_estimation.jl b/src/juliASM_estimation.jl new file mode 100644 index 0000000..a4dedf9 --- /dev/null +++ b/src/juliASM_estimation.jl @@ -0,0 +1,746 @@ +################################################################################################### +# CONSTANTS +################################################################################################### +const ETA_MAX_ABS=5.0 +const CI_THRESH=1.0 +################################################################################################### +# FUNCTIONS +################################################################################################### +""" + `create_Ux([N1,...,NK],[α1,...,αK],β)` + +Function that creates a function to compute potential energy for a region with +[N1,...,NK], parameters [α1,...,αK], and correlation β. + +# Examples +```julia-repl +julia> Ux_fun = JuliASM.create_Ux([2,2],[1.0,1.0],1.0) +julia> Ux_fun([1,1,1,1]) +-7.0 +``` +""" +function create_Ux(n::Vector{Int64},a::Vector{Float64}, b::Float64) + + # Define function given n, α, and β + function Ux(x::Vector{Int64})::Float64 + u = a[1] * sum(x[1:n[1]]) + b * sum(x[1:(end-1)] .* x[2:end]) + @inbounds for i in 2:length(n) + u += a[i] * sum(x[(sum(n[1:(i-1)])+1):(sum(n[1:i]))]) + end + return -u + end + + # Return function + return Ux + +end # end create_Ux +""" + `get_W(N,α,β)` + +Function that returns W^{N-1} computed efficiently via sum of rank-1 matrices +assuming α and β. + +# Examples +```julia-repl +julia> JuliASM.get_W(4,0.0,0.0) +2×2 Array{Int64,2}: + 4 4 + 4 4 +``` +""" +function get_W(n::Int64, a::Float64, b::Float64)::Array{Float64,2} + + # if n=1 then return identity + n==1 && return [1.0 0.0;0.0 1.0] + + # Compute relevant quantities + exp_a = exp(a) + exp_b = exp(b) + cosh_a = 0.5*(exp_a+1.0/exp_a) + sinh_a = exp_a-cosh_a + + # Eigenvalues + aux1 = exp_b * cosh_a + aux2 = sqrt(1.0 + exp_b^4*sinh_a^2) + lambda1N = (aux1-1.0/exp_b*aux2)^(n-1) + lambda2N = (aux1+1.0/exp_b*aux2)^(n-1) + + # Eigenvectors + aux1 = -exp_b^2 * sinh_a + e1 = [aux1-aux2; 1.0] + e1 /= sqrt(e1'*e1) + e2 = [aux1+aux2; 1.0] + e2 /= sqrt(e2'*e2) + + # Return W^{N-1} + return e1*e1'*lambda1N + e2*e2'*lambda2N + +end +""" + `get_V([α1,α2],β)` + +Function that returns V matrix assuming [α1,α2] and β. + +# Examples +```julia-repl +julia> JuliASM.get_V([1.0,1.0],1.0) +``` +""" +function get_V(a::Vector{Float64},b::Float64)::Array{Float64,2} + + # Compute auxiliary vars + exp_b = exp(b) + exp_a_p = exp(0.5*sum(a)) + exp_a_m = exp(0.5*(a[2]-a[1])) + + # Return V + return [exp_b/exp_a_p exp_a_m/exp_b;1.0/(exp_b*exp_a_m) exp_b*exp_a_p] + +end +""" + `get_u(α)` + +Function that boundary vector for Z computation. + +# Examples +```julia-repl +julia> JuliASM.get_u(0.0) +2-element Vector{Float64}: + 1.0 + 1.0 +``` +""" +function get_u(a::Float64)::Vector{Float64} + + # Compute auxiliary + exp_aux = exp(a/2.0) + + # Return u + return [1.0/exp_aux; exp_aux] + +end +""" + `comp_Z([N1,...,NK],[α1,...,αK],β)` + +Compute partition function of a model with [N1,...,NK] CpG cites and with +parameters [α1,...,αK] and β. + +# Examples +```julia-repl +julia> JuliASM.comp_Z([1,1,1],[1.0,1.0,1.0],1.0) +155.37102759254836 +``` +""" +function comp_Z(n::Vector{Int64},a::Vector{Float64},b::Float64)::Float64 + + # Boundary conditions. + y = get_u(a[1])'*get_W(n[1],a[1],b) + if length(n)>1 + y *= prod([get_V(a[(i-1):i],b)*get_W(n[i],a[i],b) for i in 2:length(n)]) + end + y *= get_u(a[end]) + + # Return Z + return max(1e-100,y) + +end +""" + `get_grad_logZ([N1,...,NK],θhat)` + +Computes expected value of sufficient statistis (SS) of a model with [N1,...,NK] CpG cites and +estimated parameter vector θhat, and normalizes it so as to be ∈[0,1]. In other words, vector of +MML where each component is the MML in the respective subregion. + +# Examples +```julia-repl +julia> JuliASM.get_grad_logZ([1,1,1],[1.0,-1.0,1.0,0.0]) +3-element Array{Float64,1}: + 0.8807970779851251 + 0.11920292201487487 + 0.8807970779667909 +``` +""" +function get_grad_logZ(n::Vector{Int64},θhat::Vector{Float64})::Vector{Float64} + + # Define function + function f(θ::Vector{Float64}) + log(comp_Z(n,θ[1:(end-1)],θ[end])) + end + + # Return ∇A(θ) + return Calculus.gradient(f,θhat) + +end +""" + `get_fim([N1,...,NK],θhat)` + +Estimate Fisher information matrix of a model with [N1,...,NK] CpG cites and evaluated at estimated +parameter vector θhat. + +# Examples +```julia-repl +julia> JuliASM.get_fim([1,1,1],[1.0,1.0,1.0,1.0]) +4×4 Array{Float64,2}: + 155.371 148.363 143.026 295.454 + 148.363 155.371 148.363 296.727 + 143.026 148.363 155.371 295.454 + 295.454 296.727 295.454 596.795 +``` +""" +function get_fim(n::Vector{Int64},θhat::Vector{Float64})::Array{Float64,2} + + # Define function + function f(θ::Vector{Float64}) + log(comp_Z(n,θ[1:(end-1)],θ[end])) + end + + # Return I(θ) + return Calculus.hessian(f,θhat) + +end +""" + `keep_region(M,[N1,...,NK],θhat)` + +Function that returns a bool indicating whether model with [N1,...,NK] CpG cites and with parameter +estimate vector θhat, from M observations, should be kept for downstream analysis. + +# Examples +```julia-repl +julia> JuliASM.keep_region(10,[1,1,1],[1.0,1.0,1.0,1.0]) +true +``` +""" +function keep_region(m::Int64,n::Vector{Int64},θhat::Vector{Float64})::Bool + + # Compute FIM considering special case N=1 + fim = sum(n)==1 ? 1-(tanh(θhat[1]))^2 : get_fim(n,θhat) + sum(n)==1 && return 4.0/sqrt(fim*m)<=CI_THRESH + + # Return true if all CIs are below threshold width + return det(fim)!=0 ? all(4*sqrt.(max.(0.0,diag(inv(fim)))/m).<=CI_THRESH) : false + +end +""" + `check_boundary(θhat)` + +Function that returns a bool indicating whether model with parameter estimate vector θhat is on the +boundary of the parameter space in any of its components. + +# Examples +```julia-repl +julia> JuliASM.check_boundary([1.0,1.0,1.0,1.0]) +false +``` +""" +function check_boundary(θhat::Vector{Float64})::Bool + + # Return true θhat on boundary. + return any(isapprox.(abs.(θhat),ETA_MAX_ABS;atol=5e-2)) || any(abs.(θhat).>ETA_MAX_ABS) + +end +""" + `comp_g([R1,...,RK],[α1,...,αK],β,αp1,αp2)` + +Compute scaling factor in a model with [R1,...,RK] unobserved CpG cites from each block, with +parameters [α1,...,αK] and β. The transfer-matrix method is used to obtain a computationally +efficient expression without the need of recursive expressions. αp1 and αp2 are determined by the +respective kind of boundary. + +# Examples +```julia-repl +julia> JuliASM.comp_g([1],[1.0],1.0,3.0,3.0) +20.135323991555527 +``` +""" +function comp_g(r::Vector{Int64},a::Vector{Float64},b::Float64,ap1::Float64,ap2::Float64)::Float64 + + # Return one if r=0 + r==0 && return 1.0 + + # Boundary conditions + y = get_u(ap1)'*get_W(r[1],a[1],b) + if length(r)>1 + y *= prod([get_V(a[(i-1):i],b)*get_W(r[i],a[i],b) for i in 2:length(r)]) + end + y *= get_u(ap2) + + # Return scaling factor + return max(1e-100,y) + +end +""" + `comp_lkhd(X,[N1,...,NK],[α1,...,αK],β)` + +Compute likelihood of a partial/full observation X that can be missing values anywhere (given by +0's). + +# Examples +```julia-repl +julia> JuliASM.comp_lkhd([1,1,0,1,1],[5],[1.0],1.0) +0.953646032691218 +``` +""" +function comp_lkhd(x::Vector{Int64},n::Vector{Int64},a::Vector{Float64},b::Float64)::Float64 + + # Avoid the rest if N=1 + length(x)==1 && return 0.5 * exp(x[1]*a[1]) / cosh(a[1]) + + # Get partition function and energy function + Z = comp_Z(n,a,b) + Ux = create_Ux(n,a,b) + + # Find changes to/from 0 in x vector + zerost = findall(isequal(-1),abs.(x[2:end]) - abs.(x[1:(end-1)])) .+ 1 + zeroend = findall(isequal(1),abs.(x[2:end]) - abs.(x[1:(end-1)])) .+ 1 + + # Determine whether it starts/finishes with 0 + x[1]==0 && pushfirst!(zerost,1) + x[end]==0 && push!(zeroend,length(x)+1) + + # Find subregion label for each CpG site + subid = vcat([i*ones(Int64,n[i]) for i in 1:length(n)]...) + + # Get overall scaling factor as product of individual factors + sf = 1.0 + @inbounds for i in 1:length(zerost) + # Find boundary conditions (other X's or boundary of X) + ap1 = zerost[i]==1 ? a[1] : 2.0*x[zerost[i]-1]*b+a[subid[zerost[i]]] + ap2 = zeroend[i]==sum(n)+1 ? a[end] : 2.0*x[zeroend[i]]*b+a[subid[zeroend[i]-1]] + + # Figure out b (block IDs of missing) and r (α indices) + b_id = subid[zerost[i]:(zeroend[i]-1)] + n_miss = [count(x->x==n,b_id) for n in unique(b_id)] + + # Call scaling factor function + sf *= comp_g(n_miss,a[unique(b_id)],b,ap1,ap2) + + end + + # Return energy function properly scaled. + return exp(-Ux(x)) * sf / Z + +end +""" + `create_Llkhd([N1,...,NK],XOBS)` + +Create function to compute the minus log-likelihood function for a region with N +CpG sites given the M partial observations XOBS. + +# Examples +```julia-repl +julia> n=[2,2] +julia> xobs=JuliASM.gen_ising_full_data(20,n); +julia> LogLike=JuliASM.create_Llkhd(n,xobs) +``` +""" +function create_Llkhd(n::Vector{Int64},xobs::Array{Vector{Int64},1}) + + # Define minus log-likelihood function + function Llkhd_fun(theta::Vector{Float64})::Float64 + # Get parameters + aux = 0.0 + a = theta[1:(end-1)] + b = theta[end] + + # Get energy function and partition function + Ux = create_Ux(n,a,b) + logZ = log(comp_Z(n,a,b)) + + # Initialize variables used in for loop + ap1 = ap2 = 0.0 # Boundary values left and right + b_id = n_miss = [] # Block IDs of missing CpG; number missing per ID + zerost = zeroend = [] # Indices of zeros + subid = vcat([i*ones(Int64,n[i]) for i in 1:length(n)]...) # ID's of CpGs + + # Contribution of each observation + for x in xobs + + # Find changes to/from 0 in x vector + zerost = findall(isequal(-1),abs.(x[2:end]) - abs.(x[1:(end-1)])) .+ 1 + zeroend = findall(isequal(1),abs.(x[2:end]) - abs.(x[1:(end-1)])) .+ 1 + + # Determine whether it starts/finishes with 0 + x[1]==0 && pushfirst!(zerost,1) + x[end]==0 && push!(zeroend,length(x)+1) + + # Get scaling factors due to all missing data + @inbounds for i in 1:length(zerost) + # Find boundary conditions (other X's or boundary of X) + ap1 = zerost[i]==1 ? a[1] : 2.0*x[zerost[i]-1]*b+a[subid[zerost[i]]] + ap2 = zeroend[i]==sum(n)+1 ? a[end] : 2.0*x[zeroend[i]]*b+a[subid[zeroend[i]-1]] + + # Figure out b (block IDs of missing) and r (α indices) + b_id = subid[zerost[i]:(zeroend[i]-1)] + n_miss = [count(x->x==n,b_id) for n in unique(b_id)] + + # Call scaling factor function + aux += log(comp_g(n_miss,a[unique(b_id)],b,ap1,ap2)) + end + + # Add log of it to Llkhd + aux += -Ux(x) + end + + # Return MINUS log-likelihood. Add as many logZ as samples we have + -aux + length(xobs) * logZ + end + + # Return function + return Llkhd_fun + +end # end create_Llkhd +""" + `est_alpha(XOBS)` + +Estimate parameter α for N=1 case. + +# Examples +```julia-repl +julia> Random.seed!(1234); +julia> xobs=JuliASM.gen_ising_full_data(100,1); +julia> JuliASM.est_alpha(xobs) +-0.020002667306849575 +``` +""" +function est_alpha(xobs::Array{Vector{Int64},1})::Vector{Float64} + # Derivation of estimate: + # log(p)+log(2) = α-log(cosh(α)); log(1-p)+log(2) = -α-log(cosh(α)) + # α = (log(p)-log(1-p))/2 + + # Proportion of X=1 + phat = length(findall(x->x==[1],xobs)) / length(xobs) + a = 0.5*(log(phat)-log(1.0-phat)) + + # Return estimate + return [min(max(-ETA_MAX_ABS,a),ETA_MAX_ABS),0.0] + +end # end est_alpha +""" + `est_theta_sa([N1,...,NK],XOBS)` + +Estimate parameter vector η=[α, β] based on full or partial observations using simulated annealing. + +# Examples +```julia-repl +julia> Random.seed!(1234); +julia> n=[4] +julia> xobs=JuliASM.gen_ising_full_data(100,n); +julia> JuliASM.est_theta_sa(n,xobs) +3-element Vector{Float64}: + -0.05232269932606823 + 0.009316690953631898 + -0.047507839311720854 +``` +""" +function est_theta_sa(n::Vector{Int64},xobs::Array{Vector{Int64},1})::Vector{Float64} + + # If N=1, then estimate α + sum(n)==1 && return est_alpha(xobs) + + # Define boundaries and initialization + L = create_Llkhd(n,xobs) + init = zeros(Float64,length(n)+1) + lower = -ETA_MAX_ABS * ones(Float64,length(n)+1) + upper = ETA_MAX_ABS * ones(Float64,length(n)+1) + opts = Optim.Options(iterations=10^6,show_trace=false,store_trace=false) + + # Boxed Simulated Annealing (SAMI) + optim = Optim.optimize(L,lower,upper,init,SAMIN(rt=1e-4;f_tol=1e-3,verbosity=0),opts) + + # Return estimate + return optim.minimizer + +end # end est_theta_sa +""" + `comp_ES(X,[N1,...,N_K],θ)` + +Function that computes expected value of the complete vector of statistics S(W), where W is the +complete methylation state and X is the observed portion of it. +""" +function comp_ES(x::Vector{Int64},n::Vector{Int64},θ::Vector{Float64})::Vector{Float64} + + # Compute marginal of X=x + p_x = comp_lkhd(x,n,θ[1:(end-1)],θ[end]) + + # Compute E[W_n|X;θ] + w = zeros(Int64,length(x)) + E_W_X = zeros(Float64,length(x)) + @inbounds for i=1:length(x) + w[i] = 1 + E_W_X[i] = x[i]==0 ? (2.0*comp_lkhd(x+w,n,θ[1:(end-1)],θ[end])/p_x)-1.0 : x[i] + w[i] = 0 + end + + # Compute E[W_{n}W_{n+1}|X;θ] + w1 = zeros(Int64,length(x)) + w2 = zeros(Int64,length(x)) + E_WW_X = zeros(Float64,length(x)-1) + @inbounds for i=1:(length(x)-1) + if (x[i]!=0)&(x[i+1]!=0) + E_WW_X[i] += x[i]*x[i+1] + continue + end + if (x[i]!=0)&(x[i+1]==0) + E_WW_X[i] += x[i]*E_W_X[i+1] + continue + end + if (x[i]==0)&(x[i+1]!=0) + E_WW_X[i] += E_W_X[i]*x[i+1] + continue + end + if (x[i]==0)&(x[i+1]==0) + w1[i] = -1 + w2[i+1] = -1 + E_WW_X[i] += comp_lkhd(x+w1+w2,n,θ[1:(end-1)],θ[end]) + w1[i] = 1 + w2[i+1] = 1 + E_WW_X[i] += comp_lkhd(x+w1+w2,n,θ[1:(end-1)],θ[end]) + w1[i] = -1 + E_WW_X[i] += -comp_lkhd(x+w1+w2,n,θ[1:(end-1)],θ[end]) + w1[i] = 0 + w2[i+1] = 0 + E_WW_X[i] *= 2.0/p_x + E_WW_X[i] += -1.0 + end + end + + # Get subregion ID for each CpG site + subid = vcat([i*ones(Int64,n[i]) for i in 1:length(n)]...) + + # Initialize with observed part for k=1,...,K + Sout = [sum(E_W_X[subid.==id]) for id in unique(subid)] + + # Append K+1 component + push!(Sout,sum(E_WW_X)) + + # Return vector E[S(W)|X;θ] + return Sout + +end # end comp_ES +""" + `comp_ET(XOBS,[N1,...,N_K],θ)` + +Function that computes expected value of the complete vector of statistics T({W1,...,Wm}), where Wi +is the complete methylation state of the i-th observation and Xi is the observed portion of it. +""" +function comp_ET(xobs::Array{Vector{Int64},1},n::Vector{Int64},θ::Vector{Float64})::Vector{Float64} + + # Return vector E[T({W1,...,Wm})|{X1,...,Xm};θ] + return sum(map(x -> comp_ES(x,n,θ),xobs)) + +end # end comp_ET +""" + `em_alg([N1,...,N_K],XOBS)` + +Function that performs EM algorithm given partial observations in XOBS. + +""" +function em_alg(n::Vector{Int64},xobs::Array{Vector{Int64},1})::Tuple{Vector{Float64},Bool} + + # Check if we have complete data + complete = findfirst(x->any(x.==0),xobs)==nothing + + # Initialize θhat + θhat = rand(Uniform(-1.5,1.5),length(n)+1) + + # Iterate until ||θ-θhat||<ϵ + ϵ = 5e-3 + em_convergence = false + @inbounds for i=1:10 + # (Re)-compute E[T|X1,...,XM;θ^{(i-1)}] + ET = comp_ET(xobs,n,θhat) + # Set up system + function f!(U,θ) + ∇logZ = get_grad_logZ(n,θ) + @inbounds for j=1:(length(n)+1) + U[j] = ∇logZ[j] - ET[j] / length(xobs) + end + end + # Solve NL system + sol = nlsolve(f!,θhat;iterations=20,ftol=1e-3) + # Leave if no convergence + converged(sol) || break + # Check Euclidean distance + em_convergence = complete || (sqrt(sum((sol.zero-θhat).^2)/sum(θhat.^2))<=ϵ) + # Update θhat + θhat = sol.zero + # Break if converged + em_convergence && break + end + + # Return θhat + return (θhat,em_convergence) + +end # end em_alg +""" + `est_theta_em([N1,...,N_K],XOBS)` + +Function that performs EM algorithm given partial observations in XOBS. + +""" +function est_theta_em(n::Vector{Int64},xobs::Array{Vector{Int64},1})::Tuple{Vector{Float64},Bool} + + # If N=1, then estimate α + sum(n)==1 && return (est_alpha(xobs),true) + + # Check if we have complete data + complete = findfirst(x->any(x.==0),xobs)==nothing + + # Initialize + min_LogLike = Inf + convergence = false + LogLike = create_Llkhd(n,xobs) + θhat = zeros(Float64,length(n)+1) + + # Run EM with a number of different initializations + @inbounds for i=1:15 + # EM Algorithm: obtain candidate and convergence flag + θcand,converged = em_alg(n,xobs) + # If did not converge move onto new initialization + converged || continue + # If it converged and minimizes minus log-likelihood, then keep estimate + if LogLike(θcand) Random.seed!(1234); +julia> xobs=JuliASM.gen_mult_full_data(100); +julia> JuliASM.mle_mult(xobs) +16-element Vector{Float64}: + 0.07 + 0.08 + 0.06 + 0.06 + 0.08 + 0.08 + 0.04 + 0.05 + 0.04 + 0.07 + 0.07 + 0.02 + 0.04 + 0.12 + 0.07 + 0.05 +``` +""" +function mle_mult(xobs::Array{Vector{Int64},1})::Vector{Float64} + + # Get xcal + N = size(xobs[1])[1] + xcal = generate_xcal(N) + + # Get empirical estimates + phat = zeros(Float64,2^N) + for x in xobs + phat[findfirst(y-> x==y, xcal)] += 1 + end + phat = phat ./ sum(phat) + + # Return phat + return phat + +end # end mle_mult +""" + `mle_bin_semi(XOBS)` + +Estimate parameter vector `p=[p_1,...,p_{N}]`, based on a binomial model that assumes a different +probability of methylation at each CpG site, from potentially partial observations. This results +in a semi-parametric model that grows in size proportionally to the number of CpG sites. + +# Examples +```julia-repl +julia> Random.seed!(1234); +julia> xobs=JuliASM.gen_mult_full_data(100); +julia> JuliASM.mle_bin_semi(xobs) +``` +""" +function mle_bin_semi(xobs::Array{Vector{Int64},1})::Vector{Float64} + + # Get xcal + N = size(xobs[1])[1] + + # Get empirical estimate + θ = [length(findall(x->x[i]==1,xobs)) / (length(findall(x->x[i]==1,xobs))+ + length(findall(x->x[i]==-1,xobs))) for i in 1:N] + + # Return phat + return θ + +end # end mle_bin_semi +""" + `mle_bin_param(XOBS)` + +Estimate parameter vector `p=[p_1,...,p_{2^N}]` based on a binomial model +that assumes that each CpG site has the same probability of being methylated, +as well as fully observed vectors. This results in a parametric model that does +not grow with the number of CpG sites considered. + +# Examples +```julia-repl +julia> Random.seed!(1234); +julia> xobs=JuliASM.gen_mult_full_data(100); +julia> JuliASM.mle_bin_param(xobs) +16-element Vector{Float64}: + 0.06765201 + 0.06499899 + 0.06499899 + 0.06245000999999999 + 0.06499899 + 0.06245000999999999 + 0.06245000999999999 + 0.06000099 + 0.06499899 + 0.06245000999999999 + 0.06245000999999999 + 0.06000099 + 0.06245000999999999 + 0.06000099 + 0.06000099 + 0.05764800999999999 +``` +""" +function mle_bin_param(xobs::Array{Vector{Int64},1})::Vector{Float64} + + # Get xcal + N = size(xobs[1])[1] + M = length(xobs) + xcal = generate_xcal(N) + + # Get empirical estimates θ=[θ_1,...,θ_N] + θ = sum([length(findall(x->x==1,x)) / N for x in xobs]) / M + + # Compute probabilities of each pattern + i = 1 + phat = zeros(Float64,2^N) + for x in xcal + k = length(findall(y->y==1,x)) + phat[i] = θ^(k) * (1-θ)^(N-k) + i+=1 + end + + # Return phat + return phat #/ sum(phat) + +end # end mle_bin_param diff --git a/src/juliASM_output.jl b/src/juliASM_output.jl new file mode 100644 index 0000000..e7b367a --- /dev/null +++ b/src/juliASM_output.jl @@ -0,0 +1,683 @@ +################################################################################################### +# CONSTANTS +################################################################################################### +const LOG2 = log(2) # Ln(2) +const XCAL1 = [-1,1] # 𝒳 with N=1 +const XCAL2 = [[-1,-1],[-1,1],[1,-1],[1,1]] # 𝒳 with N=2 +################################################################################################### +# STRUCTS +################################################################################################### +mutable struct IntBitVec <: AbstractVector{Bool} + data::UInt64 +end +Base.size(::IntBitVec) = (64,) +@inline function Base.getindex(v::IntBitVec,i::Int) + @boundscheck checkbounds(v, i) + v.data & (1 << (i-1)) != 0 +end +################################################################################################### +# USED FUNCTIONS +################################################################################################### +""" +`comp_ex([N1,...,NK],[α1,...,αK],β)` + +Function that computes the mean methylation vector E[X] assuming the Ising model for a methylation +state vector of size `[N1,...,NK]` and parameters `[α1,...,αK]` and `β`. + +# Examples +```julia-repl +julia> JuliASM.comp_ex([4],[0.0],0.0) +4-element Array{Float64,1}: +0.5 +0.5 +0.5 +0.5 +``` +""" +function comp_ex(n::Vector{Int64},a::Vector{Float64},b::Float64)::Vector{Float64} + + # Loop over all positions + x = zeros(Int64,sum(n)) + y = zeros(Float64,sum(n)) + @inbounds for j in 1:sum(n) + x[j] = 1 + y[j] = comp_lkhd(x,n,a,b) + x[j] = 0 + end + + # Return + return 2*y.-1 + +end # end comp_ex +""" +`comp_exx([N1,...,NK],[α1,...,αK],β;r=1)` + +Function that computes mean methylation vector E[X_{i}X_{i+r}}] assuming the Ising model for a +methylation state vector of size `[N1,...,NK]` and parameters `[α1,...,αK]` and `β`. + +# Examples +```julia-repl +julia> JuliASM.comp_exx([4],[0.0],0.0) +3-element Array{Float64,1}: + 0.0 + 2.220446049250313e-16 + 0.0 +``` +""" +function comp_exx(n::Vector{Int64},a::Vector{Float64},b::Float64;r::Int64=1)::Vector{Float64} + + # Loop over all positions + x = zeros(Int64,sum(n)) + y = zeros(Float64,sum(n)-r) + @inbounds for j in 1:(sum(n)-r) + x[j] = x[j+r] = 1 + y[j] = comp_lkhd(x,n,a,b) + comp_lkhd(-x,n,a,b) + x[j] = x[j+r] = 0 + end + + # Return + return 2*y.-1 + +end # end comp_exx +""" + `comp_mml(Z,EX)` + +Function that computes mean methylation level (MML) given at the CpG sites marked by binary vector +Z and given first order moment E[X] vector. This function is only used when not all CpG sites are +homozygous since it can compute MML over a subset of CpG sites. + +# Examples +```julia-repl +julia> ex=JuliASM.comp_ex([4],[0.0],0.0); JuliASM.comp_mml(trues(4),ex) +0.5 +``` +""" +function comp_mml(z::BitArray{1},ex::Vector{Float64})::Float64 + + # Return + return abs(round(0.5/length(ex[z])*sum(ex[z])+0.5;digits=8)) + +end # end comp_mml +""" + `comp_mml_∇([N1,...,NK],∇logZ)` + +Function that computes mean methylation level (MML) over the entire haplotype. This function takes +advantage of the fact that E[S(X)]=Adot(θ), and it's much faster than `comp_mml`. This function is +only used when all CpG sites are homozygous. + +# Examples +```julia-repl +julia> n=[1,1,1]; θ=[1.0,-1.0,1.0,0.0]; +julia> ∇logZ = JuliASM.get_grad_logZ(n,θ); +julia> JuliASM.comp_mml_∇(n,∇logZ) +0.66584246 +``` +""" +function comp_mml_∇(n::Vector{Int64},∇logZ::Vector{Float64})::Float64 + + # Return + return abs(round(0.5*(1.0+1.0/sum(n)*sum(∇logZ[1:length(n)]));digits=8)) + +end # end comp_mml_∇ +""" + `comp_exlng(Z,[N1,...,NK],[α1,...,αK],β)` + +Function that returns the third summand in the normalized methylation entropy (NME) defined +for the homozygous CpG sites, with positions determined by binary vector Z, assuming an +allele-specific vector with [N1,...,NK] CpG sites, with parameters [α1,...,αK] and β. + +# Examples +```julia-repl +julia> n=[10] +julia> z=trues(10);z[5]=false +julia> a=[0.0] +julia> b=0.0 +julia> JuliASM.comp_exlng(z,n,a,b) +0.6931471805599452 +``` +""" +function comp_exlng(z::BitArray{1},n::Vector{Int64},a::Vector{Float64},b::Float64)::Float64 + + # Find changes to/from 0 in x vector + hetst = findall(isequal(-1),abs.(z[2:end]) - abs.(z[1:(end-1)])) .+ 1 + hetend = findall(isequal(1),abs.(z[2:end]) - abs.(z[1:(end-1)])) .+ 1 + + # Determine whether it starts/finishes with true/false + z[1]==false && pushfirst!(hetst,1) + z[end]==false && push!(hetend,sum(n)+1) + + # Find subregion label for each CpG site + subid = vcat([i*ones(Int64,n[i]) for i in 1:length(n)]...) + + # Loop over heterozygous stretches + y = 0.0 + @inbounds for i=1:length(hetst) + + # Choose 𝒳 depending on boundary or not + bound = hetst[i]==1 || hetend[i]==sum(n)+1 ? true : false + xcal = bound ? XCAL1 : XCAL2 + + # Figure out b (block IDs of heterozygous) and r (α indices) + bid = subid[hetst[i]:(hetend[i]-1)] + nhet = [count(x->x==id,bid) for id in unique(bid)] + + # Compute expectation + for x in xcal + + # Find αp1 and αp2 + xaug = zeros(Int64,sum(n)) + if bound + # If heterozygous CpG on boundary of X + hetst[i]==1 ? xaug[hetend[i]]+=x : xaug[hetst[i]-1]+=x + ap1 = hetst[i]==1 ? a[1] : 2.0*x*b+a[subid[hetst[i]]] + ap2 = hetend[i]==sum(n)+1 ? a[end] : 2.0*x*b+a[subid[hetend[i]-1]] + else + # If heterozygous CpG not on boundary of X + xaug[[hetst[i]-1,hetend[i]]]+=x + ap1 = 2.0*x[1]*b+a[subid[hetst[i]]] + ap2 = 2.0*x[2]*b+a[subid[hetend[i]-1]] + end + + # Add contribution to total sum of expectations + y += log(comp_g(nhet,a[unique(bid)],b,ap1,ap2))*comp_lkhd(xaug,n,a,b) + + end + + end + + # Return sum of all expectations + return y + +end # end comp_exlng +""" + `comp_nme(Z,[N1,...,NK],[α1,...,αK],β,EX,EXX)` + +Function that computes normalized methylation entropy (NME) over the CpG sites determined by binary +vector Z. This is done by assuming an Ising model for the allele-specific methylation state vector +of size `[N1,...,NK]`, parameters `[α1,...,αK]` and `β`. This function is used when not all CpG +sites are homozygous since it can compute NME over a subset of CpG sites. + +# Examples +```julia-repl +julia> n=[10];z=trues(sum(n));z[5]=false;a=[0.0];b=0.0;θ=vcat([a,b]...); +julia> JuliASM.comp_nme(z,n,a,b,JuliASM.comp_ex(n,a,b),JuliASM.comp_exx(n,a,b)) +1.0 +``` +""" +function comp_nme(z::BitArray{1},n::Vector{Int64},a::Vector{Float64},b::Float64,ex::Vector{Float64}, + exx::Vector{Float64})::Float64 + + # Define output quantity + h = 0.0 + + # Vector of α for homozygous + avec = vcat([a[i]*ones(Float64,n[i]) for i in 1:length(n)]...)[z] + + # 1st term (log partition function) + h += log(comp_Z(n,a,b)) + + # 2nd term (average potential energy over homozygous CpG sites) + h -= avec'*ex[z]+b*sum(exx[z[1:(end-1)].*z[2:end]]) + + # 3rd term if necessary + h -= all(z) ? 0.0 : comp_exlng(z,n,a,b) + + # Return nme + return abs(round(h/(sum(z)*LOG2);digits=8)) + +end # end comp_nme +""" + `comp_nme_∇([N1,...,NK],θ,∇logZ)` + +Function that computes normalized methylation entropy (NME) using the ∇logZ information. This +function can only be used in `comp_tnull` since it does not allow computation on a subset of CpG +sites. This function is only used when all CpG sites are homozygous. + +# Examples +```julia-repl +julia> n=[4]; a=[0.0]; b=0.0; θ=vcat([a,b]...); ∇logZ=JuliASM.get_grad_logZ(n,θ); +julia> JuliASM.comp_nme_∇(n,θ,∇logZ) +1.0 +``` +""" +function comp_nme_∇(n::Vector{Int64},θ::Vector{Float64},∇logZ::Vector{Float64})::Float64 + + # Return + return abs(round(1.0/(sum(n)*LOG2)*(log(comp_Z(n,θ[1:(end-1)],θ[end]))-θ'*∇logZ);digits=8)) + +end # end comp_nme_∇ +""" + `gen_x_mc(N,α,β)` + +Function that generates a methylation vector from an Ising model with `[N1,...,NK]`, and parameters +`[α1,...,αK]` and `β`. + +# Examples +```julia-repl +julia> JuliASM.gen_x_mc([5],[0.0],0.0) +``` +""" +function gen_x_mc(n::Vector{Int64},a::Vector{Float64},b::Float64)::Vector{Int64} + + # Find subregion label for each CpG site + subid = vcat([i*ones(Int64,n[i]) for i in 1:length(n)]...) + + # Sample first CpG site + x = Vector{Int64}() + p = comp_lkhd(pushfirst!(zeros(Int64,sum(n)-1),1),n,a,b) + push!(x,sample(XCAL1,Weights([1-p,p]))) + sum(n)>1 || return x + + # Sequentially sample from Markov chain + @inbounds for i=2:sum(n) + + # Add boundary function g() if necessary + expaux = exp(a[subid[i]]+b*x[i-1]) + if i < sum(n) + ap1p = 2.0*b + a[subid[i]] + ap1m = -2.0*b + a[subid[i]] + n_miss = [count(x->x==sr,subid[(i+1):sum(n)]) for sr in unique(subid[(i+1):sum(n)])] + gp = comp_g(n_miss,a[unique(subid[(i+1):sum(n)])],b,ap1p,a[end]) + gm = comp_g(n_miss,a[unique(subid[(i+1):sum(n)])],b,ap1m,a[end]) + p = gp*expaux/(gp*expaux+gm/expaux) + else + p = expaux/(expaux+1.0/expaux) + end + + # Add i-th CpG site + push!(x,sample(XCAL1,Weights([1-p,p]))) + + end + + # Return methylation vector + return x + +end # end gen_x_mc +""" + `comp_nme_mix_mc(Z1,Z2,N1,N2,theta1,theta2)` + +Function that estimates the entropy for the Ising mixture model using Monte Carlo. This is done +assuming an Ising model for the allele-specific methylation state vector of size `[N1,...,NK]`, +parameters `[α1,...,αK]` and `β`, for each allele. The homozygous part of each model is determined +by binary vector Z (i.e., via Hadamard product Z*X, where * is the Hadamard product). + +# Examples +```julia-repl +julia> n1=[10]; n2=[10]; +julia> z1=trues(sum(n1)); z2=trues(sum(n2)); +julia> a1=[2.0]; b1=1.0; a2=[-2.0]; b2=1.0; +julia> JuliASM.comp_nme_mix_mc(z1,z2,n1,n2,vcat(a1,b1),vcat(a2,b2)) +0.0 +``` +""" +function comp_nme_mix_mc(z1::BitArray{1},z2::BitArray{1},n1::Vector{Int64},n2::Vector{Int64}, + t1::Vector{Float64},t2::Vector{Float64};L::Int64=1000)::Float64 + + # For loop to sample from mixture + h = 0.0 + @inbounds for i=1:L + + # Sample allele + y = sample(1:2,Weights([0.5,0.5])) + + # Sample x given allele + x = y==1 ? gen_x_mc(n1,t1[1:(end-1)],t1[end]) : gen_x_mc(n2,t2[1:(end-1)],t2[end]) + x0 = y==1 ? x[z1] : x[z2] + + # Add contribution + x1 = zeros(Int64,sum(n1)) + x2 = zeros(Int64,sum(n2)) + x1[z1] = x0 + x2[z2] = x0 + h += log(comp_lkhd(x1,n1,t1[1:(end-1)],t1[end])+comp_lkhd(x2,n2,t2[1:(end-1)],t2[end])) + + end + + # Return + return min(1.0,max(0.0,1.0/sum(z1)*(1.0-h/(L*LOG2)))) + +end # end comp_nme_mix_mc +""" + `comp_nme_mix_exact(Z1,Z2,N1,N2,theta1,theta2)` + +Function that exactly computes the NME for the Ising mixture model. This is done by assuming an +Ising model for the allele-specific methylation state vector of size `[N1,...,NK]`, parameters +`[α1,...,αK]` and `β`. The homozygous part of the allele-specific vector is determined by binary +vector Z (i.e., via Hadamard product Z*X, where * is the Hadamard product). This is done by +traversing 𝒳h. + +# Examples +```julia-repl +julia> n1=[10]; n2=[10]; +julia> z1=trues(sum(n1)); z2=trues(sum(n2)); +julia> a1=[2.0]; b1=1.0; a2=[-2.0]; b2=1.0; +julia> JuliASM.comp_nme_mix_exact(z1,z2,n1,n2,vcat(a1,b1),vcat(a2,b2)) +0.1087021260719882 +``` +""" +function comp_nme_mix_exact(z1::BitArray{1},z2::BitArray{1},n1::Vector{Int64},n2::Vector{Int64}, + t1::Vector{Float64},t2::Vector{Float64})::Float64 + + # Loop over 𝒳h + h = 0.0 + n = sum(z1) + w1 = zeros(Int64,sum(n1)) + w2 = zeros(Int64,sum(n2)) + @inbounds for i=1:(2^n) + z = IntBitVec(i)[1:n] + x = -ones(Int64,n) + x[z] .= 1 + w1[z1] =+ x + w2[z2] =+ x + lkhd1 = comp_lkhd(w1,n1,t1[1:(end-1)],t1[end]) + lkhd2 = comp_lkhd(w2,n2,t2[1:(end-1)],t2[end]) + h += (lkhd1+lkhd2) * log(lkhd1+lkhd2) + w1[z1] =- x + w2[z2] =- x + end + + # Return + return min(1.0,max(0.0,1.0/n*(1.0-0.5*h/LOG2))) + +end # end comp_nme_mix_exact +""" + `comp_uc(Z1,Z2,N1,N2,theta1,theta2,h1,h2)` + +Function that exactly computes uncertainty coefficient (UC) over the homozygous CpG sites. This is +done by assuming an Ising model for the allele-specific methylation state vector of size +`[N1,...,NK]`, parameters `[α1,...,αK]` and `β`. The homozygous part of the allele-specific vector +is determined by binary vector Z (i.e., via Hadamard product Z*X, where * is the Hadamard product). + +# Examples +```julia-repl +julia> n1=[10]; n2=[10] +julia> z1=trues(sum(n1)); z2=trues(sum(n2)) +julia> a1=[2.0]; a2=[-2.0]; b1=0.0; b2=0.0 +julia> h1=JuliASM.comp_nme(z1,n1,a1,b1,JuliASM.comp_ex(n1,a1,b1),JuliASM.comp_exx(n1,a1,b1)) +julia> h2=JuliASM.comp_nme(z2,n2,a2,b2,JuliASM.comp_ex(n2,a2,b2),JuliASM.comp_exx(n2,a2,b2)) +julia> JuliASM.comp_uc(z1,z2,n1,n2,vcat(a1,b1),vcat(a2,b2),h1,h2) +1.0 +``` +""" +function comp_uc(z1::BitArray{1},z2::BitArray{1},n1::Vector{Int64},n2::Vector{Int64}, + t1::Vector{Float64},t2::Vector{Float64},h1::Float64,h2::Float64)::Float64 + + # Compute h(x) + h = sum(z1)<17 ? comp_nme_mix_exact(z1,z2,n1,n2,t1,t2) : comp_nme_mix_mc(z1,z2,n1,n2,t1,t2) + + # Return + return round(min(1.0,max(0.0,1.0-0.5*(h1+h2)/h));digits=8) + +end # end comp_uc +################################################################################################### +# DEV FUNCTIONS +################################################################################################### +""" + `comp_mmlv([N1,...,NK],∇logZ)` + +Function that computes the mean methylation level vector (MMLV) for each subregion. Reporting +output for subregion might be more informative than just an overall mean. This function takes +advantage of the fact that E[S(X)]=Adot(θ), which is much faster than computing first moment +and correlations as currently done. + +# Examples +```julia-repl +julia> n=[1,1,1]; θ=[1.0,-1.0,1.0,0.0]; +julia> ∇logZ = JuliASM.get_grad_logZ(n,θ); +julia> JuliASM.comp_mmlv(n,∇logZ) +3-element Array{Float64,1}: + 0.88079708 + 0.11920292 + 0.88079708 +``` +""" +function comp_mmlv(n::Vector{Int64},∇logZ::Vector{Float64})::Vector{Float64} + + # Return + return abs.(round.(0.5.*(1.0./n.*∇logZ[1:length(n)].+1.0);digits=8)) + +end # end comp_mmlv +""" + `comp_corr(EX,EXX)` + +Function that returns the correlation vector between consecutive CpG sites given the vector of +first order moments E[X] and second order moments E[XX]. + +# Examples +```julia-repl +julia> JuliASM.comp_corr(JuliASM.comp_ex([4],[0.0],0.0),JuliASM.comp_exx([4],[0.0],0.0)) +3-element Array{Float64,1}: + 0.0 + 8.881784197001252e-16 + 0.0 +``` +""" +function comp_corr(ex::Vector{Float64},exx::Vector{Float64})::Vector{Float64} + + # Initialize vector of 1's + ov = ones(Float64,length(ex)-1) + + # Return ρ + return round.((exx.-ex[1:(end-1)].*ex[2:end]) ./ sqrt.((ov.-ex[1:(end-1)].^2) .* + (ov.-ex[2:end].^2));digits=8) + +end # end comp_corr +""" + `comp_cov([N1,...,NK],[α1,...,αK],β,EX,EXX)` + +Function that returns the covariance matrix of a methylation vector given the `[N1,...,NK]`, +`[α1,...,αK]`, `β`, E[X], and E[XX]. + +# Examples +```julia-repl +julia> ex = JuliASM.comp_ex([4],[0.0],0.0) +julia> exx = JuliASM.comp_exx([4],[0.0],0.0) +julia> JuliASM.comp_cov([4],[0.0],0.0,ex,exx) +4×4 Array{Float64,2}: + 1.0 0.0 2.22045e-16 0.0 + 0.0 1.0 2.22045e-16 2.22045e-16 + 2.22045e-16 2.22045e-16 1.0 0.0 + 0.0 2.22045e-16 0.0 1.0 +``` +""" +function comp_cov(n::Vector{Int64},a::Vector{Float64},b::Float64,ex::Vector{Float64}, + exx::Vector{Float64})::Array{Float64,2} + + # Initialize matrix + ntot = sum(n) + cov = zeros(Float64,ntot,ntot) + + # Add first subdiagonal E[X_{i}X_{i+1}] + cov[2:(ntot+1):((ntot-1)*ntot)] = exx + + # Add covariance terms E[X_{i}X_{i+k-1}] + @inbounds for k=3:ntot + cov[k:(ntot+1):((ntot-k+1)*ntot)] = comp_exx(n,a,b;r=k-1) + end + + # Symmetrize + cov += transpose(cov) + + # Substract E[X_i]E[X_j] + cov -= ex * ex' + + # Add 1's to diagonal of matrix + cov[1:(ntot+1):ntot^2] += ones(Float64,ntot) + + # Return Σ + return cov + +end # end comp_cov +""" + `comp_evec(Σ)` + +Function that returns the eigenvector associated with the largest eigenvalue of the covariance +matrix Σ. + +# Examples +```julia-repl +julia> ex = JuliASM.comp_ex([4],[0.0],0.0); +julia> exx = JuliASM.comp_exx([4],[0.0],0.0); +julia> cov = JuliASM.comp_cov([4],[0.0],0.0,ex,exx); +julia> JuliASM.comp_evec(cov) +4-element Array{Float64,1}: + 0.0 + 0.0 + 0.0 + 1.0 +``` +""" +function comp_evec(cov::Array{Float64,2})::Vector{Float64} + + # Return evec + return abs.(eigvecs(cov)[:,size(cov)[1]]) + +end # end comp_evec +################################################################################################### +# VERIFICATION FUNCTIONS (UNUSED) +################################################################################################### +# """ +# `comp_Z_xcal([N1,...,NK],[α1,...,αK],β)` +# +# Function that computes the partition function computed recursively over 𝒳. +# +# # Examples +# ```julia-repl +# julia> n=[4]; a=[0.0]; b=0.0; +# julia> JuliASM.comp_Z_xcal(n,a,b) +# 16.0 +# ``` +# """ +# function comp_Z_xcal(n::Vector{Int64},a::Vector{Float64},b::Float64)::Float64 +# +# # Loop over 𝒳h +# Z = 0.0 +# xcal = generate_xcal(sum(n)) +# @inbounds for x in xcal +# Z += exp(-) +# end +# +# # Return +# return Z +# +# end # end comp_Z_xcal +""" + `comp_nme_xcal(Z,[N1,...,NK],[α1,...,αK],β,EX,EXX)` + +Function that computes normalized methylation entropy (NME) over the homozygous CpG sites. This is +done by assuming an Ising model for the allele-specific methylation state vector of size +`[N1,...,NK]`, parameters `[α1,...,αK]` and `β`. The homozygous part of the allele-specific vector +is determined by binary vector Z (i.e., via Hadamard product Z*X, where * is the Hadamard product). + +# Examples +```julia-repl +julia> n=[10]; z=trues(sum(n)); a=[0.0]; b=0.0; +julia> JuliASM.comp_nme_xcal(z,n,a,b) +1.0 +``` +""" +function comp_nme_xcal(z::BitArray{1},n::Vector{Int64},a::Vector{Float64},b::Float64)::Float64 + + # Loop over 𝒳h + h = 0.0 + w = zeros(Int64,sum(n)) + hom_ind = findall(y->y==true,z) + xcal = generate_xcal(length(hom_ind)) + @inbounds for x in xcal + w[hom_ind] =+ x + lkhd = comp_lkhd(w,n,a,b) + h += lkhd * log(lkhd) + w[hom_ind] =- x + end + + # Return + return round(-h/(sum(z)*LOG2);digits=8) + +end # end comp_nme_xcal +""" + `comp_uc_xcal(Z1,Z2,N1,N2,theta1,theta2)` + +Function that exactly computes uncertainty coefficient (UC) over the homozygous CpG sites. This is +done by assuming an Ising model for the allele-specific methylation state vector of size +`[N1,...,NK]`, parameters `[α1,...,αK]` and `β`. The homozygous part of the allele-specific vector +is determined by binary vector Z (i.e., via Hadamard product Z*X, where * is the Hadamard product). + +# Examples +```julia-repl +julia> n1=[10]; n2=[10] +julia> z1=trues(sum(n1)); z2=trues(sum(n2)) +julia> theta1=[2.0,0.0]; theta2=[-2.0,0.0] +julia> JuliASM.comp_uc_xcal(z1,z2,n1,n2,theta1,theta2) +1.0 +``` +""" +function comp_uc_xcal(z1::BitArray{1},z2::BitArray{1},n1::Vector{Int64},n2::Vector{Int64}, + theta1::Vector{Float64},theta2::Vector{Float64})::Float64 + + # Loop over 𝒳h + num = 0.0 + den = 0.0 + n = sum(z1) + w1 = zeros(Int64,sum(n1)) + w2 = zeros(Int64,sum(n2)) + hom_ind_1 = findall(y->y==true,z1) + hom_ind_2 = findall(y->y==true,z2) + @inbounds for i=1:(2^n) + z = IntBitVec(i)[1:n] + x = -ones(Int64,n) + x[z] .= 1 + w1[hom_ind_1] =+ x + w2[hom_ind_2] =+ x + lkhd1 = comp_lkhd(w1,n1,theta1[1:(end-1)],theta1[end]) + lkhd2 = comp_lkhd(w2,n2,theta2[1:(end-1)],theta2[end]) + lkhd0 = 0.5*(lkhd1+lkhd2) + den += lkhd0 * log(lkhd0) + num += lkhd1 * log(lkhd1) + lkhd2 * log(lkhd2) + w1[hom_ind_1] =- x + w2[hom_ind_2] =- x + end + + # Return + return 1-0.5*num/den + +end # end comp_uc_xcal +################################################################################################### +# COMPETING MODELS +################################################################################################### +""" + `comp_lkhd_bin(XOBS,θ)` + +Function that returns likelihood vector of XOBS, potentially partial, given parameter vector θ for +the non-parametric independent model (binomial). + +# Examples +```julia-repl +julia> +``` +""" +function comp_lkhd_bin(xobs::Array{Vector{Int64},1},θ::Vector{Float64})::Vector{Float64} + + # Return evec + return [prod(θ.^(x.==1) .* (ones(length(xobs[1]))-θ).^(x.==-1)) for x in xobs] + +end # end comp_lkhd_bin +""" + `comp_lkhd_mult(XOBS,θ)` + +Function that returns likelihood vector of XOBS, assuming full data, given parameter vector θ for +the non-parametric dependent model (multinomial). + +# Examples +```julia-repl +julia> +``` +""" +function comp_lkhd_mult(xobs::Array{Vector{Int64},1},θ::Vector{Float64})::Vector{Float64} + + # Generate 𝒳 + xcal = generate_xcal(length(xobs[1])) + + # Return evec + return θ[[findfirst(y->y==x,xcal) for x in xobs]] + +end # end comp_lkhd_mult diff --git a/src/juliASM_plots.jl b/src/juliASM_plots.jl new file mode 100644 index 0000000..1272be5 --- /dev/null +++ b/src/juliASM_plots.jl @@ -0,0 +1,71 @@ +################################################################################################### +# FUNCTIONS +################################################################################################### +""" + `plot_histogram(X, LABELS)` + +Function to generate an overlayed histogram of vectors X[1], X[2], .... + +# Examples +```julia-repl +julia>p=JuliASM.plot_histogram(x, labels) +``` +""" +function plot_histogram(x, labels; xlabel=L"Value",ylabel=L"Frequency") + + xmin = 0.9 * minimum(reduce(vcat,x)) + xmax = 1.1 * maximum(reduce(vcat,x)) + # x_colors = [:blue :red :green :orange :pink :] + # x_colors = x_colors[1:length(labels)] + p = histogram(x, label=labels, normalize=true, line=(1,0.2), xlabel=xlabel, + ylabel=ylabel, fillcolor=:match, fillalpha=0.25, xlims=(xmin,xmax), + xtickfont=font(6, "Arial"), nbins=range(xmin,xmax,length=25) + # title=title, titlefontsize=12, + ) + return p + +end # end plot_histogram +""" + `plot_heatmap(X,η)` + +Function to generate an heatmap of log-likelihood function for a gixen +observation vector x with true parameter being η. + +# Examples +```julia-repl +julia>p=JuliASM.plot_heatmap(x,eta) +``` +""" +function plot_heatmap(x::Array{Vector{Int64},1},eta::Vector{Float64}; maxVal=4.0) + + # Ranges + par1=-maxVal:0.1:maxVal + par2=-maxVal:1:maxVal + + # Create (minus) log-likelihood function + Loglike = JuliASM.create_Llkhd(x) + + # Matrix of (minus) log-likelihood values + minY = Inf + min_ij = [NaN,NaN] + Y = zeros(Float64, length(par1), length(par1)) + for i in 1:length(par1), j in 1:length(par1) + Y[i,j] = Loglike([par1[i],par1[j]]) + if Y[i,j] xcal=JuliASM.generate_xcal(2) +4-element Array{Vector{Int64},1}: + [-1, -1] + [1, -1] + [-1, 1] + [1, 1] +``` +""" +function generate_xcal(n::Int64)::Array{Vector{Int64},1} + + # Generate iterative object + xcal = Vector{Int64}[] + [push!(xcal,2 .* digits(i, base=2, pad=n) - ones(n)) for i in 0:(2^n-1)] + + # Return 𝒳 + return xcal + +end # end generate_xcal +""" + `gen_ising_full_data(M,N;α,β)` + +Generate M FULLY observed reads with [N1,...,NK] CpG sites from energy function +U(X) parametrized by [α1,...,αK] and β. + +# Examples +```julia-repl +julia> Random.seed!(1234); +julia> xobs=JuliASM.gen_ising_full_data(10,4); +10-element Array{Vector{Int64},1}: + [-1, -1, -1, -1] + [1, -1, -1, -1] + [-1, 1, -1, -1] + [-1, -1, 1, -1] + [1, -1, 1, -1] + [1, -1, -1, 1] + [-1, 1, -1, 1] + [1, -1, 1, 1] + [1, -1, 1, 1] + [-1, 1, 1, 1] +``` +""" +function gen_ising_full_data(m::Int64,n::Vector{Int64};a=zeros(length(n)), + b=0.0)::Array{Vector{Int64},1} + + # Generate iterative object + xcal = generate_xcal(sum(n)) + + # Create function for energy computation + Ux_fun = create_Ux(n,a,b) + + # Compute probability over state space + p = zeros(2^sum(n)) + p = [exp(-Ux_fun(xcal[k])) for k in 1:length(xcal)] + p = p ./ sum(p) + + # Sample full observations from model + indices = rand(Distributions.Multinomial(m, p)) + indices = vcat([repeat([i],indices[i]) for i in 1:length(indices)]...) + + # Return observations + return xcal[indices] + +end # end gen_ising_full_data +""" + `gen_ising_part_data(M,N;α,β)` + +Generate M partially observed reads with [N1,...,NK] CpG sites from energy +function U(X) parametrized by [α1,...,αK] and β. The values code for: +1: Methylated CpG site. +-1: Unmethylated CpG site. +0: Unobserved CpG site. + +# Examples +```julia-repl +julia> Random.seed!(1234); +julia> xobs=gen_ising_part_data(10,[4]) +10-element Array{Vector{Int64},1}: +[-1, -1, -1, -1] +[1, -1, -1, -1] +[-1, 1, -1, -1] +[-1, -1, 1, -1] +[1, -1, 1, -1] +[1, -1, -1, 1] +[0, 1, -1, 1] +[1, -1, 1, 1] +[1, -1, 1, 1] +[-1, 1, 1, 1] +``` +""" +function gen_ising_part_data(m::Int64,n::Vector{Int64};a=zeros(length(n)), + b=0.0)::Array{Vector{Int64},1} + + # Get full data + full_data = gen_ising_full_data(m,n;a=a,b=b) + + # Add missing values on sides + missleft = rand(Distributions.Binomial(sum(n), 0.01),m) + missright = rand(Distributions.Binomial(sum(n), 0.01),m) + for i in 1:m + full_data[i][1:missleft[i]] = fill(0, missleft[i]) + full_data[i][(sum(n)-missright[i]+1):end] = fill(0, missright[i]) + end + + # Return partial observations + return full_data + +end # end gen_ising_part_data +""" + `gen_mult_full_data(M;N,p)` + +Generate M FULLY observed reads from a multinomial model with vector of +probabilities `p=[p_1,...,p_{2^N}]`. + +# Examples +```julia-repl +julia> Random.seed!(1234); +julia> xobs=gen_mult_full_data(2); +[-1, -1, 1, -1] +[1, -1, 1, -1] +``` +""" +function gen_mult_full_data(m::Int64;n=4,p=1.0/(2.0^n)*ones(2^n))::Array{Vector{Int64},1} + + # Generate iterative object + xcal = generate_xcal(n) + + # Sample full observations from model + indices = rand(Distributions.Multinomial(m, p)) + indices = vcat([repeat([i],indices[i]) for i in 1:length(indices)]...) + + # Return observations + return xcal[indices] + +end # end gen_mult_full_data +""" + `gen_mult_part_data(M;N,p)` + +Generate M partially observed reads with N CpG sites from a multinomial model +with vector probabilities `p=[p_1,...,p_{2^N}]`. The values code for: +1: Methylated CpG site. +-1: Unmethylated CpG site. +0: Unobserved CpG site. + +# Examples +```julia-repl +julia> Random.seed!(1234); +julia> xobs=gen_mult_part_data(10) +10-element Array{Vector{Int64},1}: + [-1, -1, -1, -1] + [1, -1, -1, -1] + [-1, 1, -1, -1] + [-1, -1, 1, -1] + [0, -1, 1, -1] + [0, -1, -1, 0] + [0, 1, -1, 1] + [0, -1, 1, 1] + [0, -1, 1, 1] + [0, 1, 1, 1] +``` +""" +function gen_mult_part_data(m::Int64;n=4,p=1.0/(2.0^n)*ones(2^n))::Array{Vector{Int64},1} + + # Get full data + full_data = gen_mult_full_data(m;n=n,p=p) + + # Add missing values on sides + missleft = rand(Distributions.Binomial(n+1, 0.05),m) + missright = rand(Distributions.Binomial(n+1, 0.05),m) + for i in 1:m + full_data[i][1:missleft[i]] = fill(0, missleft[i]) + full_data[i][(n-missright[i]+1):end] = fill(0, missright[i]) + end + + # Return partial observations + return full_data + +end # end gen_mult_part_data +""" + `mle_asymptotics(R,M,N)` + +Function to generate MLEs and plot CLT type behavior. When the number +of observations is ≧15 the convergence seems to kick in (try example +below). + +# Examples +```julia-repl +julia> p=mle_asymptotics(1000,15,2) +``` +""" +function mle_asymptotics(r::Int64,m::Int64,n::Int64) + + # Get r samples of MLE + a_mle = SharedArray{Float64}(r) + b_mle = SharedArray{Float64}(r) + for i=1:r + xobs = [gen_x_mc(div(n,k)*ones(Int64,k),ones(Float64,k),b) for c=1:1000] + mle = est_eta([n],xobs) + a_mle[i]=mle[1] + b_mle[i]=mle[2] + end + + # Plot √n(α̂-α) + gr() + p = histogram(sqrt(m) * [a_mle,b_mle], line=(3,0.2,:green), + fillcolor=[:red :black], fillalpha=0.2, nbins=75) + + # return plot + return p + +end # mle_asymptotics +""" + `comp_estimates(R,N,M)` + +Function to generate estimates using all models considerd and plot the Eucledean +distance from the true parameter vector when observing complete observations. + +# Examples +```julia-repl +julia> p=comp_estimates(10000,2,15) +``` +""" +function comp_estimates(r::Int64,n::Int64,m::Int64;p=1/(2^n)*ones(Float64,2^n)) + + # Initialize output vectors and 𝒳 + euc_mult = [] + euc_ising = [] + euc_bin_semi = [] + euc_bin_param = [] + xcal = generate_xcal(n) + + # Loop over replicates + for i in 1:r + + # Generate data from full model + xobs = gen_mult_full_data(m; n=n,p=p) + if all([xobs[i-1]==xobs[i] for i in 2:length(xobs)]) + i -= 1 + continue + end + + # Estimate parameters of multinomial model + phat = mle_mult(xobs) + euc = sqrt(sum((p - phat).^2)) + push!(euc_mult,euc) + + # Estimate parameters of Ising model + mle_ising = est_eta([n],xobs) + phat = [comp_lkhd(x,[n],[mle_ising[1]],mle_ising[2]) for x in xcal] + euc = sqrt(sum((p - phat).^2)) + push!(euc_ising,euc) + + # Estimate parameters of semipar binomial model + phat = mle_bin_semi(xobs) + euc = sqrt(sum((p - phat).^2)) + push!(euc_bin_semi,euc) + + # Estimate parameters of semipar binomial model + phat = mle_bin_param(xobs) + euc = sqrt(sum((p - phat).^2)) + push!(euc_bin_param,euc) + print("Progress: $(round(i/r*100))% \r") + flush(stdout) + end + + # Plot histogram of Eucledean distances + x = [euc_ising, euc_mult, euc_bin_semi, euc_bin_param] + labels = ["Ising fit", "Multinomial fit", "General Bernoulli fit", + "Special Bernoulli fit"] + xlabel = L"||\hat{p}_{ML}-p||" + p = plot_histogram(x, labels; xlabel=xlabel) + + # return plot + return p + +end # comp_estimates diff --git a/test/bam/example.a1.bam b/test/bam/example.a1.bam new file mode 100644 index 0000000000000000000000000000000000000000..0fd7aa94848d9cab9fbe8a73868b7b96c8f1a8b2 GIT binary patch literal 28956 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 LEVcg`BH8~3Tj^ls literal 0 HcmV?d00001 diff --git a/test/bam/example.a2.bam b/test/bam/example.a2.bam new file mode 100644 index 0000000000000000000000000000000000000000..d605633b4cac878d9dd6e59eeee45d1f2899af8f GIT binary patch literal 30345 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 literal 0 HcmV?d00001 diff --git a/test/bam/example_a2_R1_bismark_bt2_pe.bam b/test/bam/example_a2_R1_bismark_bt2_pe.bam new file mode 100644 index 0000000000000000000000000000000000000000..b44b271ba6fbdadd70821a94a1a9f1f61604249e GIT binary patch literal 31444 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 z0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdb zFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?0 z00Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdbFu(u< z3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Rs# zzyJdbFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d| z0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdb zFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?0 z00Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdbFu(u< z3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Rs# zzyJdbFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d| z0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdb zFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?0 z00Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdbFu(u< z3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Rs# zzyJdbFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d| z0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdb zFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}Rx~z#XL&TVI1a)6O(tfB^;=V1NMz z7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|YT 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 z3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Rs# zzyJdbFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d| z0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdb zFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?0 z00Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdbFu(u< z3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Rs# zzyJdbFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d| z0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdb zFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?0 z00Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdbFu(u< z3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Rs# zzyJdbFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d| z0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdb zFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?0 z00Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdbFu(u< z3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Rs# zzyJdbFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d| z0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdb zFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?0 z00Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdbFu(u< z3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Rs# zzyJdbFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d| z0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdb zFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?0 z00Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdbFu(u< z3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Rs# zzyJdbFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d| z0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdb zFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?0 z00Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdbFu(u< z3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Rs# zzyJdbFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d| z0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdb zFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?0 z00Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdbFu(u< z3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Rs# zzyJdbFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d| z0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdb zFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?0 z00Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdbFu(u< z3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Rs# zzyJdbFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d| z0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdb zFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?0 z00Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdbFu(u< z3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Rs# zzyJdbFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d| z0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdb zFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?0 z00Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdbFu(u< z3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Rs# zzyJdbFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d| z0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdb zFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?0 z00Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdbFu(u< z3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Rs# zzyJdbFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d| z0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdb zFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?0 z00Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdbFu(u< z3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Rs# zzyJdbFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d| z0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdb zFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?0 z00Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdbFu(u< z3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Rs# zzyJdbFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d| z0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdb zFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?0 z00Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdbFu(u< z3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Rs# zzyJdbFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d| z0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdb zFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?0 z00Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdbFu(u< z3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Rs# zzyJdbFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d| z0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdb zFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?0 z00Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdbFu(u< z3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Rs# zzyJdbFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d| z0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdb zFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?0 z00Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdbFu(u< z3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Rs# zzyJdbFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d| z0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdb zFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?0 z00Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdbFu(u< z3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdbFu(u#WY}m0R|XgfB^;=U|>80Kj-?hX}|yj3^2d|0}L?000Rs#zyJdbFu(u< z3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d|11k;ulKUW< z1`II300Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdb zFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?0 z00Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdbFu(u< z3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Rs# zzyJdb)Z4(Xr4-YE0R|XgfB^;=V1NMz7+`<_1{h$VEe3we_q$931{h#~0R}d1;P-q^ z?dtx>$8H)hzyJdbFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdb zFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^33h1Apc|#HIlQ3^2d|1I;qV1r$&~0RuiY@Ym*CXIsx2oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB=C}3M?-zu6&I0a$Oby0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UATR=f zYAP3E3^bqt4QN0E8qk0SG@t6xF$Uq0}W_E0~*kP1~j075*xTS&t;9ldJSBc zKH9eHb4P3?3R50r0v#RXJeoN z4QN0E8qh$K25!sqiKg3}^DqXbG;n)*?d^_yZVWV_0S%PZz@2&QHU=d(a90{O1{%^+>zFa{bZvw=r)|1}00(0~RspaBhN zKm!`M(7@I_KQ;y$(0~RspaBhNKm!`kfCe<60S#zC0~#2A1CQo+b;dvg8qk0SG@t%o*pc5I7y}JxKm!`k zfCe<60S#zC0~*kP1~i}n4QN0E8qk0SG@yYlHt=lT3o`~9&_I(0p3CFNxVAHwZ45M^ z0S#zC0~*kP1~i}n4QN0E8qk0SG@toxFFUNcxdgI%#R1{%_Cpg7-*n=1Fz;jWDGQ*0S#zC0~+Y3 zf!Ff2 z=J}*Cn8XI&OZzr{gM+ypjDZF;paBhNKm!`kfCe<60S#zC0~*kP1~i}n4QN0E8qk0S zH1Pih4&}W>W1s;IbiIN1^H^sLG@t#zF-VAP``mMa~~>kU*))sfd(|70S#!N zdkxIyXZ$4X>s()B&}-nE^ib-)&9RrXxg4)CXj216(qze-&+!j?M{^m*Km!`kfCeVL zfn)i3X!Q(^$IcjNU~~<9m-}3AC-Qldoy_Ttfd(|70S#zC0~*kP1~i}n4QN0EU25R_ z{Jz5&l-$4%Y1kNOKm&tr;8Y%4jDZF=Zs2t8D<$ttj^7weS_40(dt2LJAvSH_PdUax z?QG7=$~O2px1n8}!MRu&0}W`PX#>CHvBb(Z_%*j=}WR* j+3sxhb)GxEux)n#%I*<=C3#tn)s{~{* n8#8l51hnlys!`M&S_c$ifJj>aDLx1jNTNFpE@2E|88ZU_=Bb`W literal 0 HcmV?d00001 diff --git a/test/fasta/Bisulfite_Genome/CT_conversion/BS_CT.rev.1.bt2 b/test/fasta/Bisulfite_Genome/CT_conversion/BS_CT.rev.1.bt2 new file mode 100644 index 0000000000000000000000000000000000000000..3e275ae507422ec4528a94f261f8c859d1d4b27a GIT binary patch literal 4715658 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 zzyJdbFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d| z0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdb zFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?0 z00Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdbFu(u< z3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Rs# zzyJdbFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d| z0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdb zFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?0 z00Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdbFu(u< z3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Rs# zzyJdbFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d| z0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdb zFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?0 z00Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdbFu(u< z3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Rs# zzyJdbFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Rs#z`*hi4Env%!`4!Y zX}|yj3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d|1FLCZ zTkg+j8Zf{B0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?0 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 zV1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~ z0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz z7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|Xg zfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_ z1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;= zV1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~ z0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz z7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|Xg zfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_ z1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;= zV1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~ z0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz z7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|Xg zfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_ z1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;= zV1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~ z0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz z7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|Xg zfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_ z1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;= zV1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~ z0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz z7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|Xg zfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_ z1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;= zV1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~ z0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz z7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|Xg zfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_ z1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;= zV1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~ z0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz z7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|Xg zfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_ z1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;= zV1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~ z0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz z7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|Xg zfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_ z1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;= zV1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~ z0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz z7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|Xg zfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_ z1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;= zV1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~ z0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz z7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|Xg zfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_ z1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;= zV1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~ z0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz z7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|Xg zfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_ z1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;= zV1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~ z0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz z7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|Xg zfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_ z1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;= zV1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~ z0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz z7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|Xg zfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_ z1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;= zV1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~ z0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz z7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|Xg zfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_ z1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;= zV1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~ z0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz z7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|Xg zfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_ z1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;= zV1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~ z0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz z7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|Xg zfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_ z1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;= zV1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~ z0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz z7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|Xg zfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_ z1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;= zV1NMz7+`<_1{h#~0R|Wt&%mJH8$EnnN-+%>V1NMz7+`<_1{h#~0R|XgfB^;=V1R*k z8u%o)0h5Dg)o-_5;&^0R|XgfB^;=V1NMz7+`<_ z1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;= zV1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~ z0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz z7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1R+?82Gl7Vj3{O00Rs# zzyJdbFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d| z0}L>*at6N3@AQ}k3^2d|0}L?000Rs#zyJdbjA!8cd>?HZFu(u<3^2d|0}L?000Rs# zzyJdbFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d| z0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdb zFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?0 z00Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdbFu(u< z3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Rs# zzyJdbFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d| z0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdb zFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?0 z00Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdbFu(u< z3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Rs# zzyJdbFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d| z0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdb zFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?0 z00Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdbFu(u< z3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Rs# zzyJdbFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d| z0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdb zFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?0 z00Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdbFu(u< z3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Rs# zzyJdbFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d| z0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdb zFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?0 z00Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdbFu(u< z3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Rs# zzyJdbFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d| z0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdb zFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?0 z00Rs#zyJdbFu(u<3^2d|0}L=QIRihGQkJtH^ZKR%0}L?000Rs#zyJdbFu(u<%{K5; zzP~pO7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~ z0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz z7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|Xg zfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_ z1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;= zV1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~ z0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz z7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|Xg zfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_2BvA?=TeGkzyJdbFu(u<3^2d| z0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdb zFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?0 z00Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdbFu(u< z3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?000XmR;FnU0X}|yj3^2d|0}L?000Rs# zzyJdbFu(u<3^2d|0}L?000Rs#zyJdbFu(uCm?(<|CFu(u<3^2d|0}L?000Rs# z&@BVM<@Ny6fB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_2AX1E(C_7^oE|Hn zfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7> z3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36A zpnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim} z0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7j zD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUg zfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7> z3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36A zpnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim} z0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7j zD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUg zfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7> z3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36A zpnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim} z0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7j zD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUg zfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7> z3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36A zpnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim} z0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7j zD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUg zfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7> z3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36A zpnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim} z0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7j zD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUg zfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7> z3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36A zpnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim} z0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7j zD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUg zfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7> z3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36A zpnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim} z0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7j zD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUg zfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7> z3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36A zpnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim} z0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7j zD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUg zfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7> z3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36A zpnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim} z0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7j zD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUg zfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7> z3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36A zpnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim} z0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7j zD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUg zfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7> z3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36A zpnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim} z0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3QV;?&V2MxN}1~0a{dY^ zpnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim} z0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7j zD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUg zfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7> z3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36A zpnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim} z0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7j zD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUg zfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7> z3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0w*gl==VksCwm#EE1-Y^3Mim}0tzUgfC36A zpnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim} z0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7j zD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUg zfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7> z3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36A zpnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim} z0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7j zD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUg zfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7> z3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36A zpnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim} z0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7j zD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUg zfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7> z3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36A zpnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim} z0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7j zD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUg zfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7> z3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36A zpnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim} z0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7j zD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUg zfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7> z3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36A zpnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim} z0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7j zD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUg zfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7> z3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36A zpnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim} z0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7j zD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUg zfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7> z3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36A zpnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim} z0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7j zD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUg zfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7> z3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36A zpnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim} z0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7j zD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUg zfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7> z3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36A zpnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim} z0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7j zD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUg zfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7> z3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36A zpnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim} z0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7j 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 Gn(AM_bwNY` literal 0 HcmV?d00001 diff --git a/test/fasta/Bisulfite_Genome/CT_conversion/BS_CT.rev.2.bt2 b/test/fasta/Bisulfite_Genome/CT_conversion/BS_CT.rev.2.bt2 new file mode 100644 index 0000000000000000000000000000000000000000..134fe0bf9e1f7d70da10a97bb0b47ba4d7ffdfcb GIT binary patch literal 122 zcmZQ%U|@K^e=m@XhO;1i2=tNGAcY O6Ohdg#Qs1w#AE<#y&6UU literal 0 HcmV?d00001 diff --git a/test/fasta/Bisulfite_Genome/CT_conversion/genome_mfa.CT_conversion.fa b/test/fasta/Bisulfite_Genome/CT_conversion/genome_mfa.CT_conversion.fa new file mode 100644 index 0000000..cff6622 --- /dev/null +++ b/test/fasta/Bisulfite_Genome/CT_conversion/genome_mfa.CT_conversion.fa @@ -0,0 +1,4 @@ +>chr1_CT_converted +AATTTTAATGATGTGTTTGAATTGTGGTTGTATGTTTGTATTGGGATGTNGGTTTTATTGTTGTGTTGTGTAGAAATATNTTTTATTGTATTTTTTTTTTGTGTTATATTAAATGGTATTTTGATGTATGGGTATTATTNAATANGGTTTTTGGAAATATTTTTTAATTTAAAAATTGATTTTTTTTAAAATGTTATGA +>chr2_CT_converted +GGGTTTTTGGTTTGTTTGAGAAAGTTAAATATATAAATGNAAGATGGAANGTGGAGTTANTTAAATTTGTTAGTTTGTTGTATTTTTTGAATGTGGTTATAAAAGAATTTTTAGTAAATTGTAAATTGATTTGAATTTTATTTTTTGGTNATGAGGTGTATTTTTAAGTATTTTATAATTGAATTGTTGTTTGTATATA diff --git a/test/fasta/Bisulfite_Genome/GA_conversion/BS_GA.1.bt2 b/test/fasta/Bisulfite_Genome/GA_conversion/BS_GA.1.bt2 new file mode 100644 index 0000000000000000000000000000000000000000..432a10083ba06a6210abaff39d316967be81da31 GIT binary patch literal 4741435 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 zD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUg zfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7> z3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36A zpnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim} z0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7j zD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUg zfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7> z3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36A zpnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim} z0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7j zD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUg zfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7> z3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36A zpnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim} z0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7j zD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUg zfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7> z3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36A zpnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim} z0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7j zD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUg zfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7> z3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36A zpnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim} z0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7j zD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUg zfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7> z3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36A zpnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim} z0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7j zD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUg zfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7> z3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36A zpnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim} z0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7j zD4>7>3Mim}0tzUgfC36Apnw7jD4>7>BP@`U>OU1lF~U=JY6>WzfC36Apnw7jD4>7> z3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36A zpnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim} z0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7j zD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUg zfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7> z3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36A zpnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim} z0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7j zD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUg zfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7> z3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36A zpnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim} z0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7j zD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUg zfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7> z3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36A zpnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim} z0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7j zD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUg zfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7> z3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36A zpnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim} z0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7j zD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUg zfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7> z3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36A zpnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim} z0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7j zD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUg zfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7> z3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36A zpnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim} z0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7j zD4>7>3Mim}0tzUgfC36Apnw7jD4>7>^)AruwEIu>zN9Xl0tzUgfC36Apnw7jD4>7> z3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36A zpnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim} z0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7j zD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUg zfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7> z3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36A zpnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim} z0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7j zD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUg zfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7> z3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36A zpnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim} z0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7j zD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUg zfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7> z3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3RJy7x6|%FRsFI! z{|YFefC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7j zD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUg zfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7> z3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36A zpnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim} z0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7j zD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUg zfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7> z3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36A zpnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim} z0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7j zD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUg zfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7> z3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36A zpnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim} z0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7j zD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUg zfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7> z3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36A zpnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim} z0tzUgfC36Apnw7jD4>7>3Mim}0t(D>fo`YWf12g<>AWeRfC36Apnw7jD4>7>3Mim} z0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7j zD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUg zfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7> z3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36A zpnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim} z0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7j zD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUg zfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7> z3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36A zpnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim} z0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7j zD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUg zfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7> z3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36A zpnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim} z0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7j zD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUg zfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7> z3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36A 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 z1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;= zV1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~ z0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz z7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|Xg zfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_ z1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;= zV1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~ z0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz z7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|Xg zfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_ z1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;= zV1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~ z0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz z7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|Xg zfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_ z1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;= zV1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~ z0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz z7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|Xg zfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_ z1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;= zV1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~ z0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz z7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|Xg zfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_ z1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;= zV1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~ z0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz z7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|Xg zfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_ z1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;= zV1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~ z0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz z7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|Xg zfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_ z1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;= zV1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~ z0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz z7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|Xg zfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_ z1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;= zV1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~ z0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz z7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|Xg zfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_ z1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;= zV1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~ z0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz z7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|Xg zfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_ z1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;= zV1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~ z0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz z7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|Xg zfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_ z1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;= zV1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~ z0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz z7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|Xg zfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_ z1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;= zV1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~ z0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz z7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|Xg zfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_ z1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;= zV1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~ z0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz z7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|Xg zfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_ z1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;= zV1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~ 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 literal 0 HcmV?d00001 diff --git a/test/fasta/Bisulfite_Genome/GA_conversion/BS_GA.2.bt2 b/test/fasta/Bisulfite_Genome/GA_conversion/BS_GA.2.bt2 new file mode 100644 index 0000000000000000000000000000000000000000..97df7106871fb251a3eb25e62d5728ee44ab986b GIT binary patch literal 128 zcmZQ%U|@K^e=m@92VxI6uY{3-p#aWF zjzBE#V8R$63uJ^aI4~MAG7B&;%COhilz??Q@Bk$k9Ku1md1OKy>}z?ALFNMyh!PYD JFtHV81OVEAKLh{( literal 0 HcmV?d00001 diff --git a/test/fasta/Bisulfite_Genome/GA_conversion/BS_GA.rev.1.bt2 b/test/fasta/Bisulfite_Genome/GA_conversion/BS_GA.rev.1.bt2 new file mode 100644 index 0000000000000000000000000000000000000000..07184798b71dca5a15b8aef1afd25d218f3c7f55 GIT binary patch literal 4704687 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 zzyJdbFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d| z0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdb zFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?0 z00Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdbFu*{a z2F{mKmX{ViRzLv-6i`3`1r$&~0R7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7j zD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUg zfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7> z3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36A zpnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim} z0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7j zD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUg zfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7> z3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36A zpnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim} z0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7j zD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUg zfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7> z3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36A zpnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim} z0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7j zD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUg zfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7> z3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36A zpnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim} z0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7j zD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUg zfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7> z3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36A zpnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim} z0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7j zD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUg zfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7> z3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36A zpnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim} z0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7j zD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUg zfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7> z3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36A zpnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim} z0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7j zD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUg zfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7> z3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36A zpnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim} z0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7j zD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUg zfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7> z3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36A zpnw7jD4>7>3Mim}0+%gN26++FfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_ z1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;= zV1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~ z0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz z7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|Xg zfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_ 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 z7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|Xg zfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_ z1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;= zV1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~ z0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz z7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|Xg zfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_ z1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;= zV1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~ z0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz z7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|Xg zfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_ z1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;= zV1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~ z0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz z7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|Xg zfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_ z1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;= zV1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~ z0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz z7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|Xg zfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_ z1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;= zV1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~ z0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz z7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|Xg zfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_ z1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;= zV1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~ z0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz z7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|Xg zfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_ z1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;= zV1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~ z0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz z7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|Xg zfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_ z1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;= zV1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~ z0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz z7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|Xg zfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_ z1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;= zV1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~ z0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz z7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|Xg zfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_ z1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;= zV1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~ z0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz z7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|Xg zfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_ z1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;= zV1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~ z0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz z7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|Xg zfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_ z1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;= zV1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~ z0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz z7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|Xg zfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_ z1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;= zV1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~ z0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz z7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|Xg zfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_ z1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;= zV1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~ z0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz z7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|Xg zfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_ z1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;= zV1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~ z0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz z7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|Xg zfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_ z1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;= zV1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~ z0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz z7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|Xg zfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_ z1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;= zV1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~ z0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz z7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|Xg zfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_ z1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;= zV1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~ z0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz z7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|Xg zfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_ z1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;= zV1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~ z0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz z7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|Xg zfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+|0c z2JRn}Vj4`szyqc!1B`K@Zp)yOS$Zu1`II300Rs#zyJdbFwhkPM{^s;G+=-M1{h#~0R|Xg zU^D~Aa{bvfV1NMz7+`<_1{h#~0R|XgfB^;=V4(d5j^}%Qc432;)5J7jfB^;=V1NMz z7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|Xg zfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_ z1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;= zV1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~ z0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz z7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|Xg zfB^;=V1NMz7+`<_2AXeReo%^OzyJdbFu(u<3^2d|19cmCCAURPgQggGH6H8SYk7O7 z0Rs#$zyJdbFu(u<3^2gJBn+I$ZBo;K0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;= zV1NMz7+`<_2AX2v_1u?XyZ1)k#>IOxPcsb|V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz z7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|Xg zfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_ z1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1R*c8+dC_ifO zHVqhHfB^=^HSl)6j+h1vFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Rs# zzyJdbFu(u<3^2d|1LGQaC-+A+4K{1w-MBFg80fcwg?t{c(HfjetF^tC!=?cP3^2d| z0}L?000Rs#zyJdbFu(u<3^2ez6AYZr_pD6=1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~ z0R|XgfB^;=V1NMz7#P>UncVllG+>}v2Hwx*(llUz0R|XgfB^;=V1NMz7+|2=20qB` zf75^g1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|Xg zfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_ z1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+|0>@S$nI00Rs#zyJdb zFu(u<3@|W)fsgVsrU3&CFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Rs# zzyJdbFu(u<3^2d|1N9jAIQQQ*4cctrlNdG)7+`<_1{j#EfuH5;v1z~n0}L?000Rs# zzyJdbFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Y});B4-zXc{okUIXWH z88!_VV1NMz7+`<_1{h#q6a$~;_Je7_00Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdb zFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?G1_PhvXJJeO1{h#~0R|XgfB^;= zV1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~ z0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz z7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=U|=)@pXdLGHw_qQw}CHm zIW`R#V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_ z1{h#~0R|XgfB^;=V1NMz{@32Ur6dprU>N@Aw%STT?Vzi+(BVSJ?3|XJ&npv`Y#M z00Rs#z`%C~4s*TGq#fmaOalfOV1NMz7+`<_24-*IIM?27*-6gTG+=-M1{h#~0R|Xg zfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{kQDfqq{9W*Ribz#yJY0|ppq zlY!Gb@0kV+Fu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdbFu(u< z3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}TAkz*#=O z%QRqs0R|XgfPwD}40F9;8Zf{B0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdb zFu(u<3^2d|0}L?000Rs#zyJdbFu*`t4V>q_6{Z0L3^4Hj4P4~;+B9H*0R|XgfB^;= zV1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^>n&cJ0}ziApU@IMS( z<@eDvV1NMz7+`<_1{i3nf$LoFng$FozyJdbFu(u<3@}g!12_5mrA@od`I-g{Fu(u< z3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Rs# zzyJdbFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d| z0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdbFu(u<3^2d|0}L?000Rs#zyJdb zFu(u<3^2ezeGN>;qmSdhD#bKlfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_ z1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;= zV1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~ z0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz z7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|Xg zfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_ z1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;= zV1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|Xgpcw`ps!~jYR|Ai~*i(MS zG+=-M1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|XgfB^;=V1NMz7+`<_1{h#~0R|Xg zfB^;=V4&Uxp7Z_y`7>3Mim}0tzUg zfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7> z3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36A zpnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim} z0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7j zD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUg zfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7> z3Mim}0tzUgz|;cyhPPwAl(La+W?NbAoq9W8m9mg6W=mN&+sSUTyX^C$clU?Oowe0Y TchJA;4KI2-bGc{b>pkTKqH@CH literal 0 HcmV?d00001 diff --git a/test/fasta/Bisulfite_Genome/GA_conversion/BS_GA.rev.2.bt2 b/test/fasta/Bisulfite_Genome/GA_conversion/BS_GA.rev.2.bt2 new file mode 100644 index 0000000000000000000000000000000000000000..26a41f3b659ae7516b84a1b64cf89a589fd90b65 GIT binary patch literal 128 zcmZQ%U|@K^e=nRAXGGgikbj%3{b5q G5CZ_;%^)xU literal 0 HcmV?d00001 diff --git a/test/fasta/Bisulfite_Genome/GA_conversion/genome_mfa.GA_conversion.fa b/test/fasta/Bisulfite_Genome/GA_conversion/genome_mfa.GA_conversion.fa new file mode 100644 index 0000000..fcdf9bd --- /dev/null +++ b/test/fasta/Bisulfite_Genome/GA_conversion/genome_mfa.GA_conversion.fa @@ -0,0 +1,4 @@ +>chr1_GA_converted +AATCTTAACAACATACCCAAACTATAACCATACATTCATATTAAAATATNAATCTCATTACCATACCATACAAAAACATNTTTTACTACATTCCTCTTTTATATTATACCAAATAATACTTCAACATATAAACATCATCNAATANAATCTCCAAAAATACCTTCTAATTTAAAAATCAACTTTTTCCAAAACACTACAA +>chr2_GA_converted +AAACCCTCAACCTACCCAAAAAAACCAAACATACAAATANAAAACAAAANACAAAATCANTCAAATTCATTAACTCATTATACCTTCTAAACATAACCATAAAAAAACTCCCAACAAACTATAAATCAACCCAAACTTTACTTCCTAATNATAAAACATATCCCTAAACATTTCACAACCAAACCACTACTTATACACA diff --git a/test/fasta/allele-specific/example.g1.fa b/test/fasta/allele-specific/example.g1.fa new file mode 100644 index 0000000..d1d51cd --- /dev/null +++ b/test/fasta/allele-specific/example.g1.fa @@ -0,0 +1,4 @@ +>chr1 +AATCTTAACGACGTGCCCGAACTGTGGCCGTACGTTCGTATTGGGATGTCGGTCTCATTGCCGTGCCGTGCAGAAACATATTTTACTGCATTCCTCTTTTGTGTTATACCAAATGGTACTTCGACGTATGGGCATCATCAAATAAGGTCTCCGGAAATACCTTCTAATTTAAAAATCGACTTTTTCCAAAACGCTACGA +>chr2 +GGGCCCTCGGCCTGCCCGAGAAAGCCAAACATACAAATGGAAGACGGAAAGCGGAGTCAATCAAATTCGTTAGCTCGTTGTACCTTCTGAACGTGGCCATAAAAGAACTCCCAGCAAACTGTAAATCGACCCGAACTTTACTTCCTGGTTATGAGGCGTATCCCTAAGCATTTCACAACCGAACCGCTGCTTGTACACA diff --git a/test/fasta/allele-specific/example.g2.fa b/test/fasta/allele-specific/example.g2.fa new file mode 100644 index 0000000..15314e7 --- /dev/null +++ b/test/fasta/allele-specific/example.g2.fa @@ -0,0 +1,4 @@ +>chr1 +AATCTTAACGACGTGCCCGAACTGTGGCCGTACGTTCGTATTGGGATGTAGGTCTCATTGCCGTGCCGTGCAGAAACATTTTTTACTGCATTCCTCTTTTGTGTTATACCAAATGGTACTTCGACGTATGGGCATCATCGAATAGGGTCTCCGGAAATACCTTCTAATTTAAAAATCGACTTTTTCCAAAACGCTACGA +>chr2 +GGGCCCTCGGCCTGCCCGAGAAAGCCAAACATACAAATGAAAGACGGAACGCGGAGTCACTCAAATTCGTTAGCTCGTTGTACCTTCTGAACGTGGCCATAAAAGAACTCCCAGCAAACTGTAAATCGACCCGAACTTTACTTCCTGGTAATGAGGCGTATCCCTAAGCATTTCACAACCGAACCGCTGCTTGTACACA diff --git a/test/fasta/example.1.bt2 b/test/fasta/example.1.bt2 new file mode 100644 index 0000000000000000000000000000000000000000..061b8ece0866f8b0c253b3b285331bd0105d5782 GIT binary patch literal 4921272 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 Gg&6@VIcfL+ literal 0 HcmV?d00001 diff --git a/test/fasta/example.fa b/test/fasta/example.fa new file mode 100644 index 0000000..883d1a6 --- /dev/null +++ b/test/fasta/example.fa @@ -0,0 +1,4 @@ +>chr1 +AATCTTAACGACGTGCCCGAACTGTGGCCGTACGTTCGTATTGGGATGTNGGTCTCATTGCCGTGCCGTGCAGAAACATNTTTTACTGCATTCCTCTTTTGTGTTATACCAAATGGTACTTCGACGTATGGGCATCATCNAATANGGTCTCCGGAAATACCTTCTAATTTAAAAATCGACTTTTTCCAAAACGCTACGA +>chr2 +GGGCCCTCGGCCTGCCCGAGAAAGCCAAACATACAAATGNAAGACGGAANGCGGAGTCANTCAAATTCGTTAGCTCGTTGTACCTTCTGAACGTGGCCATAAAAGAACTCCCAGCAAACTGTAAATCGACCCGAACTTTACTTCCTGGTNATGAGGCGTATCCCTAAGCATTTCACAACCGAACCGCTGCTTGTACACA diff --git a/test/fasta/example.fa.fai b/test/fasta/example.fa.fai new file mode 100644 index 0000000..cc7968d --- /dev/null +++ b/test/fasta/example.fa.fai @@ -0,0 +1,2 @@ +chr1 199 6 199 200 +chr2 199 212 199 200 diff --git a/test/fasta/example.rev.1.bt2 b/test/fasta/example.rev.1.bt2 new file mode 100644 index 0000000000000000000000000000000000000000..4d3c933d335daf30103db9678d18f57badceb4db GIT binary patch literal 4995089 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 KEI$yd0x +##FORMAT= +##FORMAT= +#CHROM POS ID REF ALT QUAL FILTER INFO FORMAT STL003 +chr1 50 SNP A C . . . GT:PS:FI 1/0:L1:1 +chr1 80 SNP A T . . . GT:PS:FI 0/1:L1:1 +chr1 140 SNP A G . . . GT:PS:FI 0/1:L2:1 +chr1 145 SNP A G . . . GT:PS:FI 0/1:L2:1 +chr2 40 SNP G A . . . GT:PS:FI 0/1:L3:1 +chr2 50 SNP C A . . . GT:PS:FI 1/0:L3:1 +chr2 60 SNP A C . . . GT:PS:FI 0/1:L3:1